├── .github
├── CONTRIBUTING.md
└── ISSUE_TEMPLATE.md
├── .gitignore
├── .stylelintrc
├── .travis.yml
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── gulpfile.ts
├── karma.conf.js
├── nativescript
├── .vscode
│ └── launch.json
├── package.json
├── src
│ ├── App_Resources
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── app.gradle
│ │ │ ├── drawable-hdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-ldpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-mdpi
│ │ │ │ └── icon.png
│ │ │ ├── drawable-nodpi
│ │ │ │ └── splashscreen.9.png
│ │ │ ├── drawable
│ │ │ │ └── splash_logo.png
│ │ │ └── values
│ │ │ │ ├── material_colors.xml
│ │ │ │ └── splash_settings.xml
│ │ └── iOS
│ │ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon-29.png
│ │ │ │ ├── icon-29@2x.png
│ │ │ │ ├── icon-29@3x.png
│ │ │ │ ├── icon-40.png
│ │ │ │ ├── icon-40@2x.png
│ │ │ │ ├── icon-40@3x.png
│ │ │ │ ├── icon-50.png
│ │ │ │ ├── icon-50@2x.png
│ │ │ │ ├── icon-57.png
│ │ │ │ ├── icon-57@2x.png
│ │ │ │ ├── icon-60@2x.png
│ │ │ │ ├── icon-60@3x.png
│ │ │ │ ├── icon-72.png
│ │ │ │ ├── icon-72@2x.png
│ │ │ │ ├── icon-76.png
│ │ │ │ ├── icon-76@2x.png
│ │ │ │ └── icon-83.5@2x.png
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.launchimage
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Default-568h@2x.png
│ │ │ │ ├── Default-667h@2x.png
│ │ │ │ ├── Default-736h@3x.png
│ │ │ │ ├── Default-Landscape.png
│ │ │ │ ├── Default-Landscape@2x.png
│ │ │ │ ├── Default-Landscape@3x.png
│ │ │ │ ├── Default-Portrait.png
│ │ │ │ ├── Default-Portrait@2x.png
│ │ │ │ ├── Default.png
│ │ │ │ └── Default@2x.png
│ │ │ ├── LaunchScreen.AspectFill.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── LaunchScreen-AspectFill.png
│ │ │ │ └── LaunchScreen-AspectFill@2x.png
│ │ │ └── LaunchScreen.Center.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── LaunchScreen-Center.png
│ │ │ │ └── LaunchScreen-Center@2x.png
│ │ │ ├── Info.plist
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── build.xcconfig
│ ├── app.aot.ts
│ ├── app.css
│ ├── app.ts
│ ├── components.module.ts
│ ├── mobile
│ │ └── core
│ │ │ ├── index.ts
│ │ │ ├── services
│ │ │ ├── ns-app.service.ts
│ │ │ └── window-native.service.ts
│ │ │ └── utils
│ │ │ └── actionbar.util.ts
│ ├── native.module.ts
│ ├── package.json
│ ├── references.d.ts
│ ├── tsconfig.json
│ ├── vendor-platform.android.ts
│ ├── vendor-platform.ios.ts
│ └── vendor.ts
├── tools
│ └── webpack
│ │ └── tns-loader.js
├── tsconfig.aot.json
├── tsconfig.json
├── webpack.android.js
├── webpack.common.js
├── webpack.ios.js
└── yarn.lock
├── package.json
├── src
└── client
│ ├── app
│ └── shared
│ │ ├── core
│ │ ├── core.module.ts
│ │ ├── directives
│ │ │ ├── index.ts
│ │ │ ├── platform.directive.spec.ts
│ │ │ └── platform.directive.ts
│ │ ├── index.ts
│ │ ├── interfaces
│ │ │ ├── iconsole.ts
│ │ │ ├── ilang.ts
│ │ │ ├── index.ts
│ │ │ └── iwindow.ts
│ │ ├── services
│ │ │ ├── app.service.ts
│ │ │ ├── console.service.ts
│ │ │ ├── index.ts
│ │ │ ├── log.service.spec.ts
│ │ │ ├── log.service.ts
│ │ │ ├── router-extensions.service.ts
│ │ │ └── window.service.ts
│ │ ├── tokens.ts
│ │ └── utils
│ │ │ ├── config.spec.ts
│ │ │ ├── config.ts
│ │ │ ├── index.ts
│ │ │ ├── type.ts
│ │ │ ├── view-broker.spec.ts
│ │ │ └── view-broker.ts
│ │ ├── electron
│ │ ├── index.ts
│ │ ├── services
│ │ │ └── event.service.ts
│ │ └── utils
│ │ │ ├── desktop-config.spec.ts
│ │ │ └── desktop-config.ts
│ │ └── sample
│ │ ├── components
│ │ ├── app
│ │ │ ├── app.component.html
│ │ │ ├── app.component.tns.html
│ │ │ ├── app.component.ts
│ │ │ └── app.routes.ts
│ │ ├── home
│ │ │ ├── home.component.html
│ │ │ ├── home.component.tns.html
│ │ │ ├── home.component.ts
│ │ │ ├── home.css
│ │ │ ├── home.routes.ts
│ │ │ └── home.tns.css
│ │ └── index.ts
│ │ ├── index.ts
│ │ ├── models
│ │ └── sample.model.ts
│ │ ├── routes.ts
│ │ ├── sample.module.ts
│ │ └── services
│ │ ├── app-config.ts
│ │ ├── index.ts
│ │ └── sample.service.ts
│ ├── assets
│ ├── data.json
│ ├── favicon
│ │ ├── favicon-DEV.ico
│ │ └── favicon-PROD.ico
│ ├── logo.icns
│ ├── logo.ico
│ └── svg
│ │ ├── more.svg
│ │ └── smile.svg
│ ├── index.html
│ ├── main.desktop.ts
│ ├── main.web.prod.ts
│ ├── main.web.ts
│ ├── package.json
│ ├── system-config.ts
│ ├── tokens.web.ts
│ ├── tsconfig.json
│ └── web.module.ts
├── tools
├── README.md
├── config.ts
├── config
│ ├── banner-256.txt
│ ├── banner.txt
│ ├── project.config.ts
│ ├── project.tasks.json
│ ├── seed-advanced.config.ts
│ ├── seed.config.interfaces.ts
│ ├── seed.config.ts
│ ├── seed.tasks.json
│ └── seed.tslint.json
├── debug.ts
├── env
│ ├── base.ts
│ ├── dev.ts
│ ├── env-config.interface.ts
│ └── prod.ts
├── install.js
├── manual_typings
│ ├── project
│ │ └── sample.package.d.ts
│ └── seed
│ │ ├── autoprefixer.d.ts
│ │ ├── cssnano.d.ts
│ │ ├── express-history-api-fallback.d.ts
│ │ ├── istream.d.ts
│ │ ├── karma.d.ts
│ │ ├── merge-stream.d.ts
│ │ ├── open.d.ts
│ │ ├── operators.d.ts
│ │ ├── slash.d.ts
│ │ ├── systemjs-builder.d.ts
│ │ └── tildify.d.ts
├── tasks
│ ├── assets_task.ts
│ ├── css_task.ts
│ ├── project
│ │ ├── desktop.build.ts
│ │ ├── desktop.libs.ts
│ │ ├── desktop.package.linux.ts
│ │ ├── desktop.package.mac.ts
│ │ ├── desktop.package.windows.ts
│ │ └── desktop.watch.ts
│ ├── seed
│ │ ├── build.assets.dev.ts
│ │ ├── build.assets.prod.ts
│ │ ├── build.assets.tns.ts
│ │ ├── build.bundle.rxjs.ts
│ │ ├── build.bundles.app.aot.ts
│ │ ├── build.bundles.app.rollup.aot.ts
│ │ ├── build.bundles.app.ts
│ │ ├── build.bundles.ts
│ │ ├── build.docs.ts
│ │ ├── build.html_css.ts
│ │ ├── build.index.dev.ts
│ │ ├── build.index.prod.ts
│ │ ├── build.js.dev.ts
│ │ ├── build.js.e2e.ts
│ │ ├── build.js.prod.aot.ts
│ │ ├── build.js.prod.rollup.aot.ts
│ │ ├── build.js.prod.ts
│ │ ├── build.js.test.ts
│ │ ├── build.js.tns.ts
│ │ ├── build.tns_html_css.ts
│ │ ├── build.tools.ts
│ │ ├── check.tools.ts
│ │ ├── check.versions.ts
│ │ ├── clean.all.src.js.ts
│ │ ├── clean.all.ts
│ │ ├── clean.coverage.ts
│ │ ├── clean.dev.ts
│ │ ├── clean.e2e.ts
│ │ ├── clean.prod.ts
│ │ ├── clean.tns.ts
│ │ ├── clean.tools.ts
│ │ ├── clear.files.ts
│ │ ├── compile.ahead.prod.ts
│ │ ├── copy.prod.rollup.aot.ts
│ │ ├── copy.prod.ts
│ │ ├── e2e.ts
│ │ ├── generate.manifest.ts
│ │ ├── karma.run.ts
│ │ ├── karma.run.with_coverage.ts
│ │ ├── karma.watch.ts
│ │ ├── minify.bundles.ts
│ │ ├── noop.ts
│ │ ├── print.banner.ts
│ │ ├── serve.coverage.ts
│ │ ├── serve.coverage.watch.ts
│ │ ├── serve.docs.ts
│ │ ├── server.prod.ts
│ │ ├── server.start.ts
│ │ ├── start.deving.ts
│ │ ├── transpile.bundles.rollup.aot.ts
│ │ ├── tslint.tns.ts
│ │ ├── tslint.ts
│ │ ├── watch.dev.ts
│ │ ├── watch.e2e.ts
│ │ ├── watch.test.ts
│ │ ├── watch.tns.ts
│ │ └── webdriver.ts
│ ├── task.ts
│ └── typescript_task.ts
├── utils.ts
└── utils
│ ├── project.utils.ts
│ ├── project
│ └── sample_util.ts
│ ├── seed.utils.ts
│ └── seed
│ ├── clean.ts
│ ├── code_change_tools.ts
│ ├── karma.start.ts
│ ├── server.ts
│ ├── tasks_tools.ts
│ ├── template_locals.ts
│ ├── tsproject.ts
│ └── watch.ts
├── tsconfig.json
├── tslint.json
└── yarn.lock
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Submitting Pull Requests
2 |
3 | **Please follow these basic steps to simplify pull request reviews - if you don't you'll probably just be asked to anyway.**
4 |
5 | * Please rebase your branch against the current master
6 | * Run ```npm install``` to make sure your development dependencies are up-to-date
7 | * Please ensure that the test suite passes **and** that code is lint free before submitting a PR by running:
8 | * ```npm test```
9 | * If you've added new functionality, **please** include tests which validate its behaviour
10 | * Make reference to possible [issues](https://github.com/mgechev/angular2-seed/issues) on PR comment
11 |
12 | ## Submitting bug reports
13 |
14 | * Please detail the affected browser(s) and operating system(s)
15 | * Please be sure to state which version of node **and** npm you're using
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **IMPORTANT**: This repository's issues are reserved for feature requests and bug reports. Do not submit support requests here.
2 |
3 |
4 | **Steps to reproduce and a minimal demo of the problem**
5 |
6 | _What steps should we try in your demo to see the problem?_
7 |
8 | **Current behavior**
9 |
10 |
11 | **Expected/desired behavior**
12 |
13 |
14 | **Other information**
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 |
3 | node_modules/
4 |
5 | npm-debug.log
6 |
7 | src/**/*.js
8 | src/**/*.js.map
9 | nativescript/app
10 | nativescript/hooks
11 | nativescript/node_modules
12 | nativescript/platforms
13 | nativescript/src/app
14 | nativescript/src/**/*.js
15 | nativescript/src/**/*.js.map
16 | nativescript/*.d.ts
17 | !nativescript/src/references.d.ts
18 | desktop
19 | gulpfile.js
20 | gulpfile.js.map
21 |
22 | typings/
--------------------------------------------------------------------------------
/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "stylelint-config-standard",
3 | "rules": {
4 | "block-no-empty": null,
5 | "at-rule-empty-line-before": null,
6 | "rule-non-nested-empty-line-before": null,
7 | "selector-pseudo-class-no-unknown" : [ true, {
8 | "ignorePseudoClasses": [
9 | "host"
10 | ]
11 | }]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 5
4 | - 6
5 |
6 | sudo: false
7 |
8 | os:
9 | - linux
10 | - osx
11 |
12 | matrix:
13 | exclude:
14 | - os: osx
15 | node_js: 4
16 | - os: osx
17 | node_js: 5
18 |
19 | before_install:
20 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
21 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated xctool || brew upgrade xctool; fi
22 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CHROME_BIN=chromium-browser; fi # Karma CI
23 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew cask install google-chrome; fi # Karma CI
24 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=:99.0; fi
25 |
26 | before_script:
27 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh -e /etc/init.d/xvfb start; fi
28 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then nohup bash -c "webdriver-manager start 2>&1 &"; fi # Protractor CI
29 |
30 | after_failure:
31 | - cat /home/travis/build/NathanWalker/angular2-seed-advanced/npm-debug.log
32 |
33 | branches:
34 | only: master
35 |
36 | notifications:
37 | email: true
38 | webhooks:
39 | on_success: change # options: [always|never|change] default: always
40 | on_failure: always # options: [always|never|change] default: always
41 | on_start: never # options: [always|never|change] default: always
42 |
43 | env:
44 | global:
45 | # https://github.com/DefinitelyTyped/tsd#tsdrc
46 | # Token has no scope (read-only access to public information)
47 | - TSD_GITHUB_TOKEN=51b0c1347cfd8c2c90ba0f60db7898171cbb17c8
48 |
49 | cache:
50 | directories: node_modules
51 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Launch localhost with sourcemaps",
6 | "type": "chrome",
7 | "request": "launch",
8 | "url": "http://localhost:5555/",
9 | "sourceMaps": true,
10 | "webRoot": "${workspaceRoot}/dist/dev",
11 | "runtimeArgs": [
12 | "--remote-debugging-port=9222", //Open in port 9222 (standard chrome debug port)
13 | "--user-data-dir=${workspaceRoot}\\ChromeDebugger-UserData\\", //Can be any directory. Makes chrome load in a different directory so that it opens in a new instance.
14 | //"--user-data-dir=${env.LOCALAPPDATA}\\Google\\Chrome\\User Data\\", //CHROME DEFAULT
15 | "--new-window" //Open in new window
16 | ]
17 | },
18 | {
19 | "name": "Launch Electron App",
20 | "type": "node",
21 | "program": "${workspaceRoot}/dist/dev/main.desktop.js", // important
22 | "stopOnEntry": false,
23 | "args": [],
24 | "cwd": "${workspaceRoot}/dist/dev/",
25 | // next line is very important
26 | "runtimeExecutable": "${env.APPDATA}/npm/node_modules/electron-prebuilt/dist/electron.exe",
27 | "runtimeArgs": [],
28 | "env": { },
29 | "sourceMaps": true
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "**/nativescript/platforms": true,
5 | "src/client/**/*.js": true,
6 | "nativescript/app": true,
7 | "nativescript/src/**/*.js": true,
8 | "ChromeDebugger-UserData/**/*": true
9 | },
10 | "search.exclude": {
11 | "**/coverage_js": true,
12 | "**/coverage": true,
13 | "**/dist": true,
14 | "**/nativescript/platforms": true,
15 | "src/client/**/*.js": true,
16 | "nativescript/app": true,
17 | "nativescript/src/**/*.js": true,
18 | "ChromeDebugger-UserData/**/*": true
19 | },
20 | "typescript.tsdk": "node_modules/typescript/lib"
21 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "command": "npm",
4 | "isShellCommand": true,
5 | "showOutput": "always",
6 | "args": ["run"],
7 | "echoCommand": true,
8 | "tasks": [
9 | {
10 | "taskName": "reinstall",
11 | "isBuildCommand": false,
12 | "showOutput": "always",
13 | "isWatching": false,
14 | "isTestCommand": false
15 | },
16 | {
17 | "taskName": "start",
18 | "isBuildCommand": true,
19 | "showOutput": "always",
20 | "isWatching": true,
21 | "isTestCommand": false
22 | },
23 | {
24 | "taskName": "start.desktop",
25 | "isBuildCommand": false,
26 | "showOutput": "always",
27 | "isWatching": true,
28 | "isTestCommand": false
29 | },
30 | {
31 | "taskName": "start.desktop.windows",
32 | "isBuildCommand": false,
33 | "showOutput": "always",
34 | "isWatching": true,
35 | "isTestCommand": false
36 | },
37 | {
38 | "taskName": "start.livesync.desktop",
39 | "isBuildCommand": false,
40 | "showOutput": "always",
41 | "isWatching": true,
42 | "isTestCommand": false
43 | },
44 | {
45 | "taskName": "start.livesync.desktop.windows",
46 | "isBuildCommand": false,
47 | "showOutput": "always",
48 | "isWatching": true,
49 | "isTestCommand": false
50 | },
51 | {
52 | "taskName": "start.ios",
53 | "isBuildCommand": false,
54 | "showOutput": "always",
55 | "isWatching": true,
56 | "isTestCommand": false
57 | },
58 | {
59 | "taskName": "start.livesync.ios",
60 | "isBuildCommand": false,
61 | "showOutput": "always",
62 | "isWatching": true,
63 | "isTestCommand": false
64 | },
65 | {
66 | "taskName": "start.livesync.ios.device",
67 | "isBuildCommand": false,
68 | "showOutput": "always",
69 | "isWatching": true,
70 | "isTestCommand": false
71 | },
72 | {
73 | "taskName": "start.android",
74 | "isBuildCommand": false,
75 | "showOutput": "always",
76 | "isWatching": true,
77 | "isTestCommand": false
78 | },
79 | {
80 | "taskName": "start.livesync.android",
81 | "isBuildCommand": false,
82 | "showOutput": "always",
83 | "isWatching": true,
84 | "isTestCommand": false
85 | },
86 | {
87 | "taskName": "start.livesync.android.device",
88 | "isBuildCommand": false,
89 | "showOutput": "always",
90 | "isWatching": true,
91 | "isTestCommand": false
92 | },
93 | {
94 | "taskName": "test",
95 | "isBuildCommand": false,
96 | "showOutput": "always",
97 | "isWatching": true,
98 | "isTestCommand": true
99 | }
100 | ]
101 | }
102 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Submitting Pull Requests
2 |
3 | **Please follow these basic steps to simplify pull request reviews - if you don't you'll probably just be asked to anyway.**
4 |
5 | * Please rebase your branch against the current master
6 | * Run ```npm install``` to make sure your development dependencies are up-to-date
7 | * Please ensure that the test suite passes **and** that code is lint free before submitting a PR by running:
8 | * ```npm test```
9 | * If you've added new functionality, **please** include tests which validate its behaviour
10 | * Make reference to possible [issues](https://github.com/NathanWalker/angular-seed-advanced/issues) on PR comment
11 |
12 | ## Submitting bug reports
13 |
14 | * Please detail the affected browser(s) and operating system(s)
15 | * Please be sure to state which version of node **and** npm you're using
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Minko Gechev
4 | Copyright (c) 2016 Nathan Walker
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular Multi-Platform Starter
2 |
3 | ## This project is no longer maintained. Please visit https://github.com/TeamMaestro/angular-native-seed for a different way to build for NativeScript, the web, and Electron in the future.
4 |
5 | The Angular Multi-Platform Starter is a cloneable template for building apps for the web, for native mobile with [NativeScript](https://www.nativescript.org/), and for desktop with [Electron](http://electron.atom.io/). The template contains a series of npm scripts for running your apps in these environments, as well as a set of conventions for sharing and forking your code for each ecosystem—web, native mobile, and desktop. It is a basic version of Nathan Walker's [Advanced Angular Seed](https://github.com/NathanWalker/angular-seed-advanced).
6 |
7 | Visit our [**documentation hub**](https://jlooper.github.io/angular-starter/) for detailed information on this starter.
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/gulpfile.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as util from 'gulp-util';
3 | import * as runSequence from 'run-sequence';
4 |
5 | import Config from './tools/config';
6 | import { loadTasks, loadCompositeTasks } from './tools/utils';
7 |
8 |
9 | loadTasks(Config.SEED_TASKS_DIR);
10 | loadTasks(Config.PROJECT_TASKS_DIR);
11 |
12 | loadCompositeTasks(Config.SEED_COMPOSITE_TASKS, Config.PROJECT_COMPOSITE_TASKS);
13 |
14 |
15 | // --------------
16 | // Clean dev/coverage that will only run once
17 | // this prevents karma watchers from being broken when directories are deleted
18 | let firstRun = true;
19 | gulp.task('clean.once', (done: any) => {
20 | if (firstRun) {
21 | firstRun = false;
22 | runSequence('check.tools', 'clean.dev', 'clean.coverage', done);
23 | } else {
24 | util.log('Skipping clean on rebuild');
25 | done();
26 | }
27 | });
28 |
--------------------------------------------------------------------------------
/nativescript/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Launch on iOS Device",
6 | "type": "nativescript",
7 | "platform": "ios",
8 | "request": "launch",
9 | "appRoot": "${workspaceRoot}",
10 | "sourceMaps": true,
11 | "diagnosticLogging": false,
12 | "emulator": false
13 | },
14 | {
15 | "name": "Attach on iOS Device",
16 | "type": "nativescript",
17 | "platform": "ios",
18 | "request": "attach",
19 | "appRoot": "${workspaceRoot}",
20 | "sourceMaps": true,
21 | "diagnosticLogging": false,
22 | "emulator": false
23 | },
24 | {
25 | "name": "Launch on iOS Emulator",
26 | "type": "nativescript",
27 | "platform": "ios",
28 | "request": "launch",
29 | "appRoot": "${workspaceRoot}",
30 | "sourceMaps": true,
31 | "diagnosticLogging": false,
32 | "emulator": true
33 | },
34 | {
35 | "name": "Attach on iOS Emulator",
36 | "type": "nativescript",
37 | "platform": "ios",
38 | "request": "attach",
39 | "appRoot": "${workspaceRoot}",
40 | "sourceMaps": true,
41 | "diagnosticLogging": false,
42 | "emulator": true
43 | },
44 | {
45 | "name": "Launch on Android Device",
46 | "type": "nativescript",
47 | "platform": "android",
48 | "request": "launch",
49 | "appRoot": "${workspaceRoot}",
50 | "sourceMaps": true,
51 | "diagnosticLogging": false,
52 | "emulator": false
53 | },
54 | {
55 | "name": "Launch on Android Emulator",
56 | "type": "nativescript",
57 | "platform": "android",
58 | "request": "launch",
59 | "appRoot": "${workspaceRoot}",
60 | "sourceMaps": true,
61 | "diagnosticLogging": false,
62 | "emulator": true
63 | },
64 | {
65 | "name": "Attach on Android Device",
66 | "type": "nativescript",
67 | "platform": "android",
68 | "request": "attach",
69 | "appRoot": "${workspaceRoot}",
70 | "sourceMaps": false,
71 | "diagnosticLogging": false,
72 | "emulator": false
73 | },
74 | {
75 | "name": "Attach on Android Emulator",
76 | "type": "nativescript",
77 | "platform": "android",
78 | "request": "attach",
79 | "appRoot": "${workspaceRoot}",
80 | "sourceMaps": false,
81 | "diagnosticLogging": false,
82 | "emulator": true
83 | }
84 | ]
85 | }
--------------------------------------------------------------------------------
/nativescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-seed-advanced",
3 | "main": "app.js",
4 | "version": "0.0.0",
5 | "nativescript": {
6 | "id": "com.yourdomain.nativescript",
7 | "tns-ios": {
8 | "version": "2.5.0"
9 | },
10 | "tns-android": {
11 | "version": "2.5.0"
12 | }
13 | },
14 | "scripts": {
15 | "preinstall": "mkdirp app",
16 | "clean": "rimraf platforms node_modules lib hooks app && mkdirp app",
17 | "ns-bundle": "ns-bundle",
18 | "start-android-bundle": "npm run ns-bundle --android --start-app",
19 | "start-ios-bundle": "npm run ns-bundle --ios --start-app",
20 | "build-android-bundle": "npm run ns-bundle --android --build-app",
21 | "build-ios-bundle": "npm run ns-bundle --ios --build-app"
22 | },
23 | "dependencies": {
24 | "@angular/animations": "~4.0.0",
25 | "@angular/common": "~4.0.0",
26 | "@angular/compiler": "~4.0.0",
27 | "@angular/core": "~4.0.0",
28 | "@angular/forms": "~4.0.0",
29 | "@angular/http": "~4.0.0",
30 | "@angular/platform-browser": "~4.0.0",
31 | "@angular/platform-browser-dynamic": "~4.0.0",
32 | "@angular/router": "~4.0.0",
33 | "lodash": "^4.17.4",
34 | "nativescript-angular": "1.5.0",
35 | "nativescript-dev-webpack": "^0.3.1",
36 | "nativescript-theme-core": "^1.0.3",
37 | "reflect-metadata": "^0.1.8",
38 | "rxjs": "~5.2.0",
39 | "tns-core-modules": "~2.5.2",
40 | "url": "0.10.3",
41 | "zone.js": "~0.8.2"
42 | },
43 | "devDependencies": {
44 | "@angular/compiler-cli": "~4.0.0",
45 | "@ngtools/webpack": "~1.3.0",
46 | "@types/jasmine": "^2.5.35",
47 | "babel-traverse": "6.20.0",
48 | "babel-types": "6.20.0",
49 | "babylon": "6.14.1",
50 | "copy-webpack-plugin": "~4.0.1",
51 | "extract-text-webpack-plugin": "~2.1.0",
52 | "fs-extra": "^1.0.0",
53 | "htmlparser2": "^3.9.2",
54 | "lazy": "1.0.11",
55 | "nativescript-css-loader": "~0.26.1",
56 | "nativescript-dev-android-snapshot": "^0.*.*",
57 | "nativescript-dev-webpack": "^0.3.6",
58 | "raw-loader": "~0.5.1",
59 | "resolve-url-loader": "~2.0.2",
60 | "typescript": "~2.1.4",
61 | "webpack": "2.3.2",
62 | "webpack-sources": "~0.2.3"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/app.gradle:
--------------------------------------------------------------------------------
1 | // Add your native dependencies here:
2 |
3 | // Uncomment to add recyclerview-v7 dependency
4 | //dependencies {
5 | // compile 'com.android.support:recyclerview-v7:+'
6 | //}
7 |
8 | android {
9 | defaultConfig {
10 | generatedDensities = []
11 | applicationId = "__PACKAGE__"
12 | }
13 | aaptOptions {
14 | additionalParameters "--no-version-vectors"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/Android/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/Android/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/Android/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/drawable-nodpi/splashscreen.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/Android/drawable-nodpi/splashscreen.9.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/drawable/splash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/Android/drawable/splash_logo.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/Android/values/splash_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | NativeScript Splash
4 |
5 |
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "icon-29.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "icon-29@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon-29@3x.png",
19 | "scale" : "3x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "icon-40@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon-40@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "57x57",
35 | "idiom" : "iphone",
36 | "filename" : "icon-57.png",
37 | "scale" : "1x"
38 | },
39 | {
40 | "size" : "57x57",
41 | "idiom" : "iphone",
42 | "filename" : "icon-57@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon-60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "icon-60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "29x29",
59 | "idiom" : "ipad",
60 | "filename" : "icon-29.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "icon-29@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "40x40",
71 | "idiom" : "ipad",
72 | "filename" : "icon-40.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "icon-40@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "50x50",
83 | "idiom" : "ipad",
84 | "filename" : "icon-50.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "50x50",
89 | "idiom" : "ipad",
90 | "filename" : "icon-50@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "72x72",
95 | "idiom" : "ipad",
96 | "filename" : "icon-72.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "72x72",
101 | "idiom" : "ipad",
102 | "filename" : "icon-72@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "76x76",
107 | "idiom" : "ipad",
108 | "filename" : "icon-76.png",
109 | "scale" : "1x"
110 | },
111 | {
112 | "size" : "76x76",
113 | "idiom" : "ipad",
114 | "filename" : "icon-76@2x.png",
115 | "scale" : "2x"
116 | },
117 | {
118 | "size" : "83.5x83.5",
119 | "idiom" : "ipad",
120 | "filename" : "icon-83.5@2x.png",
121 | "scale" : "2x"
122 | }
123 | ],
124 | "info" : {
125 | "version" : 1,
126 | "author" : "xcode"
127 | }
128 | }
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "736h",
7 | "filename" : "Default-736h@3x.png",
8 | "minimum-system-version" : "8.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "736h",
16 | "filename" : "Default-Landscape@3x.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "landscape",
19 | "scale" : "3x"
20 | },
21 | {
22 | "extent" : "full-screen",
23 | "idiom" : "iphone",
24 | "subtype" : "667h",
25 | "filename" : "Default-667h@2x.png",
26 | "minimum-system-version" : "8.0",
27 | "orientation" : "portrait",
28 | "scale" : "2x"
29 | },
30 | {
31 | "orientation" : "portrait",
32 | "idiom" : "iphone",
33 | "filename" : "Default@2x.png",
34 | "extent" : "full-screen",
35 | "minimum-system-version" : "7.0",
36 | "scale" : "2x"
37 | },
38 | {
39 | "extent" : "full-screen",
40 | "idiom" : "iphone",
41 | "subtype" : "retina4",
42 | "filename" : "Default-568h@2x.png",
43 | "minimum-system-version" : "7.0",
44 | "orientation" : "portrait",
45 | "scale" : "2x"
46 | },
47 | {
48 | "orientation" : "portrait",
49 | "idiom" : "ipad",
50 | "filename" : "Default-Portrait.png",
51 | "extent" : "full-screen",
52 | "minimum-system-version" : "7.0",
53 | "scale" : "1x"
54 | },
55 | {
56 | "orientation" : "landscape",
57 | "idiom" : "ipad",
58 | "filename" : "Default-Landscape.png",
59 | "extent" : "full-screen",
60 | "minimum-system-version" : "7.0",
61 | "scale" : "1x"
62 | },
63 | {
64 | "orientation" : "portrait",
65 | "idiom" : "ipad",
66 | "filename" : "Default-Portrait@2x.png",
67 | "extent" : "full-screen",
68 | "minimum-system-version" : "7.0",
69 | "scale" : "2x"
70 | },
71 | {
72 | "orientation" : "landscape",
73 | "idiom" : "ipad",
74 | "filename" : "Default-Landscape@2x.png",
75 | "extent" : "full-screen",
76 | "minimum-system-version" : "7.0",
77 | "scale" : "2x"
78 | },
79 | {
80 | "orientation" : "portrait",
81 | "idiom" : "iphone",
82 | "filename" : "Default.png",
83 | "extent" : "full-screen",
84 | "scale" : "1x"
85 | },
86 | {
87 | "orientation" : "portrait",
88 | "idiom" : "iphone",
89 | "filename" : "Default@2x.png",
90 | "extent" : "full-screen",
91 | "scale" : "2x"
92 | },
93 | {
94 | "orientation" : "portrait",
95 | "idiom" : "iphone",
96 | "filename" : "Default-568h@2x.png",
97 | "extent" : "full-screen",
98 | "subtype" : "retina4",
99 | "scale" : "2x"
100 | },
101 | {
102 | "orientation" : "portrait",
103 | "idiom" : "ipad",
104 | "extent" : "to-status-bar",
105 | "scale" : "1x"
106 | },
107 | {
108 | "orientation" : "portrait",
109 | "idiom" : "ipad",
110 | "filename" : "Default-Portrait.png",
111 | "extent" : "full-screen",
112 | "scale" : "1x"
113 | },
114 | {
115 | "orientation" : "landscape",
116 | "idiom" : "ipad",
117 | "extent" : "to-status-bar",
118 | "scale" : "1x"
119 | },
120 | {
121 | "orientation" : "landscape",
122 | "idiom" : "ipad",
123 | "filename" : "Default-Landscape.png",
124 | "extent" : "full-screen",
125 | "scale" : "1x"
126 | },
127 | {
128 | "orientation" : "portrait",
129 | "idiom" : "ipad",
130 | "extent" : "to-status-bar",
131 | "scale" : "2x"
132 | },
133 | {
134 | "orientation" : "portrait",
135 | "idiom" : "ipad",
136 | "filename" : "Default-Portrait@2x.png",
137 | "extent" : "full-screen",
138 | "scale" : "2x"
139 | },
140 | {
141 | "orientation" : "landscape",
142 | "idiom" : "ipad",
143 | "extent" : "to-status-bar",
144 | "scale" : "2x"
145 | },
146 | {
147 | "orientation" : "landscape",
148 | "idiom" : "ipad",
149 | "filename" : "Default-Landscape@2x.png",
150 | "extent" : "full-screen",
151 | "scale" : "2x"
152 | }
153 | ],
154 | "info" : {
155 | "version" : 1,
156 | "author" : "xcode"
157 | }
158 | }
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-AspectFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-AspectFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-Center.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-Center@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiresFullScreen
28 |
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | NSAppTransportSecurity
47 |
48 |
49 | NSAllowsArbitraryLoads
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/nativescript/src/App_Resources/iOS/build.xcconfig:
--------------------------------------------------------------------------------
1 | // You can add custom settings here
2 | // for example you can uncomment the following line to force distribution code signing
3 | // CODE_SIGN_IDENTITY = iPhone Distribution
4 | // To build for device with Xcode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html
5 | // DEVELOPMENT_TEAM = YOUR_TEAM_ID;
6 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
7 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
8 |
--------------------------------------------------------------------------------
/nativescript/src/app.aot.ts:
--------------------------------------------------------------------------------
1 | // this import should be first in order to load some required settings (like globals and reflect-metadata)
2 | import { platformNativeScript } from 'nativescript-angular/platform-static';
3 |
4 | import { NativeModuleNgFactory } from './native.module.ngfactory';
5 | import { enableProdMode } from '@angular/core';
6 |
7 | enableProdMode();
8 |
9 | platformNativeScript().bootstrapModuleFactory(NativeModuleNgFactory);
10 |
--------------------------------------------------------------------------------
/nativescript/src/app.css:
--------------------------------------------------------------------------------
1 | @import 'nativescript-theme-core/css/core.light.css';
2 |
3 | .link {
4 | border-width: 0;
5 | background-color: transparent;
6 | }
7 | .odd {
8 | background-color: #efefef;
9 | }
10 | .even {
11 | background-color: #fff;
12 | }
--------------------------------------------------------------------------------
/nativescript/src/app.ts:
--------------------------------------------------------------------------------
1 | // nativescript
2 | import { platformNativeScriptDynamic } from 'nativescript-angular';
3 |
4 | // app
5 | import { NativeModule } from './native.module';
6 |
7 | platformNativeScriptDynamic().bootstrapModule(NativeModule);
8 |
--------------------------------------------------------------------------------
/nativescript/src/components.module.ts:
--------------------------------------------------------------------------------
1 | // nativescript
2 | import { NativeScriptModule } from 'nativescript-angular/nativescript.module';
3 | import { NativeScriptFormsModule } from 'nativescript-angular/forms';
4 | import { NativeScriptHttpModule } from 'nativescript-angular/http';
5 | import { NativeScriptRouterModule } from 'nativescript-angular/router';
6 | import { Http } from '@angular/http';
7 |
8 | // angular
9 | import { NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
10 |
11 | // app
12 | import { AppComponent } from './app/shared/sample/components/app/app.component';
13 | import { HomeComponent } from './app/shared/sample/components/home/home.component';
14 | import { routes } from './app/shared/sample/components/app/app.routes';
15 |
16 | // feature modules
17 | import { CoreModule } from './app/shared/core/core.module';
18 | import { SampleModule } from './app/shared/sample/sample.module';
19 |
20 | // intermediate component module
21 | // helps encapsulate custom native modules in with the components
22 | // note: couple ways this could be done, just one option presented here...
23 | @NgModule({
24 | imports: [
25 | NativeScriptModule,
26 | NativeScriptFormsModule,
27 | NativeScriptHttpModule,
28 | NativeScriptRouterModule,
29 | CoreModule,
30 | SampleModule
31 | ],
32 | declarations: [
33 | AppComponent,
34 | HomeComponent
35 | ],
36 | schemas: [
37 | NO_ERRORS_SCHEMA,
38 | CUSTOM_ELEMENTS_SCHEMA
39 | ],
40 | exports: [
41 | NativeScriptModule,
42 | NativeScriptFormsModule,
43 | NativeScriptHttpModule,
44 | NativeScriptRouterModule,
45 | AppComponent,
46 | CoreModule,
47 | SampleModule
48 | ]
49 | })
50 | export class ComponentsModule { }
51 |
52 | // For AoT compilation to work:
53 | export function cons() {
54 | return console;
55 | }
56 |
--------------------------------------------------------------------------------
/nativescript/src/mobile/core/index.ts:
--------------------------------------------------------------------------------
1 | // services
2 | export * from './services/window-native.service';
3 | export * from './services/ns-app.service';
4 |
5 | // utils
6 | export * from './utils/actionbar.util';
7 |
--------------------------------------------------------------------------------
/nativescript/src/mobile/core/services/ns-app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { NSLocationStrategy } from 'nativescript-angular/router/ns-location-strategy';
4 |
5 | // nativescript
6 | import * as nsApp from 'application';
7 | import { isAndroid, isIOS } from 'platform';
8 |
9 | if (isIOS) {
10 | /*
11 | nsApp.ios.delegate = require('../PATH/TO/DELEGATE').CustomAppDelegate;
12 | */
13 | }
14 |
15 | // app
16 | import { AppService } from '../../../app/shared/core/services/app.service';
17 | import { Config } from '../../../app/shared/core/utils';
18 | import { LogService, WindowService, RouterExtensions } from '../../../app/shared/core/index';
19 | import { ActionBarUtil } from '../utils/actionbar.util';
20 |
21 | declare var android: any;
22 |
23 | @Injectable()
24 | export class NSAppService extends AppService {
25 | nsApp = nsApp;
26 |
27 | // Remember to update iOS and android constructors if you change dependencies
28 | // @Inject decorator is used on injectables here since this component merely extends AppComponent
29 | // Since @Component decorator is not used here, this ensures metadata will be generated
30 | constructor(public log: LogService,
31 | public router: Router,
32 | public locationstrategy: NSLocationStrategy,
33 | public window: WindowService
34 | ) {
35 | super(log);
36 |
37 | this.log.debug('NSAppService constructor');
38 |
39 | /**
40 | * Top status bar on iOS and/or Android
41 | * iOs {number}
42 | * 0: default
43 | * 1: light
44 | * Android {string}
45 | * hex value
46 | */
47 | ActionBarUtil.STATUSBAR_STYLE(
48 | isIOS ? 1 : '#3280CF'
49 | );
50 |
51 | if (String('<%= BUILD_TYPE %>') !== 'prod') {
52 | log.debug('NSAppCmp ----');
53 |
54 | router.events.subscribe((e) => {
55 | this.log.debug(`Router Event: ${e.toString()}`);
56 | });
57 | }
58 |
59 | // Fix: Reset all nsApp events before subscribing to avoid Duplicate events.
60 | // this.unsubscribeAll();
61 |
62 | nsApp.on(nsApp.launchEvent, (eventData: nsApp.LaunchEventData) => {
63 | this.log.info('TNS Application - Launched!');
64 | });
65 |
66 | nsApp.on(nsApp.suspendEvent, (eventData: nsApp.ApplicationEventData) => {
67 | this.log.info('TNS Application - Suspended');
68 | });
69 |
70 | nsApp.on(nsApp.resumeEvent, (eventData: nsApp.ApplicationEventData) => {
71 | this.log.info('TNS Application - Resumed');
72 | });
73 |
74 | nsApp.on(nsApp.lowMemoryEvent, (eventData: nsApp.ApplicationEventData) => {
75 | this.log.warn('TNS Application - !!! LOW MEMORY !!!');
76 | });
77 |
78 | nsApp.on(nsApp.exitEvent, (eventData: any) => {
79 | this.log.info('TNS Application - EXIT');
80 | this.unsubscribeAll();
81 | });
82 |
83 | this.setupAndroid();
84 | this.setupIOS();
85 | }
86 |
87 | protected handleUncaughtError(err: any, platform: 'android' | 'ios') {
88 | this.log.info(`TNS Application - Uncaught Error: ${err.message}`);
89 |
90 | const errorDescription: any = {
91 | message: err.message,
92 | android: platform === 'android',
93 | ios: platform === 'ios',
94 | stackTrace: err.stackTrace,
95 | nativeException: err.nativeException,
96 | };
97 |
98 | for (const key of Object.keys(errorDescription)) {
99 | if (errorDescription[key]) {
100 | console.log(`**** START - errorDescription.${key} - ****\n\n\n${errorDescription[key]}\n\n\n*** END - ${key} - ****`);
101 | }
102 | }
103 | }
104 |
105 | private unsubscribeAll() {
106 | nsApp.off(nsApp.launchEvent);
107 | nsApp.off(nsApp.suspendEvent);
108 | nsApp.off(nsApp.resumeEvent);
109 | nsApp.off(nsApp.lowMemoryEvent);
110 | nsApp.off(nsApp.exitEvent);
111 | nsApp.off(nsApp.uncaughtErrorEvent);
112 | }
113 |
114 | private setupAndroid() {
115 | if (!isAndroid) {
116 | return;
117 | }
118 |
119 | // Android specific code goes here
120 |
121 | this.nsApp.android.on(this.nsApp.AndroidApplication.activityBackPressedEvent, (args) => {
122 | const states = this.locationstrategy._getStates();
123 | this.log.info(`Event: ${args.eventName}\nActivity: ${args.activity}\nstates: ${JSON.stringify(states)}`);
124 | });
125 |
126 | this.nsApp.android.on(this.nsApp.AndroidApplication.activityResumedEvent, (args) => {
127 | if (args.activity.getIntent().getAction() === android.content.Intent.ACTION_VIEW) {
128 | const intentData = args.activity.getIntent().getData();
129 | console.log(`Android received VIEW intent, with data: ${intentData}`);
130 | }
131 | });
132 |
133 | this.nsApp.on(this.nsApp.uncaughtErrorEvent, (err) => {
134 | this.handleUncaughtError(err.android, 'android');
135 | });
136 | }
137 |
138 | private setupIOS() {
139 | if (!isIOS) {
140 | return;
141 | }
142 |
143 | this.nsApp.on(this.nsApp.uncaughtErrorEvent, (err) => {
144 | this.handleUncaughtError(err.ios, 'ios');
145 | });
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/nativescript/src/mobile/core/services/window-native.service.ts:
--------------------------------------------------------------------------------
1 | // nativescript
2 | import * as dialogs from 'ui/dialogs';
3 | import { device } from 'platform';
4 |
5 | // app
6 | import { IWindow } from '../../../app/shared/core/interfaces/iwindow';
7 |
8 | export class WindowNative implements IWindow {
9 | public get navigator(): any {
10 | return {
11 | language: device.language,
12 | userAgent: 'nativescript'
13 | };
14 | }
15 | public get location(): any {
16 | return {
17 | host: 'nativescript'
18 | };
19 | }
20 | public alert(msg: string): Promise {
21 | return dialogs.alert(msg);
22 | }
23 | public confirm(msg: string): Promise {
24 | return dialogs.confirm(msg);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/nativescript/src/mobile/core/utils/actionbar.util.ts:
--------------------------------------------------------------------------------
1 | import { topmost } from 'ui/frame';
2 | import { ActionItem, ActionItems } from 'ui/action-bar';
3 | import * as app from 'application';
4 | import { device, isAndroid } from 'platform';
5 | import { Color } from 'color';
6 | declare var android;
7 |
8 | declare var UIBarStyle: any;
9 |
10 | export class ActionBarUtil {
11 | public static SET_TITLE(title: string) {
12 | var actionBar = topmost().currentPage.actionBar;
13 | actionBar.title = title;
14 | }
15 | public static ADD_BUTTON(button: ActionItem) {
16 | // NOTE: This MUST be called BEFORE SET_TITLE on start
17 | topmost().currentPage.actionBar.actionItems.addItem(button);
18 | }
19 | public static HIDE_BACK_BUTTON() {
20 | if (topmost().ios) {
21 | topmost().ios.controller.visibleViewController.navigationItem.setHidesBackButtonAnimated(true, false);
22 | }
23 | }
24 | public static EMPTY_ITEMS() {
25 | var actionBar = topmost().currentPage.actionBar;
26 | var actionItems = actionBar.actionItems.getItems();
27 | actionItems.forEach((item) => {
28 | actionBar.actionItems.removeItem(item);
29 | });
30 | }
31 | public static STATUSBAR_STYLE(style: number | string) {
32 | if (topmost().ios) {
33 | let navigationBar = topmost().ios.controller.navigationBar;
34 | // 0: default
35 | // 1: light
36 | navigationBar.barStyle = style;
37 | } else if (isAndroid) {
38 | if (app.android && device.sdkVersion >= '21') {
39 | try {
40 | let LayoutParams = android.view.WindowManager.LayoutParams;
41 | let win: any;
42 | if (app.android.foregroundActivity) {
43 | win = app.android.foregroundActivity.getWindow();
44 | } else {
45 | win = app.android.startActivity.getWindow();
46 | }
47 |
48 | win.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
49 | win.setStatusBarColor(new Color(style || '#3280CF').android);
50 | } catch (err) {
51 | console.log(err);
52 | }
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/nativescript/src/native.module.ts:
--------------------------------------------------------------------------------
1 | // nativescript
2 | import {
3 | NativeScriptRouterModule,
4 | RouterExtensions as TNSRouterExtensions
5 | } from 'nativescript-angular/router';
6 |
7 | // angular
8 | import { NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
9 |
10 | // app
11 | import {
12 | WindowService,
13 | ConsoleService,
14 | RouterExtensions,
15 | AppService
16 | } from './app/shared/core/index';
17 | import { AppComponent } from './app/shared/sample/components/app/app.component';
18 | import { routes } from './app/shared/sample/components/app/app.routes';
19 |
20 | // feature modules
21 | import { CoreModule } from './app/shared/core/core.module';
22 | import { ComponentsModule, cons } from './components.module';
23 |
24 | // {N} custom app specific
25 | import { WindowNative, NSAppService } from './mobile/core/index';
26 |
27 | /**
28 | * Config
29 | * Seed provided configuration options
30 | */
31 | import { Config } from './app/shared/core/index';
32 | import { Page } from 'ui/page';
33 | Config.PageClass = Page;
34 |
35 | // (required) platform target (allows component decorators to use the right view template)
36 | Config.PLATFORM_TARGET = Config.PLATFORMS.MOBILE_NATIVE;
37 |
38 | // (optional) log level - defaults to no logging if not set
39 | Config.DEBUG.LEVEL_4 = true;
40 |
41 | // (optional) custom i18n language support
42 | // example of how you can configure your own language sets
43 | // you can use the AppConfig class or build something similar into your own framework
44 | import { AppConfig } from './app/shared/sample/services/app-config';
45 |
46 | @NgModule({
47 | imports: [
48 | CoreModule.forRoot([
49 | { provide: WindowService, useClass: WindowNative },
50 | { provide: ConsoleService, useFactory: (cons) },
51 | ]),
52 | ComponentsModule,
53 | NativeScriptRouterModule.forRoot(routes)
54 | ],
55 | providers: [
56 | { provide: RouterExtensions, useClass: TNSRouterExtensions },
57 | { provide: AppService, useClass: NSAppService },
58 | ],
59 | schemas: [
60 | NO_ERRORS_SCHEMA,
61 | CUSTOM_ELEMENTS_SCHEMA
62 | ],
63 | bootstrap: [AppComponent]
64 | })
65 | export class NativeModule { }
66 |
--------------------------------------------------------------------------------
/nativescript/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tns-template-hello-world",
3 | "main": "app.js",
4 | "version": "1.2.0",
5 | "author": "Telerik ",
6 | "description": "Nativescript hello-world project template",
7 | "license": "MIT",
8 | "repository": {
9 | "type": "git",
10 | "url": "git://github.com/NativeScript/template-hello-world.git"
11 | },
12 | "bugs": {
13 | "url": "https://github.com/NativeScript/template-hello-world/issues"
14 | },
15 | "homepage": "https://github.com/NativeScript/template-hello-world"
16 | }
17 |
--------------------------------------------------------------------------------
/nativescript/src/references.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/nativescript/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "declaration": false,
6 | "removeComments": true,
7 | "noLib": false,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "lib": [
11 | "es6",
12 | "dom",
13 | "es2015.iterable"
14 | ],
15 | "sourceMap": true,
16 | "pretty": true,
17 | "noEmitHelpers": true,
18 | "allowUnreachableCode": false,
19 | "allowUnusedLabels": false,
20 | "noImplicitAny": false,
21 | "noImplicitReturns": true,
22 | "noImplicitUseStrict": false,
23 | "noFallthroughCasesInSwitch": true,
24 | "typeRoots": [
25 | "../node_modules/@types",
26 | "../node_modules"
27 | ],
28 | "types": [
29 | "jasmine"
30 | ]
31 | },
32 | "exclude": [
33 | "node_modules",
34 | "platforms",
35 | "*.aot.ts"
36 | ],
37 | "compileOnSave": false
38 | }
--------------------------------------------------------------------------------
/nativescript/src/vendor-platform.android.ts:
--------------------------------------------------------------------------------
1 | //Resolve JavaScript classes that extend a Java class, and need to resolve
2 | //their JavaScript module from a bundled script. For example:
3 | //NativeScriptApplication, NativeScriptActivity, etc.
4 | //
5 | //This module gets bundled together with the rest of the app code and the
6 | //`require` calls get resolved to the correct bundling import call.
7 | //
8 | //At runtime the module gets loaded *before* the rest of the app code, so code
9 | //placed here needs to be careful about its dependencies.
10 |
11 | require('application');
12 | require('ui/frame');
13 | require('ui/frame/activity');
14 |
15 | if (global.TNS_WEBPACK) {
16 | global.__requireOverride = function (name, dir) {
17 | if (name === './tns_modules/application/application.js') {
18 | return require('application');
19 | } else if (name === './tns_modules/ui/frame/frame.js') {
20 | return require('ui/frame');
21 | } else if (name === './tns_modules/ui/frame/activity.js') {
22 | return require('ui/frame/activity');
23 | }
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/nativescript/src/vendor-platform.ios.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/nativescript/src/vendor-platform.ios.ts
--------------------------------------------------------------------------------
/nativescript/src/vendor.ts:
--------------------------------------------------------------------------------
1 | require('./vendor-platform');
2 |
3 | require('reflect-metadata');
4 | require('@angular/platform-browser');
5 | require('@angular/core');
6 | require('@angular/common');
7 | require('@angular/forms');
8 | require('@angular/http');
9 | require('@angular/router');
10 |
11 | require('nativescript-angular/platform-static');
12 | require('nativescript-angular/forms');
13 | require('nativescript-angular/http');
14 | require('nativescript-angular/router');
15 |
--------------------------------------------------------------------------------
/nativescript/tools/webpack/tns-loader.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs-extra');
2 | const loaderUtils = require('loader-utils');;
3 | const _ = require('lodash');
4 | const template = _.template;
5 |
6 | const htmlCssRegexp = /\.component\.(html|css)/;
7 | const htmlCssReplaceStr = '.component.tns.\$1';
8 | const componentRegexp = /\.component\.(ts|js)/;
9 | const componentFactoryRegexp = /\.component\.ngfactory\.(ts|js)/;
10 |
11 | const ng2TemplateUrlRegex = /templateUrl *:(.*)$/gm;
12 | const ng2StyleUrlsRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
13 | const ng2StringReplaceRegexp = /(['"])((?:[^\\]\\\1|.)*?)\1/g;
14 | const ng2ModuleIdRegexp = /(moduleId *: *module\.id,)$/gm;
15 |
16 | function replaceStringsWithRequires(string) {
17 | return string.replace(ng2StringReplaceRegexp, function (match, quote, url) {
18 | if (url.charAt(0) !== '.') {
19 | url = './' + url;
20 | }
21 |
22 | const tnsPath = url.replace(htmlCssRegexp, htmlCssReplaceStr);
23 | if (fs.existsSync(tnsPath)) {
24 | return 'require(\'' + tnsPath + '\')';
25 | }
26 |
27 | return 'require(\'' + url + '\')';
28 | });
29 | }
30 |
31 | function injectTemplateVariables(loaderContext, source) {
32 | // Inject template variables via lodash.template
33 | // Note: We only support the '= varname ?>' syntax (default matches and breaks on es6 string literals).
34 | const query = loaderUtils.getOptions(loaderContext);
35 |
36 | const tpl = template(source, {
37 | interpolate: /<%=([\s\S]+?)%>/g,
38 | });
39 |
40 | return tpl(query.data);
41 | }
42 |
43 | module.exports = function tnsLoader(source) {
44 | if (this.resourcePath.match(htmlCssRegexp)) {
45 | // If a tns-version of the html/css file exists, replace the source with the content of that file.
46 | const tnsPath = this.resourcePath.replace(htmlCssRegexp, htmlCssReplaceStr);
47 | if (fs.existsSync(tnsPath)) {
48 | const tnsSource = fs.readFileSync(tnsPath, 'UTF-8');
49 | source = 'module.exports = ' + JSON.stringify(tnsSource);
50 | }
51 | } else if (this.resourcePath.match(componentRegexp)) {
52 | // For ng2 components cnnvert:
53 | // styleUrls = ['file1', ..., fileN] => styles = [require('file1'), ..., require('fileN')]
54 | // templateUrl: 'file' => template: require('file')
55 | //
56 | // Removes moduleId
57 | const styleProperty = 'styles';
58 | const templateProperty = 'template';
59 |
60 | source = source.replace(ng2TemplateUrlRegex, function replaceTemplateUrl(match, url) {
61 | return templateProperty + ':' + replaceStringsWithRequires(url);
62 | })
63 | .replace(ng2StyleUrlsRegex, function replaceStyleUrls(match, urls) {
64 | return styleProperty + ':' + replaceStringsWithRequires(urls);
65 | })
66 | .replace(ng2ModuleIdRegexp, function moduleId(match, moduleId) {
67 | return '/* ' + moduleId + ' */';
68 | });
69 | } else if (this.resourcePath.match(componentFactoryRegexp)) {
70 | // TODO: should/could we do something with the NgFactory files?
71 | }
72 |
73 | return injectTemplateVariables(this, source);
74 | };
--------------------------------------------------------------------------------
/nativescript/tsconfig.aot.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "es2015",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": false,
10 | "noImplicitAny": false,
11 | "noEmitHelpers": true,
12 | "suppressImplicitAnyIndexErrors": true,
13 | "types": [],
14 | "baseUrl": ".",
15 | "paths": {
16 | "ui/*": ["node_modules/tns-core-modules/ui/*"],
17 | "platform": ["node_modules/tns-core-modules/platform"],
18 | "image-source": ["node_modules/tns-core-modules/image-source"],
19 | "xml": ["node_modules/tns-core-modules/xml"],
20 | "xhr": ["node_modules/tns-core-modules/xhr"],
21 | "text": ["node_modules/tns-core-modules/text"],
22 | "data": ["node_modules/tns-core-modules/data"],
23 | "fetch": ["node_modules/tns-core-modules/fetch"],
24 | "trace": ["node_modules/tns-core-modules/trace"],
25 | "fps-meter": ["node_modules/tns-core-modules/fps-meter"],
26 | "color": ["node_modules/tns-core-modules/color"],
27 | "application-settings": ["node_modules/tns-core-modules/application-settings"],
28 | "http": ["node_modules/tns-core-modules/http"],
29 | "camera": ["node_modules/tns-core-modules/camera"],
30 | "console": ["node_modules/tns-core-modules/console"],
31 | "timer": ["node_modules/tns-core-modules/timer"],
32 | "utils": ["node_modules/tns-core-modules/utils"],
33 | "location": ["node_modules/tns-core-modules/location"],
34 | "file-system": ["node_modules/tns-core-modules/file-system"],
35 | "application": ["node_modules/tns-core-modules/application"],
36 | "image-asset": ["node_modules/tns-core-modules/image-asset"],
37 | "connectivity": ["node_modules/tns-core-modules/connectivity"],
38 | "globals": ["node_modules/tns-core-modules/globals"]
39 | }
40 | },
41 | "exclude": [
42 | "node_modules",
43 | "platforms",
44 | "src"
45 | ],
46 | "angularCompilerOptions": {
47 | "skipMetadataEmit": true,
48 | "genDir": "./"
49 | }
50 | }
--------------------------------------------------------------------------------
/nativescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "declaration": false,
7 | "removeComments": true,
8 | "noLib": false,
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "lib": [
12 | "es6",
13 | "dom",
14 | "es2015.iterable"
15 | ],
16 | "sourceMap": true,
17 | "pretty": true,
18 | "noEmitHelpers": true,
19 | "allowUnreachableCode": false,
20 | "allowUnusedLabels": false,
21 | "noImplicitAny": false,
22 | "noImplicitReturns": true,
23 | "noImplicitUseStrict": false,
24 | "noFallthroughCasesInSwitch": true,
25 | "baseUrl": ".",
26 | "paths": {
27 | "*": [
28 | "./node_modules/tns-core-modules/*",
29 | "./node_modules/*"
30 | ]
31 | },
32 | "typeRoots": [
33 | "../node_modules/@types",
34 | "../node_modules"
35 | ],
36 | "types": [
37 | "jasmine"
38 | ]
39 | },
40 | "exclude": [
41 | "node_modules",
42 | "platforms",
43 | "src",
44 | "**/*.aot.ts"
45 | ],
46 | "compileOnSave": false
47 | }
48 |
--------------------------------------------------------------------------------
/nativescript/webpack.android.js:
--------------------------------------------------------------------------------
1 | var makeConfig = require("./webpack.common");
2 | module.exports = makeConfig("android");
3 |
--------------------------------------------------------------------------------
/nativescript/webpack.ios.js:
--------------------------------------------------------------------------------
1 | var makeConfig = require("./webpack.common");
2 | module.exports = makeConfig("ios");
3 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/core.module.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { NgModule, ModuleWithProviders, Optional, SkipSelf } from '@angular/core';
3 | import { CommonModule } from '@angular/common';
4 | import { FormsModule } from '@angular/forms';
5 | import { RouterModule } from '@angular/router';
6 | import { HttpModule } from '@angular/http';
7 |
8 | // module
9 | import { CORE_DIRECTIVES } from './directives/index';
10 | import { CORE_PROVIDERS } from './services/index';
11 | import { Config } from './utils/index';
12 |
13 | interface ICoreModuleOptions {
14 | window?: any;
15 | console?: any;
16 | }
17 |
18 | /**
19 | * Do not specify providers for modules that might be imported by a lazy loaded module.
20 | */
21 |
22 | @NgModule({
23 | imports: [
24 | CommonModule,
25 | RouterModule,
26 | HttpModule
27 | ],
28 | declarations: [
29 | CORE_DIRECTIVES
30 | ],
31 | exports: [
32 | CommonModule,
33 | FormsModule,
34 | RouterModule,
35 | HttpModule,
36 | CORE_DIRECTIVES
37 | ],
38 | providers: [
39 | CORE_PROVIDERS
40 | ]
41 | })
42 | export class CoreModule {
43 | // configuredProviders: *required to configure WindowService and ConsoleService per platform
44 | static forRoot(configuredProviders: Array): ModuleWithProviders {
45 | return {
46 | ngModule: CoreModule,
47 | providers: configuredProviders
48 | };
49 | }
50 | constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
51 | if (parentModule) {
52 | throw new Error('CoreModule already loaded; Import in root module only.');
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/directives/index.ts:
--------------------------------------------------------------------------------
1 | // app
2 | import { PlatformDirective } from './platform.directive';
3 |
4 | export const CORE_DIRECTIVES: any[] = [
5 | PlatformDirective
6 | ];
7 |
8 | export * from './platform.directive';
9 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/directives/platform.directive.spec.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { TestBed } from '@angular/core/testing';
3 | import { Component } from '@angular/core';
4 |
5 | // app
6 | import { t } from '../../test/index';
7 |
8 | // module
9 | import { PlatformDirective } from './platform.directive';
10 | import { WindowService } from '../../core/index';
11 | import { WindowMock } from '../../core/testing/index';
12 |
13 | const testModuleConfig = () => {
14 | TestBed.configureTestingModule({
15 | declarations: [PlatformDirective, TestComponent]
16 | });
17 | };
18 |
19 | @Component({
20 | viewProviders: [
21 | { provide: WindowService, useClass: WindowMock }
22 | ],
23 | selector: 'test-cmp',
24 | template: ``
25 | })
26 | class TestComponent { }
27 |
28 | export function main() {
29 | t.describe('core: PlatformDirective', () => {
30 |
31 | t.be(testModuleConfig);
32 |
33 | t.it('should add platform class',
34 | t.async(() => {
35 | TestBed.compileComponents()
36 | .then(() => {
37 | let fixture = TestBed.createComponent(TestComponent);
38 | fixture.detectChanges();
39 | let compDOMEl = fixture.debugElement.children[0].nativeElement;
40 | t.e(compDOMEl.getAttribute('class')).toBe('web');
41 | });
42 | }));
43 | });
44 | }
45 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/directives/platform.directive.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { Directive, ElementRef, Renderer } from '@angular/core';
3 |
4 | // module
5 | import { WindowService } from '../services/window.service';
6 |
7 | @Directive({
8 | selector: '[platform]'
9 | })
10 | export class PlatformDirective {
11 |
12 | constructor(private el: ElementRef, private renderer: Renderer, private win: WindowService) {
13 | let platformClass = 'web';
14 | let agent = win.navigator.userAgent.toLowerCase();
15 | if (agent.indexOf('electron') > -1) {
16 | platformClass = 'desktop';
17 | } else if (agent.indexOf('nativescript') > -1) {
18 | platformClass = 'nativescript';
19 | }
20 | renderer.setElementClass(el.nativeElement, platformClass, true);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/index.ts:
--------------------------------------------------------------------------------
1 | // utilities
2 | // generally static helpers (non-injectables)
3 | export * from './utils/index';
4 |
5 | // interfaces
6 | export * from './interfaces/index';
7 |
8 | // services
9 | export * from './services/index';
10 |
11 | // directives
12 | export * from './directives/index';
13 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/interfaces/iconsole.ts:
--------------------------------------------------------------------------------
1 | // standard console interface
2 | export interface IConsole {
3 | log(m: any): void;
4 | debug(m: any): void;
5 | error(m: any): void;
6 | warn(m: any): void;
7 | info(m: any): void;
8 | }
9 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/interfaces/ilang.ts:
--------------------------------------------------------------------------------
1 | // standard language interface
2 | export interface ILang {
3 | code: string;
4 | title: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export * from './iconsole';
2 | export * from './ilang';
3 | export * from './iwindow';
4 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/interfaces/iwindow.ts:
--------------------------------------------------------------------------------
1 | // standard window interface
2 | export interface IWindow {
3 | navigator: any;
4 | location: any;
5 | alert(msg: string): void;
6 | confirm(msg: string): void;
7 | }
8 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | // app
4 | import { LogService } from './log.service';
5 | import { Config } from '../utils/config';
6 |
7 | @Injectable()
8 | export class AppService {
9 | constructor(public log: LogService) {
10 | this.log.debug(`AppService -> Config env: ${Config.ENVIRONMENT().ENV}`);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/console.service.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { Injectable } from '@angular/core';
3 |
4 | // module
5 | import { IConsole } from '../interfaces/iconsole';
6 |
7 | @Injectable()
8 | export class ConsoleService implements IConsole {
9 |
10 | public log(m: any): void { return; }
11 | public debug(m: any): void { return; }
12 | public error(m: any): void { return; }
13 | public warn(m: any): void { return; }
14 | public info(m: any): void { return; }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/index.ts:
--------------------------------------------------------------------------------
1 | // app
2 | import { ConsoleService } from './console.service';
3 | import { LogService } from './log.service';
4 | import { RouterExtensions } from './router-extensions.service';
5 | import { WindowService } from './window.service';
6 | import { AppService } from './app.service';
7 |
8 | export const CORE_PROVIDERS: any[] = [
9 | AppService,
10 | ConsoleService,
11 | LogService,
12 | RouterExtensions,
13 | WindowService
14 | ];
15 |
16 | export * from './app.service';
17 | export * from './console.service';
18 | export * from './log.service';
19 | export * from './router-extensions.service';
20 | export * from './window.service';
21 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/log.service.spec.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { TestBed } from '@angular/core/testing';
3 |
4 | // app
5 | import { t } from '../../test/index';
6 |
7 | // module
8 | import { Config, ConsoleService, LogService } from '../index';
9 |
10 | const providers: Array = [
11 | { provide: ConsoleService, useValue: console },
12 | LogService
13 | ];
14 |
15 | export function main() {
16 | t.describe('core: LogService', () => {
17 |
18 | t.be(() => {
19 | // ensure statics are in default state
20 | Config.RESET();
21 | // spy
22 | t.spyOn(console, 'log');
23 | t.spyOn(console, 'error');
24 | t.spyOn(console, 'warn');
25 | t.spyOn(console, 'info');
26 |
27 | TestBed.configureTestingModule({
28 | providers: providers
29 | });
30 | });
31 |
32 | t.describe('api', () => {
33 |
34 | t.it('sanity', t.inject([LogService], (log: LogService) => {
35 | t.e(log.debug).toBeDefined();
36 | t.e(log.error).toBeDefined();
37 | t.e(log.warn).toBeDefined();
38 | t.e(log.info).toBeDefined();
39 | }));
40 |
41 | t.it('should not log anything by default', t.inject([LogService], (log: LogService) => {
42 | log.debug('debug');
43 | t.e(console.log).not.toHaveBeenCalledWith('debug');
44 | log.error('error');
45 | t.e(console.error).not.toHaveBeenCalledWith('error');
46 | log.warn('warn');
47 | t.e(console.warn).not.toHaveBeenCalledWith('warn');
48 | log.info('info');
49 | t.e(console.info).not.toHaveBeenCalledWith('info');
50 | }));
51 | });
52 |
53 | t.describe('debug levels', () => {
54 |
55 | t.be(() => {
56 | Config.RESET();
57 | });
58 |
59 | t.it('LEVEL_4: everything', t.inject([LogService], (log: LogService) => {
60 | Config.DEBUG.LEVEL_4 = true;
61 |
62 | log.debug('debug');
63 | t.e(console.log).toHaveBeenCalledWith('debug');
64 | log.error('error');
65 | t.e(console.error).toHaveBeenCalledWith('error');
66 | log.warn('warn');
67 | t.e(console.warn).toHaveBeenCalledWith('warn');
68 | log.info('info');
69 | t.e(console.info).toHaveBeenCalledWith('info');
70 | }));
71 |
72 | t.it('LEVEL_3: error only', t.inject([LogService], (log: LogService) => {
73 | Config.DEBUG.LEVEL_3 = true;
74 |
75 | log.debug('debug');
76 | t.e(console.log).not.toHaveBeenCalledWith('debug');
77 | log.error('error');
78 | t.e(console.error).toHaveBeenCalledWith('error');
79 | log.warn('warn');
80 | t.e(console.warn).not.toHaveBeenCalledWith('warn');
81 | log.info('info');
82 | t.e(console.info).not.toHaveBeenCalledWith('info');
83 |
84 | // always overrides lower levels and allows them to come through
85 | Config.DEBUG.LEVEL_4 = true;
86 |
87 | log.debug('debug w/level_4');
88 | t.e(console.log).toHaveBeenCalledWith('debug w/level_4');
89 | log.error('error w/level_4');
90 | t.e(console.error).toHaveBeenCalledWith('error w/level_4');
91 | log.warn('warn w/level_4');
92 | t.e(console.warn).toHaveBeenCalledWith('warn w/level_4');
93 | log.info('info w/level_4');
94 | t.e(console.info).toHaveBeenCalledWith('info w/level_4');
95 | }));
96 |
97 | t.it('LEVEL_2: warn only', t.inject([LogService], (log: LogService) => {
98 | Config.DEBUG.LEVEL_2 = true;
99 |
100 | log.debug('debug');
101 | t.e(console.log).not.toHaveBeenCalledWith('debug');
102 | log.error('error');
103 | t.e(console.error).not.toHaveBeenCalledWith('error');
104 | log.warn('warn');
105 | t.e(console.warn).toHaveBeenCalledWith('warn');
106 | log.info('info');
107 | t.e(console.info).not.toHaveBeenCalledWith('info');
108 | }));
109 |
110 | t.it('LEVEL_1: info only', t.inject([LogService], (log: LogService) => {
111 | Config.DEBUG.LEVEL_1 = true;
112 |
113 | log.debug('debug');
114 | t.e(console.log).not.toHaveBeenCalledWith('debug');
115 | log.error('error');
116 | t.e(console.error).not.toHaveBeenCalledWith('error');
117 | log.warn('warn');
118 | t.e(console.warn).not.toHaveBeenCalledWith('warn');
119 | log.info('info');
120 | t.e(console.info).toHaveBeenCalledWith('info');
121 | }));
122 | });
123 | });
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/log.service.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { Injectable, Inject, forwardRef } from '@angular/core';
3 |
4 | // module
5 | import { Config } from '../utils/config';
6 | import { ConsoleService } from './console.service';
7 |
8 | @Injectable()
9 | export class LogService {
10 |
11 | constructor(@Inject(forwardRef(() => ConsoleService)) public logger: ConsoleService) {}
12 |
13 | // debug (standard output)
14 | public debug(msg: any) {
15 | if (Config.DEBUG.LEVEL_4) {
16 | // console.debug does not work on {N} apps... use `log`
17 | this.logger.log(msg);
18 | }
19 | }
20 |
21 | // error
22 | public error(err: any) {
23 | if (Config.DEBUG.LEVEL_4 || Config.DEBUG.LEVEL_3) {
24 | this.logger.error(err);
25 | }
26 | }
27 |
28 | // warn
29 | public warn(err: any) {
30 | if (Config.DEBUG.LEVEL_4 || Config.DEBUG.LEVEL_2) {
31 | this.logger.warn(err);
32 | }
33 | }
34 |
35 | // info
36 | public info(err: any) {
37 | if (Config.DEBUG.LEVEL_4 || Config.DEBUG.LEVEL_1) {
38 | this.logger.info(err);
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/router-extensions.service.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { Injectable } from '@angular/core';
3 | import { LocationStrategy } from '@angular/common';
4 | import { Router, UrlTree, NavigationExtras } from '@angular/router';
5 |
6 | export interface ExtendedNavigationExtras extends NavigationExtras {
7 | // Options for nativescript
8 | clearHistory?: boolean;
9 | animated?: boolean;
10 | transition?: { // See -> https://docs.nativescript.org/api-reference/interfaces/_ui_frame_.navigationtransition.html
11 | name?: string;
12 | instance?: any;
13 | duration?: number;
14 | curve?: any;
15 | };
16 | // END - Options for nativescript
17 | }
18 |
19 | export interface IRouterExtensions {
20 | navigate(commands: Array, extras?: ExtendedNavigationExtras): Promise;
21 | navigateByUrl(url: string | UrlTree, options?: ExtendedNavigationExtras): Promise;
22 | back(): void;
23 | }
24 |
25 | @Injectable()
26 | export class RouterExtensions implements IRouterExtensions {
27 |
28 | constructor(public router: Router, private locationStrategy: LocationStrategy) { }
29 |
30 | public navigate(commands: Array, extras?: ExtendedNavigationExtras): Promise {
31 | return this.router.navigate(commands, extras);
32 | }
33 |
34 | public navigateByUrl(url: string | UrlTree, options?: ExtendedNavigationExtras): Promise {
35 | return this.router.navigateByUrl(url);
36 | }
37 |
38 | public back() {
39 | this.locationStrategy.back();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/services/window.service.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { Injectable } from '@angular/core';
3 |
4 | // module
5 | import { IWindow } from '../interfaces/iwindow';
6 |
7 | @Injectable()
8 | export class WindowService implements IWindow {
9 |
10 | public navigator: any = {};
11 | public location: any = {};
12 | public alert(msg: string): void { return; }
13 | public confirm(msg: string): void { return; }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/tokens.ts:
--------------------------------------------------------------------------------
1 | import {OpaqueToken} from '@angular/core';
2 |
3 | export const FRAME: OpaqueToken = new OpaqueToken('Frame');
4 |
5 |
6 | export const TOKENS_SHARED: Array = [
7 | { provide: FRAME, useValue: {} }
8 | ];
--------------------------------------------------------------------------------
/src/client/app/shared/core/utils/config.spec.ts:
--------------------------------------------------------------------------------
1 | // libs
2 | import * as _ from 'lodash';
3 |
4 | // app
5 | import { t } from '../../test/index';
6 |
7 | // module
8 | import { Config } from './config';
9 |
10 | export function main() {
11 | t.describe('core: Config', () => {
12 | t.be(() => Config.RESET());
13 |
14 | t.it('ENVIRONMENT', () => {
15 | t.e(Config.ENVIRONMENT).toBeDefined();
16 | });
17 | t.it('PLATFORMS', () => {
18 | t.e(_.keys(Config.PLATFORMS).length).toBe(4);
19 | t.e(Config.PLATFORM_TARGET).toBeDefined();
20 | t.e(Config.PLATFORMS.WEB).toBe('web');
21 | t.e(Config.PLATFORMS.MOBILE_NATIVE).toBe('mobile_native');
22 | t.e(Config.PLATFORMS.MOBILE_HYBRID).toBe('mobile_hybrid');
23 | t.e(Config.PLATFORMS.DESKTOP).toBe('desktop');
24 |
25 | t.e(Config.IS_WEB).toBeDefined();
26 | t.e(Config.IS_MOBILE_NATIVE).toBeDefined();
27 | t.e(Config.IS_MOBILE_HYBRID).toBeDefined();
28 | t.e(Config.IS_DESKTOP).toBeDefined();
29 | });
30 | t.it('DEBUG', () => {
31 | t.e(Config.DEBUG.LEVEL_1).toBe(false);
32 | t.e(Config.DEBUG.LEVEL_2).toBe(false);
33 | t.e(Config.DEBUG.LEVEL_3).toBe(false);
34 | t.e(Config.DEBUG.LEVEL_4).toBe(false);
35 | t.e(Config.IS_DEBUG_MODE()).toBe(false);
36 | });
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/utils/config.ts:
--------------------------------------------------------------------------------
1 | // Feel free to extend this interface
2 | // depending on your app specific config.
3 | export interface EnvConfig {
4 | API?: string;
5 | ENV?: string;
6 | }
7 |
8 | export interface IPlatforms {
9 | WEB: string;
10 | MOBILE_NATIVE: string;
11 | MOBILE_HYBRID: string;
12 | DESKTOP: string;
13 | }
14 |
15 | export class Config {
16 |
17 | public static PageClass: any;
18 |
19 | public static DEBUG: any = {
20 | LEVEL_1: false, // .info only
21 | LEVEL_2: false, // .warn only
22 | LEVEL_3: false, // .error only
23 | LEVEL_4: false // .log + all the above
24 | };
25 |
26 | // supported platforms
27 | public static PLATFORMS: IPlatforms = {
28 | WEB: 'web',
29 | MOBILE_NATIVE: 'mobile_native',
30 | MOBILE_HYBRID: 'mobile_hybrid',
31 | DESKTOP: 'desktop'
32 | };
33 |
34 | // current target (defaults to web)
35 | public static PLATFORM_TARGET: string = Config.PLATFORMS.WEB;
36 |
37 | // convenient platform checks
38 | public static IS_WEB(): boolean {
39 | return Config.PLATFORM_TARGET === Config.PLATFORMS.WEB;
40 | }
41 |
42 | public static IS_MOBILE_NATIVE(): boolean {
43 | return Config.PLATFORM_TARGET === Config.PLATFORMS.MOBILE_NATIVE;
44 | }
45 |
46 | public static IS_MOBILE_HYBRID(): boolean {
47 | return Config.PLATFORM_TARGET === Config.PLATFORMS.MOBILE_HYBRID;
48 | }
49 |
50 | public static IS_DESKTOP(): boolean {
51 | return Config.PLATFORM_TARGET === Config.PLATFORMS.DESKTOP;
52 | }
53 |
54 | public static ENVIRONMENT(): EnvConfig {
55 | try {
56 | return JSON.parse('<%= ENV_CONFIG %>');
57 | } catch (exp) {
58 | return {};
59 | }
60 | }
61 |
62 | public static IS_DEBUG_MODE(): boolean {
63 | for (let key in Config.DEBUG) {
64 | if (Config.DEBUG[key]) {
65 | // if any level is on, debug mode is on
66 | return true;
67 | }
68 | }
69 | return false;
70 | }
71 |
72 | // reset debug defaults
73 | public static RESET() {
74 | for (let key in Config.DEBUG) {
75 | Config.DEBUG[key] = false;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './config';
2 | export * from './type';
3 | export * from './view-broker';
4 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/utils/type.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This function coerces a string into a string literal type.
3 | * Using tagged union types in TypeScript 2.0, this enables
4 | * powerful typechecking of our reducers.
5 | *
6 | * Since every action label passes through this function it
7 | * is a good place to ensure all of our action labels
8 | * are unique.
9 | */
10 |
11 | let typeCache: { [label: string]: boolean } = {};
12 | export function type(label: T | ''): T {
13 | if (typeCache[label]) {
14 | throw new Error(`Action type "${label}" is not unqiue"`);
15 | }
16 |
17 | typeCache[label] = true;
18 |
19 | return label;
20 | }
21 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/utils/view-broker.spec.ts:
--------------------------------------------------------------------------------
1 | // app
2 | import { t } from '../../test/index';
3 |
4 | // module
5 | import { Config } from './config';
6 | import { ViewBroker } from './view-broker';
7 |
8 | export function main() {
9 | t.describe('utilities: ViewBroker', () => {
10 |
11 | t.it('TEMPLATE_URL: web', () => {
12 | Config.PLATFORM_TARGET = Config.PLATFORMS.WEB;
13 | t.e(ViewBroker.TEMPLATE_URL('./app/components/home/home.html')).toBe('./app/components/home/home.html');
14 | });
15 | t.it('TEMPLATE_URL: mobile_native', () => {
16 | Config.PLATFORM_TARGET = Config.PLATFORMS.MOBILE_NATIVE;
17 | t.e(ViewBroker.TEMPLATE_URL('./app/components/home/home.html')).toBe('./app/components/home/home.tns.html');
18 | });
19 | t.it('TEMPLATE_URL: mobile_hybrid', () => {
20 | Config.PLATFORM_TARGET = Config.PLATFORMS.MOBILE_HYBRID;
21 | t.e(ViewBroker.TEMPLATE_URL('./app/components/home/home.html')).toBe('./app/components/home/home.html');
22 | });
23 | t.it('TEMPLATE_URL: desktop', () => {
24 | Config.PLATFORM_TARGET = Config.PLATFORMS.DESKTOP;
25 | t.e(ViewBroker.TEMPLATE_URL('./app/components/home/home.html')).toBe('./app/components/home/home.html');
26 | });
27 | });
28 | }
29 |
--------------------------------------------------------------------------------
/src/client/app/shared/core/utils/view-broker.ts:
--------------------------------------------------------------------------------
1 | // module
2 | import { Config } from './config';
3 |
4 | export class ViewBroker {
5 |
6 | public static TEMPLATE_URL(path: string): string {
7 | if (Config.IS_MOBILE_NATIVE()) {
8 | let paths = path.split('.');
9 | paths.splice(-1);
10 | return `${paths.join('.')}.tns.html`;
11 | } else {
12 | return path;
13 | }
14 | }
15 |
16 | public static STYLE_URLS(paths: string[]): string[] {
17 | if (Config.IS_MOBILE_NATIVE()) {
18 | return paths.map((path) => {
19 | let parts = path.split('.');
20 | parts.splice(-1);
21 | return `${parts.join('.')}.tns.css`;
22 | });
23 | } else {
24 | return paths;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/client/app/shared/electron/index.ts:
--------------------------------------------------------------------------------
1 | // services
2 | export * from './services/event.service';
3 |
4 | // utils
5 | export * from './utils/desktop-config';
6 |
--------------------------------------------------------------------------------
/src/client/app/shared/electron/services/event.service.ts:
--------------------------------------------------------------------------------
1 | // libs
2 | import { Observable } from 'rxjs/Observable';
3 | import 'rxjs/add/observable/fromEvent';
4 |
5 | declare var window: any;
6 |
7 | export class ElectronEventService {
8 |
9 | public static on(name: string): Observable {
10 | return Observable.fromEvent(window, name);
11 | }
12 |
13 | // TODO: add more helpers for menu setup and more...
14 | }
15 |
--------------------------------------------------------------------------------
/src/client/app/shared/electron/utils/desktop-config.spec.ts:
--------------------------------------------------------------------------------
1 | import { t } from '../../test/index';
2 | import { DesktopConfig } from './desktop-config';
3 |
4 | export function main() {
5 | t.describe('electron: DesktopConfig', () => {
6 |
7 | t.it('SUPPORTED_LANGUAGES', () => {
8 | t.e(DesktopConfig.SUPPORTED_LANGUAGES.length).toBe(5);
9 | t.e(DesktopConfig.SUPPORTED_LANGUAGES[0].code).toBe('en');
10 | t.e(DesktopConfig.SUPPORTED_LANGUAGES[1].code).toBe('es');
11 | t.e(DesktopConfig.SUPPORTED_LANGUAGES[2].code).toBe('fr');
12 | t.e(DesktopConfig.SUPPORTED_LANGUAGES[3].code).toBe('ru');
13 | t.e(DesktopConfig.SUPPORTED_LANGUAGES[4].code).toBe('bg');
14 | });
15 | });
16 | }
17 |
--------------------------------------------------------------------------------
/src/client/app/shared/electron/utils/desktop-config.ts:
--------------------------------------------------------------------------------
1 | // app
2 | import { ILang } from '../../core/index';
3 |
4 | export class DesktopConfig {
5 |
6 | public static SUPPORTED_LANGUAGES: Array = [
7 | { code: 'en', title: 'English' },
8 | { code: 'es', title: 'Spanish' },
9 | { code: 'fr', title: 'French' },
10 | { code: 'ru', title: 'Russian' },
11 | { code: 'bg', title: 'Bulgarian' }
12 | ];
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/app/app.component.tns.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/app/app.component.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import {Component} from '@angular/core';
3 |
4 | // app
5 |
6 | @Component({
7 | moduleId: module.id,
8 | selector: 'sd-app',
9 | templateUrl: 'app.component.html',
10 | })
11 | export class AppComponent {}
12 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | // app
2 | import {HomeRoutes} from '../../components/home/home.routes';
3 |
4 | export const routes: Array = [
5 | ...HomeRoutes
6 | ];
7 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/home/home.component.html:
--------------------------------------------------------------------------------
1 | Your App
2 |
3 |
Tap the button
4 |
5 |
{{ message }}
6 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/home/home.component.tns.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | moduleId: module.id,
5 | selector: 'sd-home',
6 | templateUrl: 'home.component.html',
7 | styleUrls: ['home.css']
8 | })
9 | export class HomeComponent implements OnInit {
10 | private counter: number;
11 | private message: string;
12 |
13 | constructor() {}
14 |
15 | ngOnInit() {
16 | this.counter = 42;
17 | this.updateMessage();
18 | }
19 |
20 | updateCounter() {
21 | this.counter--;
22 | this.updateMessage();
23 | }
24 |
25 | private updateMessage() {
26 | if (this.counter <= 0) {
27 | this.message = 'Hoorraaay! You unlocked the NativeScript clicker achievement!';
28 | } else {
29 | this.message = `${this.counter} taps left`;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/home/home.css:
--------------------------------------------------------------------------------
1 | button {
2 | background-color: #30BCFF;
3 | color: white;
4 | padding: 0.5em 1em;
5 | border: none;
6 | font-size: 1.5em;
7 | }
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/home/home.routes.ts:
--------------------------------------------------------------------------------
1 | import { Route } from '@angular/router';
2 |
3 | import { HomeComponent } from './home.component';
4 |
5 | export const HomeRoutes: Route[] = [
6 | {
7 | path: '',
8 | component: HomeComponent
9 | },
10 | ];
11 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/home/home.tns.css:
--------------------------------------------------------------------------------
1 | .btn {
2 | font-size: 30;
3 | }
--------------------------------------------------------------------------------
/src/client/app/shared/sample/components/index.ts:
--------------------------------------------------------------------------------
1 | import { HomeComponent } from './home/home.component';
2 |
3 |
4 | // for routes
5 | export const APP_COMPONENTS: any[] = [
6 | HomeComponent
7 | ];
8 |
9 | export * from './app/app.component';
10 | export * from './home/home.component';
11 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/index.ts:
--------------------------------------------------------------------------------
1 | // components
2 | export * from './components/index';
3 |
4 | // directives
5 | // export * from './directives/index';
6 |
7 | // services
8 | export * from './services/index';
9 |
10 | // routes
11 | export * from './routes';
12 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/models/sample.model.ts:
--------------------------------------------------------------------------------
1 | export class SampleModel {
2 | }
--------------------------------------------------------------------------------
/src/client/app/shared/sample/routes.ts:
--------------------------------------------------------------------------------
1 | import {HomeRoutes} from './components/home/home.routes';
2 |
3 | export const routes: Array = [
4 | ...HomeRoutes
5 | ];
6 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/sample.module.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { NgModule, ModuleWithProviders, Optional, SkipSelf } from '@angular/core';
3 |
4 | // app
5 | import { CoreModule } from '../core/core.module';
6 | import { TOKENS_SHARED } from '../core/tokens';
7 | import { SAMPLE_PROVIDERS } from './services/index';
8 |
9 |
10 | /**
11 | * Do not specify providers for modules that might be imported by a lazy loaded module.
12 | */
13 |
14 | @NgModule({
15 | imports: [
16 | CoreModule
17 | ],
18 | providers: [
19 | SAMPLE_PROVIDERS,
20 | TOKENS_SHARED
21 | ]
22 | })
23 | export class SampleModule {
24 | static forRoot(configuredProviders: Array): ModuleWithProviders {
25 | return {
26 | ngModule: SampleModule,
27 | providers: configuredProviders
28 | };
29 | }
30 | constructor( @Optional() @SkipSelf() parentModule: SampleModule) {
31 | console.log(`SampleModule constructor`);
32 | if (parentModule) {
33 | throw new Error('SampleModule already loaded; Import in root module only.');
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/services/app-config.ts:
--------------------------------------------------------------------------------
1 | // app
2 | import { ILang } from '../../core/index';
3 |
4 | export class AppConfig {
5 |
6 | public static SUPPORTED_LANGUAGES: Array = [
7 | { code: 'en', title: 'English' },
8 | { code: 'es', title: 'Spanish' },
9 | { code: 'fr', title: 'French' },
10 | { code: 'ru', title: 'Russian' },
11 | { code: 'bg', title: 'Bulgarian' }
12 | ];
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/client/app/shared/sample/services/index.ts:
--------------------------------------------------------------------------------
1 | import {SampleService} from './sample.service';
2 |
3 | export const SAMPLE_PROVIDERS: Array = [
4 | SampleService
5 | ];
6 |
7 | export * from './sample.service';
--------------------------------------------------------------------------------
/src/client/app/shared/sample/services/sample.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {LogService} from '../../core/services/log.service';
3 | import {Config} from '../../core/utils/config';
4 | import {Observable} from 'rxjs/Observable';
5 | import {BehaviorSubject} from 'rxjs/BehaviorSubject';
6 | import 'rxjs/add/operator/share';
7 | import {SampleModel} from '../models/sample.model';
8 |
9 | @Injectable()
10 | export class SampleService {
11 |
12 | constructor(
13 | private logger: LogService) {
14 | logger.debug(`SampleService initializing...`);
15 |
16 | if (Config.IS_MOBILE_NATIVE()) {
17 | //initialize your service for NativeScript
18 | } else {
19 | //initialize it for web
20 | }
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/client/assets/data.json:
--------------------------------------------------------------------------------
1 | [
2 | "Edsger Dijkstra",
3 | "Donald Knuth",
4 | "Alan Turing",
5 | "Grace Hopper"
6 | ]
7 |
--------------------------------------------------------------------------------
/src/client/assets/favicon/favicon-DEV.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/src/client/assets/favicon/favicon-DEV.ico
--------------------------------------------------------------------------------
/src/client/assets/favicon/favicon-PROD.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/src/client/assets/favicon/favicon-PROD.ico
--------------------------------------------------------------------------------
/src/client/assets/logo.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/src/client/assets/logo.icns
--------------------------------------------------------------------------------
/src/client/assets/logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlooper/angular-starter/b76aa75485e9222c1dc7f4ad8730b9e19582bcd6/src/client/assets/logo.ico
--------------------------------------------------------------------------------
/src/client/assets/svg/more.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= APP_TITLE %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | <% if (TARGET_DESKTOP) { %>
16 |
17 |
18 | <% } %>
19 |
20 |
21 |
22 |
23 | Loading...
24 |
25 |
29 |
30 | <% if (!TARGET_DESKTOP) { %>
31 |
32 |
33 | <% } %>
34 |
35 | <% if (BUILD_TYPE === 'dev') { %>
36 |
37 | <% } %>
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | <% if (BUILD_TYPE === 'dev') { %>
46 |
53 | <% } %>
54 |
55 | <% if (TARGET_DESKTOP && BUILD_TYPE !== 'prod') { %>
56 |
57 | <% } %>
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/client/main.web.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstraps the application and makes the ROUTER_PROVIDERS and the APP_BASE_HREF available to it.
3 | * @see https://angular.io/docs/ts/latest/api/platform-browser-dynamic/index/bootstrap-function.html
4 | */
5 | import { enableProdMode } from '@angular/core';
6 | import { platformBrowser } from '@angular/platform-browser';
7 |
8 | import { WebModuleNgFactory } from './web.module.ngfactory';
9 |
10 | enableProdMode();
11 |
12 | platformBrowser().bootstrapModuleFactory(WebModuleNgFactory);
13 |
14 | // In order to start the Service Worker located at "./worker.js"
15 | // uncomment this line. More about Service Workers here
16 | // https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers
17 | //
18 | // if ('serviceWorker' in navigator) {
19 | // (navigator).serviceWorker.register('./worker.js').then((registration: any) =>
20 | // console.log('ServiceWorker registration successful with scope: ', registration.scope))
21 | // .catch((err: any) =>
22 | // console.log('ServiceWorker registration failed: ', err));
23 | // }
24 |
--------------------------------------------------------------------------------
/src/client/main.web.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstraps the application and makes the ROUTER_PROVIDERS and the APP_BASE_HREF available to it.
3 | * @see https://angular.io/docs/ts/latest/api/platform-browser-dynamic/index/bootstrap-function.html
4 | */
5 | import { enableProdMode } from '@angular/core';
6 | // The browser platform with a compiler
7 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
8 | // Load i18n providers
9 | // import { TranslationProviders } from './i18n.providers';
10 |
11 | // platfrom module
12 | import { WebModule } from './web.module';
13 |
14 | // example of how to use build variables to determine environment
15 | if (String('<%= BUILD_TYPE %>') === 'prod' || String('<%= TARGET_DESKTOP_BUILD %>') === 'true') {
16 | enableProdMode();
17 | }
18 |
19 | // NOTE: Commented lines come from parent (angular-seed)
20 | // TODO: In future, may pivot from ng2-translate to parent seed implementation
21 | // Compile and launch the module with i18n providers
22 | // let TP = new TranslationProviders();
23 | // TP.getTranslationFile().then((providers: any) => {
24 | // const options: any = { providers };
25 | platformBrowserDynamic().bootstrapModule(WebModule/*, options*/);
26 | // });
27 |
--------------------------------------------------------------------------------
/src/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-seed-advanced",
3 | "version": "1.0.0",
4 | "main": "main.desktop.js"
5 | }
6 |
--------------------------------------------------------------------------------
/src/client/system-config.ts:
--------------------------------------------------------------------------------
1 | declare var System: SystemJSLoader.System;
2 |
3 | System.config(JSON.parse('<%= SYSTEM_CONFIG_DEV %>'));
4 |
--------------------------------------------------------------------------------
/src/client/tokens.web.ts:
--------------------------------------------------------------------------------
1 |
2 | export const TOKENS_WEB: Array = [
3 | ];
--------------------------------------------------------------------------------
/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "declaration": false,
6 | "removeComments": true,
7 | "noLib": false,
8 | "lib": ["es2016", "dom"],
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "sourceMap": true,
12 | "pretty": true,
13 | "allowUnreachableCode": false,
14 | "allowUnusedLabels": false,
15 | "noImplicitAny": false,
16 | "noImplicitReturns": true,
17 | "noImplicitUseStrict": false,
18 | "noFallthroughCasesInSwitch": true,
19 | "allowSyntheticDefaultImports": true,
20 | "typeRoots": [
21 | "../../node_modules/@types",
22 | "../../node_modules"
23 | ],
24 | "types": [
25 | "node",
26 | "jasmine",
27 | "protractor",
28 | "systemjs"
29 | ]
30 | },
31 | "exclude": [
32 | "desktop",
33 | "nativescript",
34 | "node_modules",
35 | "dist",
36 | "src"
37 | ],
38 | "compileOnSave": false
39 | }
40 |
--------------------------------------------------------------------------------
/src/client/web.module.ts:
--------------------------------------------------------------------------------
1 | // angular
2 | import { NgModule } from '@angular/core';
3 | import { APP_BASE_HREF } from '@angular/common';
4 | import { BrowserModule } from '@angular/platform-browser';
5 | import { RouterModule } from '@angular/router';
6 | import { Http } from '@angular/http';
7 |
8 | // app
9 | import { APP_COMPONENTS, AppComponent } from './app/shared/sample/components/index';
10 | import { routes } from './app/shared/sample/components/app/app.routes';
11 |
12 | // feature modules
13 | import { CoreModule } from './app/shared/core/core.module';
14 | import { SampleModule } from './app/shared/sample/sample.module';
15 |
16 | // config
17 | import { Config, WindowService, ConsoleService } from './app/shared/core/index';
18 | Config.PLATFORM_TARGET = Config.PLATFORMS.WEB;
19 | if (String('<%= BUILD_TYPE %>') === 'dev') {
20 | // only output console logging in dev mode
21 | Config.DEBUG.LEVEL_4 = true;
22 | }
23 |
24 | // sample config (extra)
25 | import { AppConfig } from './app/shared/sample/services/app-config';
26 |
27 | let routerModule = RouterModule.forRoot(routes);
28 |
29 | if (String('<%= TARGET_DESKTOP %>') === 'true') {
30 | Config.PLATFORM_TARGET = Config.PLATFORMS.DESKTOP;
31 | // desktop (electron) must use hash
32 | routerModule = RouterModule.forRoot(routes, {useHash: true});
33 | }
34 |
35 | declare var window, console;
36 |
37 | // For AoT compilation to work:
38 | export function win() {
39 | return window;
40 | }
41 | export function cons() {
42 | return console;
43 | }
44 |
45 | let DEV_IMPORTS: any[] = [];
46 |
47 | if (String('<%= BUILD_TYPE %>') === 'dev') {
48 | DEV_IMPORTS = [
49 | ...DEV_IMPORTS
50 | ];
51 | }
52 |
53 | @NgModule({
54 | imports: [
55 | BrowserModule,
56 | CoreModule.forRoot([
57 | { provide: WindowService, useFactory: (win) },
58 | { provide: ConsoleService, useFactory: (cons) }
59 | ]),
60 | routerModule,
61 | SampleModule,
62 | DEV_IMPORTS
63 | ],
64 | declarations: [
65 | APP_COMPONENTS,
66 | AppComponent
67 | ],
68 | providers: [
69 | {
70 | provide: APP_BASE_HREF,
71 | useValue: '<%= APP_BASE %>'
72 | }
73 | ],
74 | bootstrap: [AppComponent]
75 | })
76 |
77 | export class WebModule { }
78 |
--------------------------------------------------------------------------------
/tools/config.ts:
--------------------------------------------------------------------------------
1 | import { ProjectConfig } from './config/project.config';
2 |
3 | const config: ProjectConfig = new ProjectConfig();
4 | export default config;
5 |
--------------------------------------------------------------------------------
/tools/config/banner.txt:
--------------------------------------------------------------------------------
1 | Welcome to _ _
2 | __ _ _ __ __ _ _ _| | __ _ _ __ ___ ___ ___ __| |
3 | / _` | '_ \ / _` | | | | |/ _` | '__|____/ __|/ _ \/ _ \/ _` |
4 | | (_| | | | | (_| | |_| | | (_| | | |_____\__ \ __/ __/ (_| |
5 | \__,_|_| |_|\__, |\__,_|_|\__,_|_| |___/\___|\___|\__,_|
6 | |___/
7 |
--------------------------------------------------------------------------------
/tools/config/project.config.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import { SeedAdvancedConfig } from './seed-advanced.config';
3 | // import { ExtendPackages } from './seed.config.interfaces';
4 |
5 | /**
6 | * This class extends the basic seed configuration, allowing for project specific overrides. A few examples can be found
7 | * below.
8 | */
9 | export class ProjectConfig extends SeedAdvancedConfig {
10 |
11 | PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');
12 |
13 | constructor() {
14 | super();
15 | // this.APP_TITLE = 'Put name of your app here';
16 |
17 | /* Enable typeless compiler runs (faster) between typed compiler runs. */
18 | // this.TYPED_COMPILE_INTERVAL = 5;
19 |
20 | // Add `NPM` third-party libraries to be injected/bundled.
21 | this.NPM_DEPENDENCIES = [
22 | ...this.NPM_DEPENDENCIES,
23 | // {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
24 | ];
25 |
26 | // Add `local` third-party libraries to be injected/bundled.
27 | this.APP_ASSETS = [
28 | ...this.APP_ASSETS,
29 | // {src: `${this.APP_SRC}/your-path-to-lib/libs/jquery-ui.js`, inject: true, vendor: false}
30 | // {src: `${this.CSS_SRC}/path-to-lib/test-lib.css`, inject: true, vendor: false},
31 | ];
32 |
33 | // Add packages (e.g. ng2-translate)
34 | // ng2-translate is already added with the advanced seed - here for example only
35 | // let additionalPackages: ExtendPackages[] = [{
36 | // name: 'ng2-translate',
37 | // // Path to the package's bundle
38 | // path: 'node_modules/ng2-translate/bundles/ng2-translate.umd.js'
39 | // }];
40 | //
41 | // this.addPackagesBundles(additionalPackages);
42 |
43 | /* Add to or override NPM module configurations: */
44 | // this.mergeObject(this.PLUGIN_CONFIGS['browser-sync'], { ghostMode: false });
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/tools/config/project.tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "test": [
3 | "tslint",
4 | "build.test",
5 | "karma.run"
6 | ]
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/tools/config/seed-advanced.config.ts:
--------------------------------------------------------------------------------
1 | import { argv } from 'yargs';
2 | import { SeedConfig } from './seed.config';
3 | import * as path from 'path';
4 | import { ExtendPackages } from './seed.config.interfaces';
5 |
6 | export class SeedAdvancedConfig extends SeedConfig {
7 | /**
8 | * The base folder of the nativescript applications source files.
9 | * @type {string}
10 | */
11 | TNS_BASE_DIR = 'nativescript';
12 |
13 | srcSubdir = 'src';
14 | destSubdir = 'app';
15 |
16 | TNS_APP_SRC = `${this.TNS_BASE_DIR}/${this.srcSubdir}`;
17 |
18 | TNS_APP_DEST = `${this.TNS_BASE_DIR}/${this.destSubdir}`;
19 |
20 | TNS_CONFIG = {
21 | ANALYTICS_TRACKING_ID: '',
22 | };
23 |
24 | /**
25 | * Holds added packages for desktop build.
26 | */
27 | DESKTOP_PACKAGES: ExtendPackages[] = [];
28 |
29 | constructor() {
30 | super();
31 |
32 | let arg: string;
33 | if (argv && argv._) {
34 | arg = argv._[0];
35 | if (arg.indexOf('desktop') > -1) {
36 | this.TARGET_DESKTOP = true;
37 | if (arg.indexOf('.mac') > -1 || arg.indexOf('.windows') > -1 || arg.indexOf('.linux') > -1) {
38 | this.TARGET_DESKTOP_BUILD = true;
39 | }
40 | } else if (arg.indexOf('hybrid') > -1) {
41 | this.TARGET_MOBILE_HYBRID = true;
42 | }
43 | }
44 | let bootstrap = 'main.web';
45 | if (this.TARGET_MOBILE_HYBRID) {
46 | // Perhaps Ionic or Cordova
47 | // This is not implemented in the seed but here to show you way forward if you wanted to add
48 | bootstrap = 'main.mobile.hybrid';
49 | }
50 |
51 | if (argv['analytics']) {
52 | this.TNS_CONFIG.ANALYTICS_TRACKING_ID = argv['analytics'];
53 | }
54 |
55 | // Override seed defaults
56 | this.BOOTSTRAP_DIR = argv['app'] ? (argv['app'] + '/') : '';
57 | this.BOOTSTRAP_MODULE = `${this.BOOTSTRAP_DIR}${bootstrap}`;
58 | this.NG_FACTORY_FILE = `${bootstrap}.prod`;
59 | this.BOOTSTRAP_PROD_MODULE = `${this.BOOTSTRAP_DIR}${bootstrap}`;
60 | this.BOOTSTRAP_FACTORY_PROD_MODULE = `${this.BOOTSTRAP_DIR}${bootstrap}.prod`;
61 |
62 | this.APP_TITLE = 'Angular Seed Advanced';
63 | this.APP_BASE = ''; // paths must remain relative
64 |
65 | // Advanced seed packages
66 | let additionalPackages: ExtendPackages[] = [
67 | {
68 | name: 'lodash',
69 | path: `${this.APP_BASE}node_modules/lodash/lodash.js`,
70 | packageMeta: {
71 | main: 'index.js',
72 | defaultExtension: 'js'
73 | }
74 | }
75 | ];
76 |
77 | /**
78 | * Need to duplicate this in the project.config.ts to
79 | * pick up packages there too.
80 | */
81 | this.DESKTOP_PACKAGES = [
82 | ...this.DESKTOP_PACKAGES,
83 | ...additionalPackages,
84 | ];
85 |
86 | this.addPackagesBundles(additionalPackages);
87 |
88 | // Settings for building sass (include ./srs/client/scss in includes)
89 | // Needed because for components you cannot use ../../../ syntax
90 | this.PLUGIN_CONFIGS['gulp-sass'] = {
91 | includePaths: [
92 | './src/client/scss/',
93 | './node_modules/',
94 | './'
95 | ]
96 | };
97 |
98 | // Settings for building sass for tns modules
99 | this.PLUGIN_CONFIGS['gulp-sass-tns'] = {
100 | includePaths: [
101 | this.srcSubdir,
102 | './node_modules/',
103 | './node_modules/nativescript-theme-core/scss/'
104 | ].map((dir) => path.resolve(this.TNS_BASE_DIR, dir)),
105 | };
106 |
107 | // Fix up path to bootstrap module
108 | this.SYSTEM_CONFIG.paths[this.BOOTSTRAP_MODULE] = `${this.APP_BASE}${this.BOOTSTRAP_MODULE}`;
109 |
110 | /** Production **/
111 |
112 | delete this.SYSTEM_BUILDER_CONFIG['packageConfigPaths']; // not all libs are distributed the same
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/tools/config/seed.config.interfaces.ts:
--------------------------------------------------------------------------------
1 | export interface InjectableDependency {
2 | src: string;
3 | inject: string | boolean;
4 | vendor?: boolean;
5 | buildType?: string[] | string;
6 |
7 | // @deprecated
8 | env?: string[] | string;
9 | }
10 |
11 | export interface BuildType {
12 | DEVELOPMENT: string;
13 | PRODUCTION: string;
14 | [key: string]: string;
15 | }
16 |
17 | export interface ExtendPackages {
18 | name: string;
19 | path?: string;
20 | packageMeta?: any;
21 | }
22 |
--------------------------------------------------------------------------------
/tools/config/seed.tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "initialize": [
3 | "noop"
4 | ],
5 |
6 | "build.dev": [
7 | "initialize",
8 | "clean.once",
9 | "build.assets.dev",
10 | "build.html_css",
11 | "build.js.dev",
12 | "build.index.dev"
13 | ],
14 |
15 | "build.dev.watch": [
16 | "build.dev",
17 | "watch.dev"
18 | ],
19 |
20 | "build.e2e": [
21 | "initialize",
22 | "clean.e2e",
23 | "tslint",
24 | "build.js.e2e"
25 | ],
26 |
27 | "build.prod": [
28 | "initialize",
29 | "check.tools",
30 | "clean.prod",
31 | "tslint",
32 | "build.assets.prod",
33 | "build.html_css",
34 | "copy.prod",
35 | "build.js.prod",
36 | "build.bundles",
37 | "build.bundles.app",
38 | "minify.bundles",
39 | "build.index.prod"
40 | ],
41 |
42 | "build.prod.aot": [
43 | "initialize",
44 | "check.tools",
45 | "clean.prod",
46 | "tslint",
47 | "build.assets.prod",
48 | "build.html_css",
49 | "copy.prod",
50 | "compile.ahead.prod",
51 | "build.js.prod.aot",
52 | "build.bundles",
53 | "build.bundles.app.aot",
54 | "minify.bundles",
55 | "build.index.prod"
56 | ],
57 |
58 | "build.prod.rollup.aot": [
59 | "initialize",
60 | "check.tools",
61 | "clean.prod",
62 | "tslint",
63 | "build.assets.prod",
64 | "build.html_css",
65 | "copy.prod.rollup.aot",
66 | "compile.ahead.prod",
67 | "build.js.prod.rollup.aot",
68 | "build.bundles",
69 | "build.bundles.app.rollup.aot",
70 | "transpile.bundles.rollup.aot",
71 | "minify.bundles",
72 | "build.index.prod"
73 | ],
74 |
75 | "build.tns": [
76 | "build.assets.tns",
77 | "build.tns_html_css",
78 | "build.js.tns"
79 | ],
80 |
81 | "build.prod.tns": [
82 | "clean.tns",
83 | "tslint.tns",
84 | "build.tns"
85 | ],
86 |
87 | "build.tns.watch": [
88 | "build.tns",
89 | "watch.tns"
90 | ],
91 |
92 | "build.test": [
93 | "initialize",
94 | "clean.dev",
95 | "build.assets.dev",
96 | "build.html_css",
97 | "build.js.dev",
98 | "build.js.test",
99 | "build.index.dev"
100 | ],
101 |
102 | "test.watch": [
103 | "build.test",
104 | "watch.test",
105 | "karma.watch"
106 | ],
107 |
108 | "docs": [
109 | "build.docs",
110 | "serve.docs"
111 | ],
112 |
113 | "serve.dev": [
114 | "build.dev",
115 | "server.start",
116 | "watch.dev"
117 | ],
118 |
119 | "serve.e2e": [
120 | "tslint",
121 | "build.dev",
122 | "build.js.e2e",
123 | "server.start",
124 | "watch.dev",
125 | "watch.e2e"
126 | ],
127 |
128 | "serve.prod": [
129 | "build.prod",
130 | "server.prod"
131 | ],
132 |
133 | "serve.prod.aot": [
134 | "build.prod.aot",
135 | "server.prod"
136 | ],
137 |
138 | "serve.prod.rollup.aot": [
139 | "build.prod.rollup.aot",
140 | "server.prod"
141 | ],
142 |
143 | "test": [
144 | "build.test",
145 | "karma.run"
146 | ],
147 |
148 | "desktop": [
149 | "build.dev",
150 | "desktop.libs",
151 | "desktop.build"
152 | ],
153 |
154 | "desktop.mac": [
155 | "desktop",
156 | "desktop.package.mac"
157 | ],
158 |
159 | "desktop.windows": [
160 | "desktop",
161 | "desktop.package.windows"
162 | ],
163 |
164 | "desktop.linux": [
165 | "desktop",
166 | "desktop.package.linux"
167 | ]
168 | }
169 |
--------------------------------------------------------------------------------
/tools/config/seed.tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "../../node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "class-name": true,
7 | "curly": false,
8 | "eofline": true,
9 | "indent": [true, "spaces"],
10 | "max-line-length": [true, 600],
11 | "member-ordering": [true,
12 | "public-before-private",
13 | "static-before-instance",
14 | "variables-before-functions"
15 | ],
16 | "no-arg": true,
17 | "no-construct": true,
18 | "no-duplicate-variable": true,
19 | "no-empty": true,
20 | "no-eval": true,
21 | "no-trailing-whitespace": false,
22 | "no-unused-expression": true,
23 | "no-use-before-declare": true,
24 | "one-line": [
25 | true,
26 | "check-open-brace",
27 | "check-catch",
28 | "check-else",
29 | "check-whitespace"
30 | ],
31 | "quotemark": [
32 | true,
33 | "single"
34 | ],
35 | "semicolon": [
36 | true,
37 | "always"
38 | ],
39 | "trailing-comma": true,
40 | "triple-equals": true,
41 | "variable-name": false,
42 | "directive-selector": [true, "attribute", [], "camelCase"],
43 | "component-selector": [true, "element", [], "kebab-case"],
44 | "use-input-property-decorator": true,
45 | "use-output-property-decorator": true,
46 | "use-host-property-decorator": true
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tools/debug.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { argv } from 'yargs';
3 |
4 | require('../gulpfile');
5 |
6 | const TASK = argv['task'];
7 |
8 | if (!TASK) {
9 | throw new Error('You must specify a task name.');
10 | }
11 |
12 | console.log('**********************');
13 | console.log('* angular-seed tools ');
14 | console.log('* debugging task:', TASK);
15 | console.log('**********************');
16 |
17 | gulp.start(TASK);
18 |
--------------------------------------------------------------------------------
/tools/env/base.ts:
--------------------------------------------------------------------------------
1 | import { EnvConfig } from './env-config.interface';
2 |
3 | const BaseConfig: EnvConfig = {
4 | // Sample API url
5 | API: 'https://demo.com'
6 | };
7 |
8 | export = BaseConfig;
9 |
10 |
--------------------------------------------------------------------------------
/tools/env/dev.ts:
--------------------------------------------------------------------------------
1 | import { EnvConfig } from './env-config.interface';
2 |
3 | const DevConfig: EnvConfig = {
4 | ENV: 'DEV'
5 | };
6 |
7 | export = DevConfig;
8 |
9 |
--------------------------------------------------------------------------------
/tools/env/env-config.interface.ts:
--------------------------------------------------------------------------------
1 | export { EnvConfig } from '../../src/client/app/shared/core/utils/config';
2 |
--------------------------------------------------------------------------------
/tools/env/prod.ts:
--------------------------------------------------------------------------------
1 | import { EnvConfig } from './env-config.interface';
2 |
3 | const ProdConfig: EnvConfig = {
4 | ENV: 'PROD'
5 | };
6 |
7 | export = ProdConfig;
8 |
--------------------------------------------------------------------------------
/tools/manual_typings/project/sample.package.d.ts:
--------------------------------------------------------------------------------
1 | // declare module "moment/moment" {
2 | // export = moment;
3 | // }
4 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/autoprefixer.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'autoprefixer' {
2 |
3 | interface IOptions {
4 | browsers: string[];
5 | }
6 |
7 | interface IAutoprefixer {
8 | (opts?: IOptions): NodeJS.ReadWriteStream;
9 | }
10 |
11 | const autoprefixer: IAutoprefixer;
12 | export = autoprefixer;
13 | }
14 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/cssnano.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'cssnano' {
2 |
3 | interface IOptions {
4 | discardComments?: {
5 | removeAll: boolean;
6 | };
7 | discardUnused?: boolean;
8 | zindex?: boolean;
9 | reduceIdents?: boolean;
10 | }
11 |
12 | interface ICssnano {
13 | (opts?: IOptions): NodeJS.ReadWriteStream;
14 | }
15 |
16 | const cssnano: ICssnano;
17 | export = cssnano;
18 | }
19 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/express-history-api-fallback.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'express-history-api-fallback' {
2 |
3 | import { RequestHandler } from 'express';
4 |
5 | interface IOptions {
6 | maxAge?: number;
7 | root?: string;
8 | lastModified?: number;
9 | headers?: { [key: string]: string; };
10 | dotfiles?: boolean;
11 | }
12 |
13 | function fallback(index: string, options?: IOptions): RequestHandler;
14 |
15 | module fallback {}
16 |
17 | export = fallback;
18 | }
19 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/istream.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'isstream' {
2 | function istream(stream: any): boolean;
3 | interface Istream {
4 | isReadable(stream: any): boolean;
5 | isWritable(stream: any): boolean;
6 | isDuplex(stream: any): boolean;
7 | }
8 | module istream {}
9 | export = istream;
10 | }
11 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/karma.d.ts:
--------------------------------------------------------------------------------
1 | // Use this minimalistic definition file as bluebird dependency
2 | // generate a lot of errors.
3 |
4 | declare module 'karma' {
5 | var karma: IKarma;
6 | export = karma;
7 | interface IKarma {
8 | server: {
9 | start(options: any, callback: Function): void
10 | };
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/merge-stream.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'merge-stream' {
2 | function mergeStream(...streams: NodeJS.ReadWriteStream[]): MergeStream;
3 | interface MergeStream extends NodeJS.ReadWriteStream {
4 | add(stream: NodeJS.ReadWriteStream): MergeStream;
5 | }
6 | module mergeStream {}
7 | export = mergeStream;
8 | }
9 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/open.d.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/borisyankov/DefinitelyTyped/tree/master/open
2 | // Does not support ES2015 import (import * as open from 'open').
3 |
4 | declare module 'open' {
5 | function open(target: string, app?: string): void;
6 | module open {}
7 | export = open;
8 | }
9 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/operators.d.ts:
--------------------------------------------------------------------------------
1 | import '../../../src/client/app/operators';
2 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/slash.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'slash' {
2 | function slash(path: string): string;
3 | module slash {}
4 | export = slash;
5 | }
6 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/systemjs-builder.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'systemjs-builder' {
2 | class Builder {
3 | constructor(configObject?: any, baseUrl?: string, configPath?: string);
4 | bundle(source: string, target: string, options?: any): Promise;
5 | buildStatic(source: string, target: string, options?: any): Promise;
6 | }
7 |
8 | module Builder {}
9 | export = Builder;
10 | }
11 |
--------------------------------------------------------------------------------
/tools/manual_typings/seed/tildify.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'tildify' {
2 | function tildify(path: string): string;
3 | module tildify {}
4 | export = tildify;
5 | }
6 |
--------------------------------------------------------------------------------
/tools/tasks/assets_task.ts:
--------------------------------------------------------------------------------
1 | import { Task } from './task';
2 |
3 | export abstract class AssetsTask extends Task {
4 | shallRun(files: String[]) {
5 | return files.reduce((a, f) => {
6 | return a || (!f.endsWith('.css') && !f.endsWith('.sass') &&
7 | !f.endsWith('.scss') && !f.endsWith('.ts'));
8 | }, false);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tools/tasks/css_task.ts:
--------------------------------------------------------------------------------
1 | import { Task } from './task';
2 | import Config from '../config';
3 |
4 | export abstract class CssTask extends Task {
5 |
6 | shallRun(files: String[]) {
7 | return Config.ENABLE_SCSS || files.some(f =>
8 | f.endsWith('.css') || f.endsWith('.sass') || f.endsWith('.scss'));
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/tools/tasks/project/desktop.build.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { join } from 'path';
3 | var newer = require('gulp-newer');
4 |
5 | import Config from '../../config';
6 |
7 | export = () => {
8 | let src = [
9 | join(Config.APP_SRC, 'package.json')
10 | ];
11 | return gulp.src(src)
12 | .pipe(newer({
13 | dest: Config.APP_DEST,
14 | map: function(path: String) { return path.replace('.ts', '.js').replace('.scss', '.css'); }
15 | }))
16 | .pipe(gulp.dest(Config.APP_DEST));
17 | };
18 |
--------------------------------------------------------------------------------
/tools/tasks/project/desktop.libs.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { ExtendPackages } from '../../config/seed.config.interfaces';
3 | import { relative, join } from 'path';
4 | import Config from '../../config';
5 | var newer = require('gulp-newer');
6 |
7 | export = () => {
8 | let src = [
9 | 'node_modules/@angular/**/*',
10 | 'node_modules/rxjs/**/*'
11 | ];
12 |
13 | let additionalPkgs: ExtendPackages[] = Config.DESKTOP_PACKAGES;
14 | additionalPkgs.forEach((pkg) => {
15 | if (typeof(pkg.name) !== 'undefined') {
16 | src.push(`node_modules/${pkg.name}/**/*`);
17 | }
18 | });
19 |
20 | src.push(...Config.NPM_DEPENDENCIES.map(x => relative(Config.PROJECT_ROOT, x.src)));
21 |
22 | return gulp.src(src, { base: 'node_modules' })
23 | .pipe(newer({
24 | dest: join(Config.APP_DEST + '/node_modules'),
25 | map: function (path: String) { return path.replace('.ts', '.js').replace('.scss', '.css'); }
26 | }))
27 | .pipe(gulp.dest(join(Config.APP_DEST + '/node_modules')));
28 | };
29 |
--------------------------------------------------------------------------------
/tools/tasks/project/desktop.package.linux.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | var symdest = require('gulp-symdest');
3 | var electron = require('gulp-atom-electron');
4 |
5 | export = () => {
6 | let src = [
7 | 'dist/dev/**/*'
8 | ];
9 | return gulp.src(src, { base: 'dist/dev' })
10 | .pipe(electron({ version: '0.37.2', platform: 'linux' }))
11 | .pipe(symdest('desktop/linux'));
12 | };
13 |
--------------------------------------------------------------------------------
/tools/tasks/project/desktop.package.mac.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | var symdest = require('gulp-symdest');
3 | var electron = require('gulp-atom-electron');
4 |
5 | export = () => {
6 | let src = [
7 | 'dist/dev/**/*'
8 | ];
9 | return gulp.src(src, { base: 'dist/dev' })
10 | .pipe(electron({ version: '0.37.2', platform: 'darwin', darwinIcon: 'src/client/assets/logo.icns' }))
11 | .pipe(symdest('desktop/mac'));
12 | };
13 |
--------------------------------------------------------------------------------
/tools/tasks/project/desktop.package.windows.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | var symdest = require('gulp-symdest');
3 | var electron = require('gulp-atom-electron');
4 |
5 | export = () => {
6 | let src = [
7 | 'dist/dev/**/*'
8 | ];
9 | return gulp.src(src, { base: 'dist/dev' })
10 | .pipe(electron({ version: '0.37.2', platform: 'win32', winIcon: 'src/client/assets/logo.ico' }))
11 | .pipe(symdest('desktop/windows'));
12 | };
13 |
--------------------------------------------------------------------------------
/tools/tasks/project/desktop.watch.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as runSequence from 'run-sequence';
3 |
4 | const electron = require('electron-connect').server.create({ 'path': 'dist/dev' });
5 |
6 | export = () => {
7 | electron.start();
8 | gulp.watch(['./src/**/*'], reload);
9 | };
10 |
11 | function reload() {
12 | runSequence('desktop', electron.reload);
13 | }
14 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.assets.dev.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { join } from 'path';
3 |
4 | import { AssetsTask } from '../assets_task';
5 | import Config from '../../config';
6 |
7 | /**
8 | * Executes the build process, copying the assets located in `src/client` over to the appropriate
9 | * `dist/dev` directory.
10 | */
11 | export =
12 | class BuildAssetsTask extends AssetsTask {
13 | run(done: any) {
14 | let paths: string[] = [
15 | join(Config.APP_SRC, '**'),
16 | '!' + join(Config.APP_SRC, '**', '*.ts'),
17 | '!' + join(Config.APP_SRC, '**', '*.scss'),
18 | '!' + join(Config.APP_SRC, '**', '*.sass')
19 | ].concat(Config.TEMP_FILES.map((p) => { return '!' + p; }));
20 |
21 | return gulp.src(paths)
22 | .pipe(gulp.dest(Config.APP_DEST));
23 | }
24 | };
25 |
26 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.assets.prod.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { join } from 'path';
3 |
4 | import Config from '../../config';
5 |
6 | // TODO There should be more elegant to prevent empty directories from copying
7 | var onlyDirs = function (es: any) {
8 | return es.map(function (file: any, cb: any) {
9 | if (file.stat.isFile()) {
10 | return cb(null, file);
11 | } else {
12 | return cb();
13 | }
14 | });
15 | };
16 |
17 | /**
18 | * Executes the build process, copying the assets located in `src/client` over to the appropriate
19 | * `dist/prod` directory.
20 | */
21 | export = () => {
22 | let es: any = require('event-stream');
23 | return gulp.src([
24 | join(Config.APP_SRC, '**'),
25 | '!' + join(Config.APP_SRC, 'tsconfig.json'),
26 | '!' + join(Config.APP_SRC, '**', '*.ts'),
27 | '!' + join(Config.APP_SRC, '**', '*.css'),
28 | '!' + join(Config.APP_SRC, '**', '*.html'),
29 | '!' + join(Config.APP_SRC, '**', '*.scss'),
30 | '!' + join(Config.APP_SRC, '**', '*.sass'),
31 | '!' + join(Config.ASSETS_SRC, '**', '*.js')
32 | ].concat(Config.TEMP_FILES.map((p) => { return '!' + p; })))
33 | .pipe(onlyDirs(es))
34 | .pipe(gulp.dest(Config.APP_DEST));
35 | };
36 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.assets.tns.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as merge from 'merge-stream';
3 | import { join } from 'path';
4 | import * as newer from 'gulp-newer';
5 |
6 | import { AssetsTask } from '../assets_task';
7 | import Config from '../../config';
8 |
9 | function copyFiles(paths: string[], subdir: string) {
10 | const dest = join(Config.TNS_APP_DEST, subdir);
11 |
12 | return gulp.src(paths)
13 | .pipe(newer(dest))
14 | .pipe(gulp.dest(dest));
15 | }
16 |
17 | function copyAssets() {
18 | const paths: string[] = [
19 | join(Config.APP_SRC, 'assets', '**'),
20 | '!' + join(Config.APP_SRC, 'assets', 'icons', '**', '*'),
21 | ].concat(Config.TEMP_FILES.map((p) => { return '!' + p; }));
22 |
23 | return copyFiles(paths, 'assets');
24 | }
25 |
26 | function copyAppResources() {
27 | const paths: string[] = [
28 | join(Config.TNS_APP_SRC, 'App_Resources', '**'),
29 | ];
30 |
31 | return copyFiles(paths, 'App_Resources');
32 | }
33 |
34 | function copyAppFonts() {
35 | const paths: string[] = [
36 | join(Config.TNS_APP_SRC, 'fonts', '**', '*.otf'),
37 | join(Config.TNS_APP_SRC, 'fonts', '**', '*.ttf'),
38 | ];
39 |
40 | return copyFiles(paths, 'fonts');
41 | }
42 |
43 | export =
44 | class BuildTNSAssetsTask extends AssetsTask {
45 | run() {
46 | return merge(
47 | copyAssets(),
48 | copyAppResources(),
49 | copyAppFonts(),
50 | copyFiles([join(Config.TNS_APP_SRC, 'package.json')], ''),
51 | );
52 | }
53 | };
54 |
55 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.bundle.rxjs.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Temporary fix. See https://github.com/angular/angular/issues/9359
3 | */
4 |
5 | const Builder = require('systemjs-builder');
6 |
7 | export = (done: any) => {
8 | const options = {
9 | normalize: true,
10 | runtime: false,
11 | sourceMaps: true,
12 | sourceMapContents: true,
13 | minify: true,
14 | mangle: false
15 | };
16 | var builder = new Builder('./');
17 | builder.config({
18 | paths: {
19 | 'n:*': 'node_modules/*',
20 | 'rxjs/*': 'node_modules/rxjs/*.js',
21 | },
22 | map: {
23 | 'rxjs': 'n:rxjs',
24 | },
25 | packages: {
26 | 'rxjs': {main: 'Rx.js', defaultExtension: 'js'},
27 | }
28 | });
29 | builder.bundle('rxjs', 'node_modules/.tmp/Rx.min.js', options)
30 | .then(() => done())
31 | .catch((error:any) => done(error));
32 | };
33 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.bundles.app.aot.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import * as Builder from 'systemjs-builder';
3 |
4 | import Config from '../../config';
5 |
6 | const BUNDLER_OPTIONS = {
7 | format: 'cjs',
8 | minify: true,
9 | mangle: false
10 | };
11 |
12 | /**
13 | * Executes the build process, bundling the JavaScript files using the SystemJS builder.
14 | */
15 | export = (done: any) => {
16 | let builder = new Builder(Config.SYSTEM_BUILDER_CONFIG);
17 | builder
18 | .buildStatic(join(Config.TMP_DIR, Config.BOOTSTRAP_FACTORY_PROD_MODULE),
19 | join(Config.JS_DEST, Config.JS_PROD_APP_BUNDLE),
20 | BUNDLER_OPTIONS)
21 | .then(() => done())
22 | .catch((err: any) => done(err));
23 | };
24 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.bundles.app.rollup.aot.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { writeFile } from 'fs';
3 | import { join } from 'path';
4 |
5 | const nodeResolve = require('rollup-plugin-node-resolve');
6 | const commonjs = require('rollup-plugin-commonjs');
7 | const includePaths = require('rollup-plugin-includepaths');
8 | const rollup = require('rollup');
9 |
10 | const config = {
11 | entry: join(Config.TMP_DIR, Config.BOOTSTRAP_FACTORY_PROD_MODULE),
12 | sourceMap: true,
13 | treeshake: true,
14 | moduleName: 'main',
15 | plugins: [
16 | includePaths({
17 | include: {},
18 | paths: [join(Config.TMP_DIR, 'app')],
19 | external: [],
20 | extensions: ['.js', '.json', '.html', '.ts']
21 | }),
22 | nodeResolve({
23 | jsnext: true, main: true, module: true
24 | }),
25 | commonjs({
26 | include: 'node_modules/**',
27 | namedExports: {
28 | // 'node_modules/immutable/dist/immutable.js': [ 'Map', 'Set', 'List', 'fromJS' ],
29 | // 'node_modules/ng2-dragula/ng2-dragula.js': [ 'DragulaModule', 'DragulaService' ]
30 | }
31 | })
32 | ]
33 | };
34 |
35 |
36 | export = (done: any) => {
37 | rollup.rollup(config)
38 | .then((bundle: any) => {
39 | const result = bundle.generate({
40 | format: 'iife'
41 | });
42 | const path = join(Config.TMP_DIR, 'bundle.js');
43 | writeFile(path, result.code, (error: any) => {
44 | if (error) {
45 | console.error(error);
46 | process.exit(0);
47 | }
48 | done();
49 | });
50 | })
51 | .catch((error: any) => {
52 | console.error(error);
53 | process.exit(0);
54 | });
55 | };
56 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.bundles.app.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import * as Builder from 'systemjs-builder';
3 |
4 | import Config from '../../config';
5 |
6 | const BUNDLER_OPTIONS = {
7 | format: 'cjs',
8 | minify: true,
9 | mangle: false
10 | };
11 |
12 | /**
13 | * Executes the build process, bundling the JavaScript files using the SystemJS builder.
14 | */
15 | export = (done: any) => {
16 | let builder = new Builder(Config.SYSTEM_BUILDER_CONFIG);
17 | builder
18 | .buildStatic(join(Config.TMP_DIR, Config.BOOTSTRAP_PROD_MODULE),
19 | join(Config.JS_DEST, Config.JS_PROD_APP_BUNDLE),
20 | BUNDLER_OPTIONS)
21 | .then(() => done())
22 | .catch((err: any) => done(err));
23 | };
24 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.bundles.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import * as merge from 'merge-stream';
4 |
5 | import Config from '../../config';
6 |
7 | const plugins = gulpLoadPlugins();
8 |
9 | /**
10 | * Executes the build process, bundling the shim files.
11 | */
12 | export = () => merge(bundleShims());
13 |
14 | /**
15 | * Returns the shim files to be injected.
16 | */
17 | function getShims() {
18 | let libs = Config.DEPENDENCIES
19 | .filter(d => /\.js$/.test(d.src));
20 |
21 | return libs.filter(l => l.inject === 'shims')
22 | .concat(libs.filter(l => l.inject === 'libs'))
23 | .concat(libs.filter(l => l.inject === true))
24 | .map(l => l.src);
25 | }
26 |
27 | /**
28 | * Bundles the shim files.
29 | */
30 | function bundleShims() {
31 | return gulp.src(getShims())
32 | .pipe(plugins.concat(Config.JS_PROD_SHIMS_BUNDLE))
33 | // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks.
34 | .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;'))
35 | .pipe(gulp.dest(Config.JS_DEST));
36 | }
37 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.docs.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 |
7 | const plugins = gulpLoadPlugins();
8 |
9 | /**
10 | * Executes the build process, building the documentation for the TypeScript
11 | * files (excluding spec and e2e-spec files) using `typedoc`.
12 | */
13 | export = () => {
14 |
15 | let src = [
16 | 'typings/index.d.ts',
17 | join(Config.APP_SRC, '**/*.ts'),
18 | '!' + join(Config.APP_SRC, '**/*.spec.ts'),
19 | '!' + join(Config.APP_SRC, '**/*.e2e-spec.ts')
20 | ];
21 |
22 | return gulp.src(src)
23 | .pipe(plugins.typedoc({
24 | // TypeScript options (see typescript docs)
25 | module: 'commonjs',
26 | target: 'es5',
27 | excludeExternals: true,
28 | includeDeclarations: true,
29 | // Output options (see typedoc docs)
30 | out: Config.DOCS_DEST,
31 | json: join(Config.DOCS_DEST, 'data/docs.json'),
32 | name: Config.APP_TITLE,
33 | ignoreCompilerErrors: false,
34 | experimentalDecorators: true,
35 | version: true
36 | }));
37 | };
38 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.index.dev.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 | import * as slash from 'slash';
5 |
6 | import Config from '../../config';
7 | import { TemplateLocalsBuilder } from '../../utils';
8 |
9 | const plugins = gulpLoadPlugins();
10 |
11 |
12 | /**
13 | * Executes the build process, injecting the shims and libs into the `index.hml` for the development environment.
14 | */
15 | export = () => {
16 | return gulp.src(join(Config.APP_SRC, 'index.html'))
17 | .pipe(inject('shims'))
18 | .pipe(inject('libs'))
19 | .pipe(inject())
20 | .pipe(plugins.template(new TemplateLocalsBuilder().wihtoutStringifiedEnvConfig().build()))
21 | .pipe(gulp.dest(Config.APP_DEST));
22 | };
23 |
24 | /**
25 | * Injects the file with the given name.
26 | * @param {string} name - The file to be injected.
27 | */
28 | function inject(name?: string) {
29 | return plugins.inject(gulp.src(getInjectablesDependenciesRef(name), { read: false }), {
30 | name,
31 | transform: transformPath()
32 | });
33 | }
34 |
35 | /**
36 | * Returns the injectable dependency, mapping its filename to its path.
37 | * @param {string} name - The dependency to be mapped.
38 | */
39 | function getInjectablesDependenciesRef(name?: string) {
40 | return Config.DEPENDENCIES
41 | .filter(dep => dep['inject'] && dep['inject'] === (name || true))
42 | .map(mapPath);
43 | }
44 |
45 | /**
46 | * Maps the path of the given dependency to its path according to the applications environment.
47 | * @param {any} dep - The dependency to be mapped.
48 | */
49 | function mapPath(dep: any) {
50 | let envPath = dep.src;
51 | if (envPath.startsWith(Config.APP_SRC) && !envPath.endsWith('.scss')) {
52 | envPath = join(Config.APP_DEST, envPath.replace(Config.APP_SRC, ''));
53 | } else if (envPath.startsWith(Config.APP_SRC) && envPath.endsWith('.scss')) {
54 | envPath = envPath.replace(Config.ASSETS_SRC, Config.CSS_DEST).replace('.scss', '.css');
55 | }
56 | return envPath;
57 | }
58 |
59 | /**
60 | * Transform the path of a dependency to its location within the `dist` directory according to the applications
61 | * environment.
62 | */
63 | function transformPath() {
64 | return function (filepath: string) {
65 | if (filepath.startsWith(`/${Config.APP_DEST}`)) {
66 | filepath = filepath.replace(`/${Config.APP_DEST}`, '');
67 | }
68 | if (Config.TARGET_DESKTOP) {
69 | let path = join(Config.APP_BASE, filepath);
70 | if (path.indexOf('dist/dev') > -1 || path.indexOf('dist\\dev') > -1) {
71 | path = path.replace(/(dist\/dev\/)|(dist\\dev\\)/g, '');
72 | }
73 | arguments[0] = path.substring(1) + `?${Date.now()}`;
74 | } else {
75 | arguments[0] = join(Config.APP_BASE, filepath) + `?${Date.now()}`;
76 | }
77 | return slash(plugins.inject.transform.apply(plugins.inject.transform, arguments));
78 | };
79 | }
80 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.index.prod.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join, sep, normalize } from 'path';
4 | import * as slash from 'slash';
5 |
6 | import Config from '../../config';
7 | import { TemplateLocalsBuilder } from '../../utils';
8 |
9 | const plugins = gulpLoadPlugins();
10 |
11 | /**
12 | * Executes the build process, injecting the JavaScript and CSS dependencies into the `index.html` for the production
13 | * environment.
14 | */
15 | export = () => {
16 | return gulp.src(join(Config.APP_SRC, 'index.html'))
17 | .pipe(injectJs())
18 | .pipe(injectCss())
19 | .pipe(plugins.template(new TemplateLocalsBuilder().wihtoutStringifiedEnvConfig().build()))
20 | .pipe(gulp.dest(Config.APP_DEST));
21 | };
22 |
23 | /**
24 | * Injects the given file array and transforms the path of the files.
25 | * @param {Array} files - The files to be injected.
26 | */
27 | function inject(...files: Array) {
28 | return plugins.inject(gulp.src(files, { read: false }), {
29 | files,
30 | transform: transformPath()
31 | });
32 | }
33 |
34 | /**
35 | * Injects the bundled JavaScript shims and application bundles for the production environment.
36 | */
37 | function injectJs() {
38 | return inject(join(Config.JS_DEST, Config.JS_PROD_SHIMS_BUNDLE), join(Config.JS_DEST, Config.JS_PROD_APP_BUNDLE));
39 | }
40 |
41 | /**
42 | * Injects the bundled CSS files for the production environment.
43 | */
44 | function injectCss() {
45 | return inject(join(Config.CSS_DEST, Config.CSS_PROD_BUNDLE));
46 | }
47 |
48 | /**
49 | * Transform the path of a dependency to its location within the `dist` directory according to the applications
50 | * environment.
51 | */
52 | function transformPath() {
53 | return function(filepath: string) {
54 | let path: Array = normalize(filepath).split(sep);
55 | let slice_after = path.indexOf(Config.APP_DEST);
56 | if (slice_after > -1) {
57 | slice_after++;
58 | } else {
59 | slice_after = 3;
60 | }
61 | arguments[0] = Config.APP_BASE + path.slice(slice_after, path.length).join(sep) + `?${Date.now()}`;
62 | return slash(plugins.inject.transform.apply(plugins.inject.transform, arguments));
63 | };
64 | }
65 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.dev.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import * as merge from 'merge-stream';
4 | import * as util from 'gulp-util';
5 | import { join/*, sep, relative*/ } from 'path';
6 |
7 | import Config from '../../config';
8 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
9 | import { TypeScriptTask } from '../typescript_task';
10 |
11 | const plugins = gulpLoadPlugins();
12 |
13 | let typedBuildCounter = Config.TYPED_COMPILE_INTERVAL; // Always start with the typed build.
14 |
15 | /**
16 | * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development
17 | * environment.
18 | */
19 | export =
20 | class BuildJsDev extends TypeScriptTask {
21 | run() {
22 | let tsProject: any;
23 | let typings = gulp.src([
24 | Config.TOOLS_DIR + '/manual_typings/**/*.d.ts'
25 | ]);
26 | let src = [
27 | join(Config.APP_SRC, '**/*.ts'),
28 | '!' + join(Config.APP_SRC, '**/*.spec.ts'),
29 | '!' + join(Config.APP_SRC, '**/*.e2e-spec.ts'),
30 | '!' + join(Config.APP_SRC, `**/${Config.NG_FACTORY_FILE}.ts`)
31 | ];
32 |
33 | let projectFiles = gulp.src(src);
34 | let result: any;
35 | let isFullCompile = true;
36 |
37 | // Only do a typed build every X builds, otherwise do a typeless build to speed things up
38 | if (typedBuildCounter < Config.TYPED_COMPILE_INTERVAL) {
39 | isFullCompile = false;
40 | tsProject = makeTsProject({ isolatedModules: true });
41 | projectFiles = projectFiles.pipe(plugins.cached());
42 | util.log('Performing typeless TypeScript compile.');
43 | } else {
44 | tsProject = makeTsProject();
45 | projectFiles = merge(typings, projectFiles);
46 | }
47 |
48 | result = projectFiles
49 | .pipe(plugins.plumber())
50 | .pipe(plugins.sourcemaps.init())
51 | .pipe(tsProject())
52 | .on('error', () => {
53 | typedBuildCounter = Config.TYPED_COMPILE_INTERVAL;
54 | });
55 |
56 | if (isFullCompile) {
57 | typedBuildCounter = 0;
58 | } else {
59 | typedBuildCounter++;
60 | }
61 |
62 | return result.js
63 | .pipe(plugins.sourcemaps.write())
64 | // Use for debugging with Webstorm/IntelliJ
65 | // https://github.com/mgechev/angular-seed/issues/1220
66 | // .pipe(plugins.sourcemaps.write('.', {
67 | // includeContent: false,
68 | // sourceRoot: (file: any) =>
69 | // relative(file.path, Config.PROJECT_ROOT + '/' + Config.APP_SRC).replace(sep, '/') + '/' + Config.APP_SRC
70 | // }))
71 | .pipe(plugins.template(new TemplateLocalsBuilder().withStringifiedSystemConfigDev().build()))
72 | .pipe(gulp.dest(Config.APP_DEST));
73 | }
74 | };
75 |
76 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.e2e.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
7 |
8 | const plugins = gulpLoadPlugins();
9 |
10 | /**
11 | * Executes the build process, transpiling the TypeScript files (including the e2e-spec files, excluding the spec files)
12 | * for the e2e environment.
13 | */
14 | export = () => {
15 | let tsProject = makeTsProject({ 'target': 'es2015' }, Config.E2E_SRC);
16 | let src = [
17 | Config.TOOLS_DIR + '/manual_typings/**/*.d.ts',
18 | join(Config.E2E_SRC, '**/*.ts')
19 | ];
20 | let result = gulp.src(src)
21 | .pipe(plugins.plumber())
22 | .pipe(plugins.sourcemaps.init())
23 | .pipe(tsProject());
24 |
25 | return result.js
26 | .pipe(plugins.sourcemaps.write())
27 | .pipe(plugins.template(new TemplateLocalsBuilder().withStringifiedSystemConfigDev().build()))
28 | .pipe(gulp.dest(Config.E2E_DEST));
29 | };
30 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.prod.aot.ts:
--------------------------------------------------------------------------------
1 | import { readdirSync, lstatSync } from 'fs';
2 | import * as gulp from 'gulp';
3 | import * as gulpLoadPlugins from 'gulp-load-plugins';
4 | import { join } from 'path';
5 |
6 | import Config from '../../config';
7 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
8 |
9 | const plugins = gulpLoadPlugins();
10 |
11 | /**
12 | * Executes the build process, transpiling the TypeScript files for the production environment.
13 | */
14 |
15 | export = () => {
16 | let tsProject = makeTsProject({}, Config.TMP_DIR);
17 | let toIgnore = readdirSync(Config.TMP_DIR).filter((f: string) =>
18 | lstatSync(join(Config.TMP_DIR, f)).isDirectory() && f !== Config.BOOTSTRAP_DIR)
19 | .map((f: string) => '!' + join(Config.TMP_DIR, f, Config.NG_FACTORY_FILE + '.ts'));
20 |
21 | let src = [
22 | Config.TOOLS_DIR + '/manual_typings/**/*.d.ts',
23 | join(Config.TMP_DIR, '**/*.ts'),
24 | join(Config.TMP_DIR, `${Config.BOOTSTRAP_FACTORY_PROD_MODULE}.ts`),
25 | ...toIgnore
26 | ];
27 | let result = gulp.src(src)
28 | .pipe(plugins.plumber())
29 | .pipe(tsProject())
30 | .once('error', function(e: any) {
31 | this.once('finish', () => process.exit(1));
32 | });
33 |
34 | return result.js
35 | .pipe(plugins.template(new TemplateLocalsBuilder().build()))
36 | .pipe(gulp.dest(Config.TMP_DIR))
37 | .on('error', (e: any) => {
38 | console.log(e);
39 | });
40 | };
41 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.prod.rollup.aot.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
7 |
8 | const plugins = gulpLoadPlugins();
9 |
10 | /**
11 | * Executes the build process, transpiling the TypeScript files for the production environment.
12 | */
13 |
14 | export = () => {
15 | const tsProject = makeTsProject({
16 | target: 'es2015',
17 | module: 'es2015',
18 | moduleResolution: 'node'
19 | }, Config.TMP_DIR);
20 | const src = [
21 | join(Config.TOOLS_DIR, '/manual_typings/**/*.d.ts'),
22 | join(Config.TMP_DIR, '**/*.ts')
23 | ];
24 | const result = gulp.src(src)
25 | .pipe(plugins.plumber())
26 | .pipe(tsProject())
27 | .once('error', () => {
28 | this.once('finish', () => process.exit(1));
29 | });
30 |
31 | return result.js
32 | .pipe(plugins.template(new TemplateLocalsBuilder().build(), {interpolate: /<%=([\s\S]+?)%>/g}))
33 | .pipe(gulp.dest(Config.TMP_DIR))
34 | .on('error', (e: any) => {
35 | console.log(e);
36 | });
37 | };
38 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.prod.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
7 |
8 | const plugins = gulpLoadPlugins();
9 |
10 | const INLINE_OPTIONS = {
11 | base: Config.TMP_DIR,
12 | target: 'es5',
13 | useRelativePaths: true,
14 | removeLineBreaks: true
15 | };
16 |
17 | /**
18 | * Executes the build process, transpiling the TypeScript files for the production environment.
19 | */
20 |
21 | export = () => {
22 | let tsProject = makeTsProject({}, Config.TMP_DIR);
23 | let src = [
24 | Config.TOOLS_DIR + '/manual_typings/**/*.d.ts',
25 | join(Config.TMP_DIR, '**/*.ts'),
26 | '!' + join(Config.TMP_DIR, `**/${Config.NG_FACTORY_FILE}.ts`)
27 | ];
28 | let result = gulp.src(src)
29 | .pipe(plugins.plumber())
30 | .pipe(plugins.inlineNg2Template(INLINE_OPTIONS))
31 | .pipe(tsProject())
32 | .once('error', function(e: any) {
33 | this.once('finish', () => process.exit(1));
34 | });
35 |
36 |
37 | return result.js
38 | .pipe(plugins.template(new TemplateLocalsBuilder().build()))
39 | .pipe(gulp.dest(Config.TMP_DIR))
40 | .on('error', (e: any) => {
41 | console.log(e);
42 | });
43 | };
44 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.test.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata';
2 | import * as gulp from 'gulp';
3 | import * as gulpLoadPlugins from 'gulp-load-plugins';
4 | import * as merge from 'merge-stream';
5 | import * as util from 'gulp-util';
6 | import { join } from 'path';
7 |
8 | import Config from '../../config';
9 | import { makeTsProject } from '../../utils';
10 | import { TypeScriptTask } from '../typescript_task';
11 |
12 | const plugins = gulpLoadPlugins();
13 |
14 | let typedBuildCounter = Config.TYPED_COMPILE_INTERVAL; // Always start with the typed build.
15 |
16 | /**
17 | * Executes the build process, transpiling the TypeScript files (excluding the spec and e2e-spec files) for the test
18 | * environment.
19 | */
20 | export =
21 | class BuildJsTest extends TypeScriptTask {
22 | run() {
23 | let tsProject: any;
24 | let typings = gulp.src( [
25 | Config.TOOLS_DIR + '/manual_typings/**/*.d.ts'
26 | ] );
27 | let src = [
28 | join(Config.APP_SRC, '**/*.spec.ts')
29 | ];
30 |
31 | let projectFiles = gulp.src(src);
32 | let result: any;
33 | let isFullCompile = true;
34 |
35 | // Only do a typed build every X builds, otherwise do a typeless build to speed things up
36 | if (typedBuildCounter < Config.TYPED_COMPILE_INTERVAL) {
37 | isFullCompile = false;
38 | tsProject = makeTsProject({isolatedModules: true});
39 | projectFiles = projectFiles.pipe(plugins.cached());
40 | util.log('Performing typeless TypeScript compile of specs.');
41 | } else {
42 | tsProject = makeTsProject();
43 | projectFiles = merge(typings, projectFiles);
44 | }
45 |
46 | //noinspection TypeScriptUnresolvedFunction
47 | result = projectFiles
48 | .pipe(plugins.plumber())
49 | .pipe(plugins.sourcemaps.init())
50 | .pipe(tsProject())
51 | .on('error', () => {
52 | typedBuildCounter = Config.TYPED_COMPILE_INTERVAL;
53 | });
54 |
55 | if (isFullCompile) {
56 | typedBuildCounter = 0;
57 | } else {
58 | typedBuildCounter++;
59 | }
60 |
61 | return result.js
62 | .pipe(plugins.sourcemaps.write())
63 | // Use for debugging with Webstorm/IntelliJ
64 | // https://github.com/mgechev/angular-seed/issues/1220
65 | // .pipe(plugins.sourcemaps.write('.', {
66 | // includeContent: false,
67 | // sourceRoot: (file: any) =>
68 | // relative(file.path, PROJECT_ROOT + '/' + APP_SRC).replace(sep, '/') + '/' + APP_SRC
69 | // }))
70 | .pipe(gulp.dest(Config.APP_DEST));
71 | }
72 | };
73 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.js.tns.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import * as merge from 'merge-stream';
4 | import * as fs from 'fs';
5 | import * as path from 'path';
6 |
7 | import Config from '../../config';
8 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
9 | import { TypeScriptTask } from '../typescript_task';
10 |
11 | const plugins = gulpLoadPlugins();
12 |
13 | const jsonSystemConfig = JSON.stringify(Config.TNS_CONFIG);
14 |
15 | /**
16 | * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development
17 | * environment.
18 | */
19 | export =
20 | class BuildJsDev extends TypeScriptTask {
21 | run() {
22 | const src = [
23 | '**/*.ts',
24 | 'app/**/*.ts',
25 | '!**/*.spec.ts',
26 | '!app/**/*.spec.ts',
27 | '!**/*.e2e-spec.ts',
28 | '!app/**/*.e2e-spec.ts',
29 | '!app/shared/test/**/*',
30 | `!**/${Config.NG_FACTORY_FILE}.ts`,
31 | ];
32 |
33 | const tsProject = makeTsProject({}, Config.TNS_APP_SRC);
34 |
35 | const result = gulp.src([
36 | ...src,
37 | '!**/*.aot.ts',
38 | ], {
39 | base: Config.TNS_APP_SRC,
40 | cwd: Config.TNS_APP_SRC,
41 | })
42 | .pipe(plugins.sourcemaps.init())
43 | .pipe(tsProject());
44 |
45 | const template = (Object).assign(
46 | new TemplateLocalsBuilder().withStringifiedSystemConfigDev().build(), {
47 | SYSTEM_CONFIG_TNS: jsonSystemConfig
48 | },
49 | );
50 |
51 | const transpiled = result.js
52 | .pipe(plugins.sourcemaps.write())
53 | // Use for debugging with Webstorm/IntelliJ
54 | // https://github.com/mgechev/angular-seed/issues/1220
55 | // .pipe(plugins.sourcemaps.write('.', {
56 | // includeContent: false,
57 | // sourceRoot: (file: any) =>
58 | // relative(file.path, PROJECT_ROOT + '/' + APP_SRC).replace(sep, '/') + '/' + APP_SRC
59 | // }))
60 | .pipe(plugins.template(template))
61 | .pipe(gulp.dest(Config.TNS_APP_DEST));
62 |
63 | const copy = gulp.src(src, {
64 | base: Config.TNS_APP_SRC,
65 | cwd: Config.TNS_APP_SRC,
66 | })
67 | .pipe(gulp.dest(Config.TNS_APP_DEST));
68 |
69 | fs.writeFileSync(path.join(Config.TNS_APP_DEST, 'build-config.json'), JSON.stringify(template));
70 |
71 | return merge(transpiled, copy);
72 | }
73 | };
74 |
75 |
76 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.tns_html_css.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import * as merge from 'merge-stream';
4 | import * as util from 'gulp-util';
5 | import * as rename from 'gulp-rename';
6 |
7 | import Config from '../../config';
8 | import { CssTask } from '../css_task';
9 |
10 | const plugins = gulpLoadPlugins();
11 | const reportPostCssError = (e: any) => util.log(util.colors.red(e.message));
12 |
13 | function renamer() {
14 | return rename((path: any) => {
15 | path.basename = path.basename.replace(/\.tns/, '');
16 | });
17 | }
18 |
19 | function prepareTemplates() {
20 | return gulp.src([
21 | '**/*.html',
22 | 'app/**/*.html',
23 | '!app/**/*.component.html',
24 | ], {
25 | base: Config.TNS_APP_SRC,
26 | cwd: Config.TNS_APP_SRC,
27 | })
28 | .pipe(renamer())
29 | .pipe(gulp.dest(Config.TNS_APP_DEST));
30 | }
31 |
32 | function processComponentStylesheets() {
33 | return Config.ENABLE_SCSS ?
34 | merge(
35 | processComponentScss(),
36 | processComponentCss())
37 | :
38 | processComponentCss();
39 | }
40 |
41 | function processComponentCss() {
42 | return gulp.src([
43 | '**/*.css',
44 | 'app/**/*.css',
45 | '!app/**/*.component.css',
46 | ], {
47 | base: Config.TNS_APP_SRC,
48 | cwd: Config.TNS_APP_SRC,
49 | })
50 | .pipe(renamer())
51 | .on('error', reportPostCssError)
52 | .pipe(gulp.dest(Config.TNS_APP_DEST));
53 | }
54 |
55 | /**
56 | * Process scss files referenced from Angular component `styleUrls` metadata
57 | */
58 | function processComponentScss() {
59 | const stream = gulp.src([
60 | '**/*.scss',
61 | 'app/**/*.scss',
62 | '!app/**/*.component.scss',
63 | ], {
64 | base: Config.TNS_APP_SRC,
65 | cwd: Config.TNS_APP_SRC,
66 | })
67 | .pipe(plugins.sourcemaps.init())
68 | .pipe(plugins.sass(Config.getPluginConfig('gulp-sass-tns')).on('error', plugins.sass.logError))
69 | .pipe(plugins.sourcemaps.write());
70 |
71 | return stream
72 | .pipe(renamer())
73 | .pipe(gulp.dest(Config.TNS_APP_DEST));
74 | }
75 |
76 | function handlePlatformSpecificFiles() {
77 | // Make a copy of platform specific files were ext is swapped with platform-name
78 | // This is to support both our webpack --bundle and livesync builds
79 | const platformRegexp = /(\.ios|\.android)/;
80 |
81 | return gulp.src([
82 | '**/*.ios.css',
83 | '**/*.ios.html',
84 | '**/*.ios.js',
85 |
86 | '**/*.android.css',
87 | '**/*.android.html',
88 | '**/*.android.js',
89 | ], {
90 | base: Config.TNS_APP_DEST,
91 | cwd: Config.TNS_APP_DEST,
92 | })
93 | .pipe(rename((path) => {
94 | const match = path.basename.match(platformRegexp);
95 | if (match) {
96 | const oldExt = path.extname;
97 | path.extname = match[1];
98 | path.basename = path.basename.replace(platformRegexp, oldExt);
99 | }
100 | }))
101 | .pipe(gulp.dest((Config.TNS_APP_DEST)));
102 | }
103 |
104 | export =
105 | class BuildTNSCSS extends CssTask {
106 | shallRun(files: String[]) {
107 | // Only run if tns-resources
108 | return files.some((f) =>
109 | // tns.html, tns.scss or tns.css under nativescript/src/app
110 | (f.indexOf('nativescript/src/app') !== -1 && !!f.match(/\.tns\.(s?css|html)$/)) ||
111 | // .html, .scss or .css NOT under nativescript/src/app
112 | (f.indexOf('nativescript/src/app') === -1 && !!f.match(/\.(s?css|html)$/))
113 | );
114 | }
115 |
116 | run() {
117 | return merge(processComponentStylesheets(), prepareTemplates()).on('end', () => handlePlatformSpecificFiles());
118 | }
119 | };
120 |
121 |
--------------------------------------------------------------------------------
/tools/tasks/seed/build.tools.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 | import { makeTsProject, TemplateLocalsBuilder } from '../../utils';
7 |
8 | const plugins = gulpLoadPlugins();
9 |
10 | /**
11 | * Executes the build process, transpiling the TypeScript files within the `tools` directory.
12 | */
13 | export = () => {
14 |
15 | let tsProject = makeTsProject();
16 |
17 | let src = [
18 | join(Config.PROJECT_ROOT, 'gulpfile.ts'),
19 | join(Config.TOOLS_DIR, 'manual_typings/**/*.d.ts'),
20 | join(Config.TOOLS_DIR, '**/*.ts')
21 | ];
22 | let result = gulp.src(src, { base: './' })
23 | .pipe(plugins.plumber())
24 | .pipe(plugins.sourcemaps.init())
25 | .pipe(tsProject());
26 |
27 | return result.js
28 | .pipe(plugins.template(new TemplateLocalsBuilder().build()))
29 | .pipe(plugins.sourcemaps.write())
30 | .pipe(gulp.dest('./'));
31 | };
32 |
--------------------------------------------------------------------------------
/tools/tasks/seed/check.tools.ts:
--------------------------------------------------------------------------------
1 | import * as util from 'gulp-util';
2 | import { join } from 'path';
3 |
4 | let fs = require('fs');
5 |
6 |
7 | // if gulpfile.ts has been compiled then we need to rebuild the toolchain
8 |
9 | export = (done: any) => {
10 |
11 | let checkFile = join(process.cwd(), 'tools', 'config.js');
12 |
13 | // need to require the build.toolchain task as it won't be able to run after we run clear.files
14 | let buildTools = require('./build.tools');
15 | let cleanTools = require('./clean.tools');
16 |
17 | let rebuild = false;
18 |
19 | try {
20 | fs.accessSync(checkFile, fs.F_OK);
21 | util.log('Gulpfile has previously been compiled, rebuilding toolchain');
22 | rebuild = true;
23 |
24 | } catch (e) {
25 | util.log('Tools not compiled, skipping rebuild');
26 | done();
27 | }
28 |
29 | // continue here to prevent other errors being caught...
30 | if (rebuild) {
31 | util.log('Running \'clean.tools\' from check.tools');
32 | cleanTools();
33 |
34 | util.log('Running \'build.tools\' from check.tools');
35 | let build = buildTools();
36 |
37 | build.on('end', done);
38 |
39 | }
40 |
41 | };
42 |
--------------------------------------------------------------------------------
/tools/tasks/seed/check.versions.ts:
--------------------------------------------------------------------------------
1 | import * as util from 'gulp-util';
2 | import Config from '../../config';
3 |
4 | function reportError(message: string) {
5 | console.error(util.colors.white.bgRed.bold(message));
6 | process.exit(1);
7 | }
8 |
9 | /**
10 | * Executes the build process, verifying that the installed NodeJS and NPM version matches the required versions as
11 | * defined in the application configuration.
12 | */
13 | export = () => {
14 | let exec = require('child_process').exec;
15 | let semver = require('semver');
16 |
17 | exec('npm --version',
18 | function(error: Error, stdout: NodeBuffer, stderr: NodeBuffer) {
19 | if (error !== null) {
20 | reportError('npm preinstall error: ' + error + stderr);
21 | }
22 |
23 | if (!semver.gte(stdout, Config.VERSION_NPM)) {
24 | reportError('NPM is not in required version! Required is ' + Config.VERSION_NPM + ' and you\'re using ' + stdout);
25 | }
26 | });
27 |
28 | exec('node --version',
29 | function(error: Error, stdout: NodeBuffer, stderr: NodeBuffer) {
30 | if (error !== null) {
31 | reportError('npm preinstall error: ' + error + stderr);
32 | }
33 |
34 | if (!semver.gte(stdout, Config.VERSION_NODE)) {
35 | reportError('NODE is not in required version! Required is ' + Config.VERSION_NODE + ' and you\'re using ' + stdout);
36 | }
37 | });
38 | };
39 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.all.src.js.ts:
--------------------------------------------------------------------------------
1 | import * as chalk from 'chalk';
2 | import { lstatSync, readdirSync } from 'fs';
3 | import * as util from 'gulp-util';
4 | import * as rimraf from 'rimraf';
5 | import { join } from 'path';
6 |
7 | import Config from '../../config';
8 |
9 | /**
10 | * Executes the build process, deleting all JavaScript and Source Map files (which were transpiled from the TypeScript sources) with in
11 | * the `src/client` directory.
12 | */
13 | export = (done: any) => {
14 | deleteAndWalk(Config.APP_SRC);
15 | done();
16 | };
17 |
18 | /**
19 | * Recursively walks along the given path and deletes all JavaScript files.
20 | * @param {any} path - The path to walk and clean.
21 | */
22 | function walk(path: any) {
23 | let files = readdirSync(path);
24 | for (let i = 0; i < files.length; i += 1) {
25 | let curPath = join(path, files[i]);
26 | if (lstatSync(curPath).isDirectory()) { // recurse
27 | deleteAndWalk(curPath);
28 | }
29 | }
30 | }
31 |
32 | /**
33 | * Deletes the JavaScript file with the given path.
34 | * @param {any} path - The path of the JavaScript file to be deleted.
35 | */
36 | function deleteAndWalk(path: any) {
37 | try {
38 | rimraf.sync(join(path, '*.js'));
39 | util.log('Deleted', chalk.yellow(`${path}/*.js`));
40 | rimraf.sync(join(path, '*.js.map'));
41 | util.log('Deleted', chalk.yellow(`${path}/*.js.map`));
42 | } catch (e) {
43 | util.log('Error while deleting', chalk.yellow(`${path}/*.js`), e);
44 | }
45 | walk(path);
46 | }
47 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.all.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { clean } from '../../utils';
3 |
4 | /**
5 | * Executes the build process, cleaning all files within the `/dist` directory.
6 | */
7 | export = clean([Config.DIST_DIR, Config.COVERAGE_DIR, Config.TNS_APP_DEST]);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.coverage.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { clean } from '../../utils';
3 |
4 | /**
5 | * Executes the build process, cleaning all files within the `/dist/dev` directory.
6 | */
7 | export = clean([Config.COVERAGE_DIR, Config.COVERAGE_TS_DIR]);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.dev.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { clean } from '../../utils';
3 |
4 | /**
5 | * Executes the build process, cleaning all files within the `/dist/dev` directory.
6 | */
7 | export = clean(Config.DEV_DEST);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.e2e.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { clean } from '../../utils';
3 |
4 | /**
5 | * Executes the build process, cleaning all files within the `/dist/dev` directory.
6 | */
7 | export = clean(Config.E2E_DEST);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.prod.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { clean } from '../../utils';
3 |
4 | /**
5 | * Executes the build process, cleaning all files within the `/dist/dev` and `dist/tmp` directory.
6 | */
7 | export = clean([Config.PROD_DEST, Config.TMP_DIR]);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.tns.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { clean } from '../../utils';
3 |
4 | /**
5 | * Executes the build process, cleaning all files within the `/dist` directory.
6 | */
7 | export = clean([Config.TNS_APP_DEST]);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clean.tools.ts:
--------------------------------------------------------------------------------
1 | import { clean } from '../../utils';
2 | import { join } from 'path';
3 |
4 | import Config from '../../config';
5 |
6 | /**
7 | * Removes all the js, js.map from the tools directories
8 | *
9 | * NB: this needs to remain syncronus, or check.tools will
10 | * need to be updated to handle the returned promise/stream
11 | *
12 | */
13 | export = clean([
14 | 'gulpfile.js',
15 | 'gulpfile.js.map',
16 | join(Config.TOOLS_DIR, '**/*.js'),
17 | join(Config.TOOLS_DIR, '**/*.js.map')
18 | ]);
19 |
20 |
--------------------------------------------------------------------------------
/tools/tasks/seed/clear.files.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import { clean } from '../../utils';
3 |
4 | import Config from '../../config';
5 |
6 | /**
7 | * Removes all the js, js.map and metadata.json from the src and tools directories
8 | */
9 | export = clean([
10 | 'gulpfile.js',
11 | 'gulpfile.js.map',
12 | join(Config.TOOLS_DIR, '**/*.js'),
13 | join(Config.TOOLS_DIR, '**/*.js.map'),
14 | join(Config.TOOLS_DIR, '**/*.metadata.json'),
15 | join(Config.APP_SRC, '**/*.js'),
16 | join(Config.APP_SRC, '**/*.js.map'),
17 | join(Config.APP_SRC, '**/*.metadata.json')
18 | ]);
19 |
20 |
--------------------------------------------------------------------------------
/tools/tasks/seed/compile.ahead.prod.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata';
2 | import * as ts from 'typescript';
3 | import { argv } from 'yargs';
4 | import { join } from 'path';
5 | import { writeFileSync, readFileSync, readdirSync } from 'fs';
6 | import { CodeGenerator, AngularCompilerOptions, NgcCliOptions, main } from '@angular/compiler-cli';
7 |
8 | import Config from '../../config';
9 |
10 | function codegen(
11 | ngOptions: AngularCompilerOptions, cliOptions: NgcCliOptions, program: ts.Program,
12 | host: ts.CompilerHost) {
13 | return CodeGenerator.create(ngOptions, cliOptions, program, host).codegen();
14 | }
15 |
16 | const modifyFile = (path: string, mod: any = (f: string) => f) => {
17 | const file = readFileSync(path);
18 | writeFileSync(path, mod(file.toString()));
19 | };
20 |
21 | export = (done: any) => {
22 | // Note: dirty hack until we're able to set config easier
23 | modifyFile(join(Config.TMP_DIR, 'tsconfig.json'), (content: string) => {
24 | const parsed = JSON.parse(content);
25 | const path = join(Config.PROJECT_ROOT, Config.TOOLS_DIR, 'manual_typings', 'project');
26 | parsed.files = parsed.files || [];
27 | parsed.files = parsed.files.concat(
28 | readdirSync(path)
29 | .filter(f => f.endsWith('d.ts'))
30 | .map(f => join(path, f)));
31 | parsed.files = parsed.files.filter((f: string, i: number) => parsed.files.indexOf(f) === i);
32 | parsed.files.push(join(Config.BOOTSTRAP_DIR, 'main.web.ts'));
33 | return JSON.stringify(parsed, null, 2);
34 | });
35 | const args = argv;
36 |
37 | // If a translation, tell the compiler
38 | if (args.lang) {
39 | args['i18nFile'] = `./src/client/assets/locale/messages.${args.lang}.xlf`;
40 | args['locale'] = args.lang;
41 | args['i18nFormat'] = 'xlf';
42 | }
43 |
44 | const cliOptions = new NgcCliOptions(args);
45 | main(Config.TMP_DIR, cliOptions, codegen)
46 | .then(done)
47 | .catch(e => {
48 | console.error(e.stack);
49 | console.error('Compilation failed');
50 | process.exit(1);
51 | });
52 | };
53 |
--------------------------------------------------------------------------------
/tools/tasks/seed/copy.prod.rollup.aot.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { join } from 'path';
3 | import Config from '../../config';
4 |
5 | const replace = require('gulp-replace');
6 |
7 | /**
8 | * Executes the build task, copying all TypeScript files over to the `dist/tmp` directory.
9 | */
10 | export = () => {
11 | return gulp.src([
12 | join(Config.APP_SRC, '**/*.ts'),
13 | join(Config.APP_SRC, '**/*.json'),
14 | '!' + join(Config.APP_SRC, '**/*.spec.ts'),
15 | '!' + join(Config.APP_SRC, '**/*.e2e-spec.ts')
16 | ])
17 | // import in dev mode: import * as moment from 'moment';
18 | // import for rollup: import moment from 'moment';
19 | // .pipe(replace('import * as moment from \'moment\';', 'import moment from \'moment\';'))
20 | // .pipe(replace('import * as uuid from \'node-uuid\';', 'import uuid from \'node-uuid\';'))
21 | .pipe(gulp.dest(Config.TMP_DIR));
22 | };
23 |
--------------------------------------------------------------------------------
/tools/tasks/seed/copy.prod.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import { join } from 'path';
3 |
4 | import Config from '../../config';
5 |
6 | /**
7 | * Executes the build task, copying all TypeScript files over to the `dist/tmp` directory.
8 | */
9 | export = () => {
10 | return gulp.src([
11 | join(Config.APP_SRC, '**/*.ts'),
12 | join(Config.APP_SRC, '**/*.json'),
13 | '!' + join(Config.APP_SRC, '**/*.spec.ts'),
14 | '!' + join(Config.APP_SRC, '**/*.e2e-spec.ts')
15 | ])
16 | .pipe(gulp.dest(Config.TMP_DIR));
17 | };
18 |
--------------------------------------------------------------------------------
/tools/tasks/seed/e2e.ts:
--------------------------------------------------------------------------------
1 | import * as express from 'express';
2 | import * as history from 'express-history-api-fallback';
3 | import * as gulp from 'gulp';
4 | import { resolve, join } from 'path';
5 | import { protractor } from 'gulp-protractor';
6 | import Config from '../../config';
7 |
8 | class Protractor {
9 | server(port: number, dir: string) {
10 | let app = express();
11 | let root = resolve(process.cwd(), dir);
12 | for (let proxy of Config.getProxyMiddleware()) {
13 | app.use(proxy);
14 | }
15 | app.use(express.static(root));
16 | app.use(history('index.html', { root }));
17 | return new Promise((resolve, reject) => {
18 | let server = app.listen(port, () => {
19 | resolve(server);
20 | });
21 | });
22 | }
23 | }
24 |
25 | /**
26 | * Executes the build process, running all e2e specs using `protractor`.
27 | */
28 | export = (done: any) => {
29 | process.env.LANG = 'en_US.UTF-8';
30 | new Protractor()
31 | .server(Config.PORT, Config.PROD_DEST)
32 | .then((server: any) => {
33 | gulp
34 | .src(join(Config.DEV_DEST, '**/*.e2e-spec.js'))
35 | .pipe(protractor({ configFile: 'protractor.conf.js' }))
36 | .on('error', (error: string) => { throw error; })
37 | .on('end', () => { server.close(done); });
38 | });
39 | };
40 |
--------------------------------------------------------------------------------
/tools/tasks/seed/generate.manifest.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 |
3 | import Config from '../../config';
4 |
5 | /**
6 | * Executes the build process, generating the manifest file using `angular2-service-worker`.
7 | */
8 | export = () => {
9 | return require('angular2-service-worker')
10 | .gulpGenManifest({
11 | group: [{
12 | name: 'css',
13 | sources: gulp.src(`${Config.APP_DEST}/**/*.css`)
14 | }, {
15 | name: 'js',
16 | sources: gulp.src(`${Config.APP_DEST}/**/*.js`)
17 | }]
18 | })
19 | .pipe(gulp.dest(Config.APP_DEST));
20 | };
21 |
--------------------------------------------------------------------------------
/tools/tasks/seed/karma.run.ts:
--------------------------------------------------------------------------------
1 | import { startKarma } from '../../utils/seed/karma.start';
2 | import Config from '../../config';
3 |
4 | /**
5 | * Executes the build process, running all unit tests using `karma`.
6 | */
7 | export = (done: any) => {
8 | return startKarma(done, Config.getKarmaReporters());
9 | };
10 |
--------------------------------------------------------------------------------
/tools/tasks/seed/karma.run.with_coverage.ts:
--------------------------------------------------------------------------------
1 | import * as karma from 'karma';
2 | import { join } from 'path';
3 |
4 | import Config from '../../config';
5 |
6 | let repeatableStartKarma = (done: any, config: any = {}) => {
7 | return new (karma).Server(Object.assign({
8 | configFile: join(process.cwd(), 'karma.conf.js'),
9 | singleRun: true
10 | }, config), (exitCode: any) => {
11 | // Karma run is finished but do not exit the process for failure. Rather just mark this task as done.
12 | done();
13 | }).start();
14 | };
15 |
16 | export = (done: any) => {
17 | let karmaReporters = Config.getKarmaReporters();
18 | karmaReporters.singleRun = true;
19 | return repeatableStartKarma(done, karmaReporters);
20 | };
21 |
--------------------------------------------------------------------------------
/tools/tasks/seed/karma.watch.ts:
--------------------------------------------------------------------------------
1 | import { startKarma } from '../../utils/seed/karma.start';
2 | /**
3 | * Executes the build process, running all unit tests using `karma`.
4 | */
5 | export = (done: any) => setTimeout(() => {
6 | return startKarma(done, {
7 | singleRun: false
8 | });
9 | },
10 | // On some OS, the default max opened file descriptor limit might cause karma to not start.
11 | // By setting this timeout, there should be enough time before other tasks release the descriptors.
12 | // Karma itself can have as many opened files as it needs, it uses graceful-fs.
13 | 1000);
14 |
--------------------------------------------------------------------------------
/tools/tasks/seed/minify.bundles.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import * as merge from 'merge-stream';
4 | import { join } from 'path';
5 |
6 | import Config from '../../config';
7 |
8 | const plugins = gulpLoadPlugins();
9 |
10 | const getTask = (target: string, destDir: string) => {
11 | return gulp.src(join(destDir, target))
12 | .pipe(plugins.uglify({
13 | compress: true,
14 | mangle: true
15 | }))
16 | .pipe(gulp.dest(destDir));
17 | };
18 |
19 | export = () => {
20 | return merge(
21 | getTask(Config.JS_PROD_APP_BUNDLE, Config.JS_DEST),
22 | getTask(Config.JS_PROD_SHIMS_BUNDLE, Config.JS_DEST)
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/tools/tasks/seed/noop.ts:
--------------------------------------------------------------------------------
1 | export = (done: any) => {
2 | done();
3 | };
4 |
--------------------------------------------------------------------------------
/tools/tasks/seed/print.banner.ts:
--------------------------------------------------------------------------------
1 | import Config from '../../config';
2 | import { readFile } from 'fs';
3 | import * as util from 'gulp-util';
4 | import { join } from 'path';
5 |
6 | export = (done: any) => {
7 | let bannerPath = join(Config.TOOLS_DIR, 'config', 'banner.txt');
8 | if (require('supports-color').has256) {
9 | bannerPath = join(Config.TOOLS_DIR, 'config', 'banner-256.txt');
10 | }
11 | readFile(bannerPath, (e, content) => {
12 | if (!e) {
13 | console.log(util.colors.green(content.toString()));
14 | }
15 | done();
16 | });
17 | };
18 |
19 |
--------------------------------------------------------------------------------
/tools/tasks/seed/serve.coverage.ts:
--------------------------------------------------------------------------------
1 | import { serveCoverage } from '../../utils';
2 |
3 | /**
4 | * Executes the build process, serving unit test coverage report using an `express` server.
5 | */
6 | export = serveCoverage;
7 |
--------------------------------------------------------------------------------
/tools/tasks/seed/serve.coverage.watch.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import * as browserSync from 'browser-sync';
3 |
4 | import Config from '../../config';
5 |
6 | export = () => {
7 | let coverageFolder = Config.COVERAGE_TS_DIR;
8 | let watchedFiles: string[] = [join(coverageFolder, '**')];
9 |
10 | // Serve files from the coverage of this project
11 | browserSync.create().init({
12 | server: {
13 | baseDir: './' + coverageFolder
14 | },
15 | port: Config.COVERAGE_PORT,
16 | files: watchedFiles,
17 | logFileChanges: false
18 | });
19 | };
20 |
--------------------------------------------------------------------------------
/tools/tasks/seed/serve.docs.ts:
--------------------------------------------------------------------------------
1 | import { serveDocs } from '../../utils';
2 |
3 | /**
4 | * Executes the build process, serving the application documentation using an `express` server.
5 | */
6 | export = serveDocs;
7 |
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/server.prod.ts:
--------------------------------------------------------------------------------
1 | import { serveProd } from '../../utils';
2 |
3 | /**
4 | * Executes the build process, serving the files of the production environment using an `express` server.
5 | */
6 | export = serveProd;
7 |
--------------------------------------------------------------------------------
/tools/tasks/seed/server.start.ts:
--------------------------------------------------------------------------------
1 | import { serveSPA } from '../../utils';
2 |
3 | /**
4 | * Executes the build process, serving the files of the development environment using an `express` server.
5 | */
6 | export = serveSPA;
7 |
--------------------------------------------------------------------------------
/tools/tasks/seed/start.deving.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 | import * as runSequence from 'run-sequence';
5 |
6 | import Config from '../../config';
7 |
8 | const plugins = gulpLoadPlugins();
9 |
10 | import { notifyLiveReload } from '../../utils';
11 |
12 | function watchAppFiles(path: string, fileChangeCallback: (e: any, done: () => void) => void) {
13 |
14 | let paths: string[] = [
15 | join(Config.APP_SRC, path)
16 | ].concat(Config.TEMP_FILES.map((p) => { return '!' + p; }));
17 |
18 | let busyWithCall : boolean = false;
19 | let changesWaiting : any = null;
20 | let afterCall = () => {
21 | busyWithCall = false;
22 | if (changesWaiting) {
23 | fileChangeCallback(changesWaiting, afterCall);
24 | changesWaiting = null;
25 | }
26 | };
27 | plugins.watch(paths, (e: any) => {
28 | if (busyWithCall) {
29 | changesWaiting = e;
30 | return;
31 | }
32 | busyWithCall = true;
33 | fileChangeCallback(e, afterCall);
34 | });
35 |
36 | }
37 |
38 | gulp.task('watch.while_deving', function () {
39 | watchAppFiles('**/!(*.ts)', (e: any, done: any) =>
40 | runSequence('build.assets.dev', 'build.html_css', 'build.index.dev', () => { notifyLiveReload(e); done(); }));
41 | watchAppFiles('**/(*.ts)', (e: any, done: any) =>
42 | runSequence('build.js.dev', 'build.index.dev', () => {
43 | notifyLiveReload(e);
44 | runSequence('build.js.test', 'karma.run.with_coverage', done);
45 | }));
46 | });
47 |
48 | export = (done: any) =>
49 | runSequence('build.test',
50 | 'watch.while_deving',
51 | 'server.start',
52 | 'karma.run.with_coverage',
53 | 'serve.coverage.watch',
54 | done);
55 |
--------------------------------------------------------------------------------
/tools/tasks/seed/transpile.bundles.rollup.aot.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 | import { makeTsProject, } from '../../utils';
7 | import { TemplateLocalsBuilder } from '../../utils/seed/template_locals';
8 |
9 | const plugins = gulpLoadPlugins();
10 |
11 | /**
12 | * Executes the build process, transpiling the TypeScript files for the production environment.
13 | */
14 |
15 | export = () => {
16 | const tsProject = makeTsProject({
17 | allowJs: true,
18 | noFallthroughCasesInSwitch: false
19 | }, Config.TMP_DIR);
20 | const src = [
21 | join(Config.TMP_DIR, 'bundle.js')
22 | ];
23 | const result = gulp.src(src)
24 | .pipe(plugins.plumber())
25 | .pipe(tsProject())
26 | .once('error', () => {
27 | this.once('finish', () => process.exit(1));
28 | });
29 |
30 | return result.js
31 | .pipe(plugins.template(new TemplateLocalsBuilder().build()))
32 | .pipe(plugins.rename(Config.JS_PROD_APP_BUNDLE))
33 | .pipe(gulp.dest(Config.JS_DEST))
34 | .on('error', (e: any) => {
35 | console.log(e);
36 | });
37 | };
38 |
--------------------------------------------------------------------------------
/tools/tasks/seed/tslint.tns.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/mgechev/angular-seed/pull/1681
2 | import * as gulp from 'gulp';
3 | import * as gulpLoadPlugins from 'gulp-load-plugins';
4 |
5 | import Config from '../../config';
6 |
7 | const plugins = gulpLoadPlugins();
8 |
9 | /**
10 | * Executes the build process, linting the TypeScript files using `codelyzer`.
11 | */
12 | export = () => {
13 | let src = [
14 | '**/*.ts',
15 | 'app/**/*.ts',
16 | ];
17 |
18 | return gulp.src(src, {
19 | base: Config.TNS_APP_SRC,
20 | cwd: Config.TNS_APP_SRC,
21 | })
22 | .pipe(plugins.tslint())
23 | .pipe(plugins.tslint.report({
24 | emitError: require('is-ci')
25 | }));
26 | };
27 |
--------------------------------------------------------------------------------
/tools/tasks/seed/tslint.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as gulpLoadPlugins from 'gulp-load-plugins';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 |
7 | const plugins = gulpLoadPlugins();
8 |
9 | /**
10 | * Executes the build process, linting the TypeScript files using `codelyzer`.
11 | */
12 | export = () => {
13 | let src = [
14 | join(Config.APP_SRC, '**/*.ts'),
15 | '!' + join(Config.APP_SRC, '**/*.d.ts'),
16 | join(Config.E2E_SRC, '**/*.ts'),
17 | '!' + join(Config.E2E_SRC, '**/*.d.ts'),
18 | join(Config.TOOLS_DIR, '**/*.ts'),
19 | '!' + join(Config.TOOLS_DIR, '**/*.d.ts')
20 | ];
21 |
22 | return gulp.src(src, {'base': '.'})
23 | .pipe(plugins.tslint())
24 | .pipe(plugins.tslint.report({
25 | emitError: require('is-ci') || Config.FORCE_TSLINT_EMIT_ERROR
26 | }));
27 | };
28 |
--------------------------------------------------------------------------------
/tools/tasks/seed/watch.dev.ts:
--------------------------------------------------------------------------------
1 | import { watch } from '../../utils';
2 |
3 | /**
4 | * Executes the build process, watching for file changes and rebuilding the development environment.
5 | */
6 | export = watch('build.dev');
7 |
--------------------------------------------------------------------------------
/tools/tasks/seed/watch.e2e.ts:
--------------------------------------------------------------------------------
1 | import { watch } from '../../utils';
2 | import Config from '../../config';
3 |
4 | /**
5 | * Executes the build process, watching for file changes and rebuilding the e2e environment.
6 | */
7 | export = watch('build.e2e', Config.E2E_SRC);
8 |
--------------------------------------------------------------------------------
/tools/tasks/seed/watch.test.ts:
--------------------------------------------------------------------------------
1 | import { watch } from '../../utils';
2 |
3 | /**
4 | * Executes the build process, watching for file changes and rebuilding the test environment.
5 | */
6 | export = watch('build.test');
7 |
--------------------------------------------------------------------------------
/tools/tasks/seed/watch.tns.ts:
--------------------------------------------------------------------------------
1 | import * as gulpLoadPlugins from 'gulp-load-plugins';
2 | import * as runSequence from 'run-sequence';
3 |
4 | import Config from '../../config';
5 | import { changeFileManager } from '../../utils/seed/code_change_tools';
6 | import { notifyLiveReload } from '../../utils';
7 | const plugins = gulpLoadPlugins();
8 |
9 | const taskname = 'build.tns';
10 |
11 | export = function watch() {
12 | const paths: string[] = [
13 | `${Config.ASSETS_SRC}/**/*`,
14 | `${Config.TNS_APP_SRC}/**/*`,
15 | `${Config.TNS_APP_SRC}/app/*`,
16 | `${Config.TNS_APP_SRC}/app/**/*`,
17 | `!${Config.TNS_APP_SRC}/app/*.component.css`,
18 | `!${Config.TNS_APP_SRC}/app/*.component.html`,
19 | ];
20 |
21 | plugins.watch(paths, (e: any) => {
22 | changeFileManager.addFile(e.path);
23 |
24 | runSequence(taskname, () => {
25 | changeFileManager.clear();
26 |
27 | notifyLiveReload(e);
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/tools/tasks/seed/webdriver.ts:
--------------------------------------------------------------------------------
1 | import { webdriver_update } from 'gulp-protractor';
2 |
3 | /**
4 | * Executes the build process, installing the selenium webdriver used for the protractor e2e specs.
5 | */
6 | export = webdriver_update;
7 |
--------------------------------------------------------------------------------
/tools/tasks/task.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Base class for all tasks.
3 | */
4 | export abstract class Task {
5 | /**
6 | * Override this task if you want to implement some custom
7 | * task activation mechanism. By default each task will be always executed.
8 | *
9 | * @param {string[]} files A list of files changed since the previous watch.
10 | */
11 | shallRun(files: string[]): boolean {
12 | return true;
13 | }
14 |
15 | /**
16 | * Implements your task behavior.
17 | *
18 | * @param {any} done A function which should be activated once your task completes.
19 | * @return {ReadWriteStream | Promise | void} This method can either return a promise
20 | * which should be resolved once your task execution completes, a stream
21 | * which should throw an end event once your task execution completes
22 | * or nothing in case you will manually invoke the `done` method.
23 | */
24 | abstract run(done?: any, files?: string[]): any | Promise | void;
25 | }
26 |
--------------------------------------------------------------------------------
/tools/tasks/typescript_task.ts:
--------------------------------------------------------------------------------
1 | import { Task } from './task';
2 |
3 | export abstract class TypeScriptTask extends Task {
4 | shallRun(files: String[]) {
5 | return files.reduce((a, f) => {
6 | return a || f.endsWith('.ts');
7 | }, false);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tools/utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This barrel file provides the export for the utilities provided by the project and the seed.
3 | */
4 | export * from './utils/project.utils';
5 | export * from './utils/seed.utils';
6 |
--------------------------------------------------------------------------------
/tools/utils/project.utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This barrel file provides the exports for the project specific utilities.
3 | */
4 | export * from './project/sample_util';
5 |
--------------------------------------------------------------------------------
/tools/utils/project/sample_util.ts:
--------------------------------------------------------------------------------
1 | export function myUtil() {
2 | // Code goes here
3 | }
4 |
--------------------------------------------------------------------------------
/tools/utils/seed.utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This barrel file provides the export for the utilities provided by the seed.
3 | */
4 | export * from './seed/clean';
5 | export * from './seed/code_change_tools';
6 | export * from './seed/server';
7 | export * from './seed/tasks_tools';
8 | export * from './seed/template_locals';
9 | export * from './seed/tsproject';
10 | export * from './seed/watch';
11 |
--------------------------------------------------------------------------------
/tools/utils/seed/clean.ts:
--------------------------------------------------------------------------------
1 | import * as util from 'gulp-util';
2 | import { relative, normalize } from 'path';
3 | import * as rimraf from 'rimraf';
4 |
5 | import Config from '../../config';
6 |
7 | /**
8 | * Cleans the given path(s) using `rimraf`.
9 | * @param {string or string[]} paths - The path or list of paths to clean.
10 | */
11 | export function clean(paths: string|string[]): (done: () => void) => void {
12 | return done => {
13 | let pathsToClean: string[];
14 | if (paths instanceof Array) {
15 | pathsToClean = paths;
16 | } else {
17 | pathsToClean = [paths];
18 | }
19 |
20 | let promises = pathsToClean.map(p => {
21 | return new Promise(resolve => {
22 | const relativePath: string = relative(Config.PROJECT_ROOT, p);
23 | if (relativePath.startsWith('..')) {
24 | util.log(util.colors.bgRed.white(`Cannot remove files outside the project root but tried "${normalize(p)}"`));
25 | process.exit(1);
26 | } else {
27 | rimraf(p, e => {
28 | if (e) {
29 | util.log('Clean task failed with', e);
30 | } else {
31 | util.log('Deleted', util.colors.yellow(p || '-'));
32 | }
33 | resolve();
34 | });
35 | }
36 | });
37 | });
38 | Promise.all(promises).then(() => (done || (() => 1))())
39 | .catch(e => util.log(util.colors.red(`Error while removing files "${[].concat(paths).join(', ')}", ${e}`)));
40 | };
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/tools/utils/seed/code_change_tools.ts:
--------------------------------------------------------------------------------
1 | import * as browserSync from 'browser-sync';
2 | // import * as path from 'path';
3 |
4 | import Config from '../../config';
5 |
6 | class ChangeFileManager {
7 | private _files: string[] = [];
8 | private _pristine = true;
9 |
10 | get lastChangedFiles() {
11 | return this._files.slice();
12 | }
13 |
14 | get pristine() {
15 | return this._pristine;
16 | }
17 |
18 | addFile(file: string) {
19 | this._pristine = false;
20 | this._files.push(file);
21 | }
22 |
23 | addFiles(files: string[]) {
24 | files.forEach(f => this.addFile(f));
25 | }
26 |
27 | clear() {
28 | this._files = [];
29 | }
30 | }
31 |
32 | export let changeFileManager = new ChangeFileManager();
33 |
34 | /**
35 | * Initialises BrowserSync with the configuration defined in seed.config.ts (or if overriden: project.config.ts).
36 | */
37 | let runServer = () => {
38 | browserSync.init(Config.getPluginConfig('browser-sync'));
39 | };
40 |
41 | /**
42 | * Runs BrowserSync as the listening process for the application.
43 | */
44 | let listen = () => {
45 | runServer();
46 | };
47 |
48 | /**
49 | * Provides a flag to mark which files have changed and reloads BrowserSync accordingly.
50 | */
51 | let changed = (files: any) => {
52 | if (!(files instanceof Array)) {
53 | files = [files];
54 | }
55 | browserSync.reload(files);
56 | };
57 |
58 | export { listen, changed };
59 |
--------------------------------------------------------------------------------
/tools/utils/seed/karma.start.ts:
--------------------------------------------------------------------------------
1 | import * as karma from 'karma';
2 | import { join } from 'path';
3 |
4 | export const startKarma = (done: any, config: any = {}) => {
5 | return new (karma).Server(Object.assign({
6 | configFile: join(process.cwd(), 'karma.conf.js'),
7 | singleRun: true
8 | }, config)).start(done);
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/tools/utils/seed/server.ts:
--------------------------------------------------------------------------------
1 | import * as express from 'express';
2 | import * as fallback from 'express-history-api-fallback';
3 | import * as openResource from 'open';
4 | import { resolve } from 'path';
5 |
6 | import * as codeChangeTool from './code_change_tools';
7 | import Config from '../../config';
8 |
9 | /**
10 | * Serves the Single Page Application. More specifically, calls the `listen` method, which itself launches BrowserSync.
11 | */
12 | export function serveSPA() {
13 | codeChangeTool.listen();
14 | }
15 |
16 | /**
17 | * This utility method is used to notify that a file change has happened and subsequently calls the `changed` method,
18 | * which itself initiates a BrowserSync reload.
19 | * @param {any} e - The file that has changed.
20 | */
21 | export function notifyLiveReload(e:any) {
22 | let fileName = e.path;
23 | codeChangeTool.changed(fileName);
24 | }
25 |
26 | /**
27 | * Starts a new `express` server, serving the static documentation files.
28 | */
29 | export function serveDocs() {
30 | let server = express();
31 |
32 | server.use(
33 | Config.APP_BASE,
34 | express.static(resolve(process.cwd(), Config.DOCS_DEST))
35 | );
36 |
37 | server.listen(Config.DOCS_PORT, () =>
38 | openResource('http://localhost:' + Config.DOCS_PORT + Config.APP_BASE)
39 | );
40 | }
41 |
42 | /**
43 | * Starts a new `express` server, serving the static unit test code coverage report.
44 | */
45 | export function serveCoverage() {
46 | let server = express();
47 |
48 | server.use(
49 | Config.APP_BASE,
50 | express.static(resolve(process.cwd(), Config.COVERAGE_TS_DIR))
51 | );
52 |
53 | server.listen(Config.COVERAGE_PORT, () =>
54 | openResource('http://localhost:' + Config.COVERAGE_PORT + Config.APP_BASE)
55 | );
56 | }
57 |
58 | /**
59 | * Starts a new `express` server, serving the built files from `dist/prod`.
60 | */
61 | export function serveProd() {
62 | let root = resolve(process.cwd(), Config.PROD_DEST);
63 | let server = express();
64 |
65 | for (let proxy of Config.getProxyMiddleware()) {
66 | server.use(proxy);
67 | }
68 |
69 | server.use(Config.APP_BASE, express.static(root));
70 |
71 | server.use(fallback('index.html', { root }));
72 |
73 | server.listen(Config.PORT, () =>
74 | openResource('http://localhost:' + Config.PORT + Config.APP_BASE)
75 | );
76 | };
77 |
--------------------------------------------------------------------------------
/tools/utils/seed/template_locals.ts:
--------------------------------------------------------------------------------
1 | import * as util from 'gulp-util';
2 | import { argv } from 'yargs';
3 | import { join } from 'path';
4 |
5 | import Config from '../../config';
6 |
7 | /**
8 | * Builds an object consisting of the base configuration provided by confg/seed.config.ts, the additional
9 | * project specific overrides as defined in config/project.config.ts and including the base environment config as defined in env/base.ts
10 | * and the environment specific overrides (for instance if env=dev then as defined in env/dev.ts).
11 | */
12 | export class TemplateLocalsBuilder {
13 | private stringifySystemConfigDev = false;
14 | private stringifyEnvConfig = true;
15 |
16 | withStringifiedSystemConfigDev() {
17 | this.stringifySystemConfigDev = true;
18 | return this;
19 | }
20 | wihtoutStringifiedEnvConfig() {
21 | this.stringifyEnvConfig = false;
22 | return this;
23 | }
24 |
25 |
26 | build() {
27 | const configEnvName = argv['env-config'] || argv['config-env'] || 'dev';
28 | const configPath = Config.getPluginConfig('environment-config');
29 | const envOnlyConfig = this.getConfig(configPath, configEnvName);
30 | const baseConfig = this.getConfig(configPath, 'base');
31 |
32 | if (!envOnlyConfig) {
33 | throw new Error(configEnvName + ' is an invalid configuration name');
34 | }
35 |
36 | const envConfig = Object.assign({}, baseConfig, envOnlyConfig);
37 | let locals = Object.assign({},
38 | Config,
39 | { ENV_CONFIG: this.stringifyEnvConfig ? JSON.stringify(envConfig) : envConfig }
40 | );
41 | if (this.stringifySystemConfigDev) {
42 | Object.assign(locals, {SYSTEM_CONFIG_DEV: JSON.stringify(Config.SYSTEM_CONFIG_DEV)});
43 | }
44 | return locals;
45 | }
46 |
47 | private getConfig(path: string, env: string) {
48 | const configPath = join(path, env);
49 | let config: any;
50 | try {
51 | config = JSON.parse(JSON.stringify(require(configPath)));
52 | } catch (e) {
53 | config = null;
54 | util.log(util.colors.red(e.message));
55 | }
56 |
57 | return config;
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/tools/utils/seed/tsproject.ts:
--------------------------------------------------------------------------------
1 | import * as gulpLoadPlugins from 'gulp-load-plugins';
2 | import { join } from 'path';
3 | import ts = require('gulp-typescript/release/main');
4 |
5 | import Config from '../../config';
6 |
7 | const plugins = gulpLoadPlugins();
8 |
9 | let tsProjects: any = {};
10 |
11 | /**
12 | * Creates a TypeScript project with the given options using the gulp typescript plugin.
13 | * @param {Object} options - The additional options for the project configuration.
14 | */
15 | export function makeTsProject(options: ts.Settings = {}, pathToTsConfig: string = Config.APP_SRC, projectName = Config.APP_PROJECTNAME) {
16 | let optionsHash = JSON.stringify(options);
17 | if (!tsProjects[optionsHash]) {
18 | let config = Object.assign({
19 | typescript: require('typescript')
20 | }, options);
21 | tsProjects[optionsHash] =
22 | plugins.typescript.createProject(join(pathToTsConfig, projectName), config);
23 | }
24 | return tsProjects[optionsHash];
25 | }
26 |
--------------------------------------------------------------------------------
/tools/utils/seed/watch.ts:
--------------------------------------------------------------------------------
1 | import * as gulpLoadPlugins from 'gulp-load-plugins';
2 | import { join } from 'path';
3 | import * as runSequence from 'run-sequence';
4 |
5 | import Config from '../../config';
6 | import { changeFileManager } from './code_change_tools';
7 | import { notifyLiveReload } from '../../utils';
8 |
9 | const plugins = gulpLoadPlugins();
10 |
11 | /**
12 | * Watches the task with the given taskname.
13 | * @param {string} taskname - The name of the task.
14 | */
15 | export function watch(taskname: string, root: string = Config.APP_SRC) {
16 | return function () {
17 | let paths: string[] = [
18 | join(root, '**')
19 | ].concat(Config.TEMP_FILES.map((p) => { return '!' + p; }));
20 |
21 | // watches for user defined paths to trigger compilation
22 | if (Config.EXTRA_WATCH_PATHS) {
23 | paths = paths.concat(Config.EXTRA_WATCH_PATHS.map((p) => {
24 | return join(p, '**');
25 | }));
26 | }
27 |
28 | plugins.watch(paths, (e: any) => {
29 | changeFileManager.addFile(e.path);
30 |
31 |
32 | // Resolves issue in IntelliJ and other IDEs/text editors which
33 | // save multiple files at once.
34 | // https://github.com/mgechev/angular-seed/issues/1615 for more details.
35 | setTimeout(() => {
36 |
37 | runSequence(taskname, () => {
38 | changeFileManager.clear();
39 | notifyLiveReload(e);
40 | });
41 |
42 | }, 100);
43 | });
44 | };
45 | }
46 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "declaration": false,
6 | "removeComments": true,
7 | "noLib": false,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "lib": ["es2015"],
11 | "sourceMap": true,
12 | "pretty": true,
13 | "allowUnreachableCode": false,
14 | "allowUnusedLabels": false,
15 | "noImplicitAny": true,
16 | "noImplicitReturns": true,
17 | "noImplicitUseStrict": false,
18 | "noFallthroughCasesInSwitch": true,
19 | "typeRoots": [
20 | "./node_modules/@types",
21 | "./node_modules"
22 | ],
23 | "types": [
24 | "node"
25 | ]
26 | },
27 | "exclude": [
28 | "desktop",
29 | "nativescript",
30 | "node_modules",
31 | "dist",
32 | "src"
33 | ],
34 | "compileOnSave": false
35 | }
36 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tools/config/seed.tslint.json",
3 | "rules": {
4 | }
5 | }
6 |
--------------------------------------------------------------------------------