diff --git a/.eslintignore b/.eslintignore
index f07735d14909..2f22ee7a858c 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -5,7 +5,7 @@ tmp/
typings/
# Ignore all blueprint files. We e2e tests those later on.
-packages/angular-cli/blueprints/*/files/
+packages/universal-cli/blueprints/*/files/
# Ignore ember cli.
-packages/angular-cli/ember-cli/
\ No newline at end of file
+packages/universal-cli/ember-cli/
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index fa7c45bbb104..d63ca452e4b5 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -6,7 +6,7 @@
### Versions.
-> Please run `ng --version`. If there's nothing outputted, please run in a Terminal: `node --version` and paste the result here:
+> Please run `ung --version`. If there's nothing outputted, please run in a Terminal: `node --version` and paste the result here:
### Repro steps.
diff --git a/.travis.yml b/.travis.yml
index f09e83ca2e5c..0d3fbaa714c6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,9 +20,6 @@ matrix:
- node_js: "6"
os: linux
env: SCRIPT=build
- - node_js: "4"
- os: linux
- env: NODE_SCRIPT=tests/e2e_runner.js
- node_js: "6"
os: linux
env: SCRIPT=test
@@ -43,6 +40,18 @@ matrix:
- node_js: "7"
os: linux
env: NODE_SCRIPT=tests/e2e_runner.js
+ - node_js: "5"
+ os: osx
+ env: UNIVERSAL=true NODE_SCRIPT=tests/e2e_runner.js
+ - node_js: "6"
+ os: osx
+ env: UNIVERSAL=true NODE_SCRIPT=tests/e2e_runner.js
+ - node_js: "5"
+ os: linux
+ env: UNIVERSAL=true NODE_SCRIPT=tests/e2e_runner.js
+ - node_js: "6"
+ os: linux
+ env: UNIVERSAL=true NODE_SCRIPT=tests/e2e_runner.js
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
@@ -53,7 +62,6 @@ before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh -e /etc/init.d/xvfb start; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CHROME_BIN=chromium-browser; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo "--no-sandbox" > ~/.config/chromium-flags.conf; fi
- - if [[ "$TARGET" == "mobile" ]]; then export MOBILE_TEST=true; fi
- npm install -g npm
- npm config set spin false
- npm config set progress false
@@ -64,3 +72,6 @@ install:
script:
- if [[ "$SCRIPT" ]]; then npm run-script $SCRIPT; fi
- if [[ "$NODE_SCRIPT" ]]; then node $NODE_SCRIPT; fi
+
+notifications:
+ email: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8dff9c0bc660..d45bc87f4b08 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,140 +1,136 @@
-
-# [1.0.0-beta.23](https://github.com/angular/angular-cli/compare/v1.0.0-beta.22-1...v1.0.0-beta.23) (2016-12-15)
+
+# [1.0.0-alpha.universal.3](https://github.com/devCrossNet/universal-cli/compare/v1.0.0-alpha.universal.2-2...v1.0.0-alpha.universal.3) (2016-12-29)
### Bug Fixes
-* **@ngtools/webpack:** keep the decorators in. ([#3583](https://github.com/angular/angular-cli/issues/3583)) ([db25183](https://github.com/angular/angular-cli/commit/db25183))
-* **@ngtools/webpack:** use tsconfig declaration flag to report decl errors ([#3499](https://github.com/angular/angular-cli/issues/3499)) ([c46de15](https://github.com/angular/angular-cli/commit/c46de15))
-* **blueprints:** remove app root barrel ([#3530](https://github.com/angular/angular-cli/issues/3530)) ([3329d46](https://github.com/angular/angular-cli/commit/3329d46)), closes [#3369](https://github.com/angular/angular-cli/issues/3369)
-* **build:** added autoprefixer to prod ([1648d51](https://github.com/angular/angular-cli/commit/1648d51)), closes [#3156](https://github.com/angular/angular-cli/issues/3156) [#3164](https://github.com/angular/angular-cli/issues/3164)
-* **build:** pin [@types](https://github.com/types)/lodash ([#3465](https://github.com/angular/angular-cli/issues/3465)) ([9b65481](https://github.com/angular/angular-cli/commit/9b65481))
-* **completion:** Update with the new help command ([#3479](https://github.com/angular/angular-cli/issues/3479)) ([0b5dc74](https://github.com/angular/angular-cli/commit/0b5dc74))
-* **dependencies:** reduce the dependencies further. ([#3488](https://github.com/angular/angular-cli/issues/3488)) ([901a64f](https://github.com/angular/angular-cli/commit/901a64f))
-* **deploy:** gh-pages checkout initial branch on error ([#3378](https://github.com/angular/angular-cli/issues/3378)) ([c5cd095](https://github.com/angular/angular-cli/commit/c5cd095)), closes [#3030](https://github.com/angular/angular-cli/issues/3030) [#2663](https://github.com/angular/angular-cli/issues/2663) [#1259](https://github.com/angular/angular-cli/issues/1259)
-* **deploy:** gh-pages deploy fail after repo create ([#3386](https://github.com/angular/angular-cli/issues/3386)) ([0a68cc5](https://github.com/angular/angular-cli/commit/0a68cc5)), closes [#3385](https://github.com/angular/angular-cli/issues/3385)
-* **gitignore:** No longer ignore VSCode settings ([#3477](https://github.com/angular/angular-cli/issues/3477)) ([8d88446](https://github.com/angular/angular-cli/commit/8d88446))
-* **help:** fix `ng help ` ([#3442](https://github.com/angular/angular-cli/issues/3442)) ([51659b9](https://github.com/angular/angular-cli/commit/51659b9))
-* **new:** Make sure the project name is valid. ([#3478](https://github.com/angular/angular-cli/issues/3478)) ([e836f92](https://github.com/angular/angular-cli/commit/e836f92))
-* **webpack:** fix some problems with errors not reported. ([#3444](https://github.com/angular/angular-cli/issues/3444)) ([09f9aa9](https://github.com/angular/angular-cli/commit/09f9aa9))
-* **webpack:** remove usage of __dirname from the config. ([#3422](https://github.com/angular/angular-cli/issues/3422)) ([8597786](https://github.com/angular/angular-cli/commit/8597786))
+* **@ngtools/webpack:** fixed path resolution for entry modules and lazy routes ([#3332](https://github.com/devCrossNet/universal-cli/issues/3332)) ([45d5154](https://github.com/devCrossNet/universal-cli/commit/45d5154))
+* **@ngtools/webpack:** keep the decorators in. ([#3583](https://github.com/devCrossNet/universal-cli/issues/3583)) ([db25183](https://github.com/devCrossNet/universal-cli/commit/db25183))
+* **@ngtools/webpack:** performance improvement. ([#3360](https://github.com/devCrossNet/universal-cli/issues/3360)) ([4dcfe27](https://github.com/devCrossNet/universal-cli/commit/4dcfe27))
+* **@ngtools/webpack:** report errors during codegen ([#3608](https://github.com/devCrossNet/universal-cli/issues/3608)) ([0f604ac](https://github.com/devCrossNet/universal-cli/commit/0f604ac))
+* **@ngtools/webpack:** use tsconfig declaration flag to report decl errors ([#3499](https://github.com/devCrossNet/universal-cli/issues/3499)) ([c46de15](https://github.com/devCrossNet/universal-cli/commit/c46de15))
+* **aot:** lock the angular version to 2.2.1. ([#3242](https://github.com/devCrossNet/universal-cli/issues/3242)) ([6e8a848](https://github.com/devCrossNet/universal-cli/commit/6e8a848))
+* **blueprints:** remove app root barrel ([#3530](https://github.com/devCrossNet/universal-cli/issues/3530)) ([3329d46](https://github.com/devCrossNet/universal-cli/commit/3329d46)), closes [#3369](https://github.com/devCrossNet/universal-cli/issues/3369)
+* **build:** added autoprefixer to prod ([1648d51](https://github.com/devCrossNet/universal-cli/commit/1648d51)), closes [#3156](https://github.com/devCrossNet/universal-cli/issues/3156) [#3164](https://github.com/devCrossNet/universal-cli/issues/3164)
+* **build:** don't inline sourcemaps ([#3262](https://github.com/devCrossNet/universal-cli/issues/3262)) ([859d905](https://github.com/devCrossNet/universal-cli/commit/859d905))
+* **build:** pin [@types](https://github.com/types)/lodash ([#3465](https://github.com/devCrossNet/universal-cli/issues/3465)) ([9b65481](https://github.com/devCrossNet/universal-cli/commit/9b65481))
+* **build:** use custom index value when copying to 404.html during github deploy ([#3201](https://github.com/devCrossNet/universal-cli/issues/3201)) ([b1cbf17](https://github.com/devCrossNet/universal-cli/commit/b1cbf17))
+* **completion:** Update with the new help command ([#3479](https://github.com/devCrossNet/universal-cli/issues/3479)) ([0b5dc74](https://github.com/devCrossNet/universal-cli/commit/0b5dc74))
+* **dependencies:** reduce the dependencies further. ([#3488](https://github.com/devCrossNet/universal-cli/issues/3488)) ([901a64f](https://github.com/devCrossNet/universal-cli/commit/901a64f))
+* **deploy:** clean up gh-pages obsolete files ([#3081](https://github.com/devCrossNet/universal-cli/issues/3081)) ([#3333](https://github.com/devCrossNet/universal-cli/issues/3333)) ([51869fb](https://github.com/devCrossNet/universal-cli/commit/51869fb))
+* **deploy:** gh-pages checkout initial branch on error ([#3378](https://github.com/devCrossNet/universal-cli/issues/3378)) ([c5cd095](https://github.com/devCrossNet/universal-cli/commit/c5cd095)), closes [#3030](https://github.com/devCrossNet/universal-cli/issues/3030) [#2663](https://github.com/devCrossNet/universal-cli/issues/2663) [#1259](https://github.com/devCrossNet/universal-cli/issues/1259)
+* **deploy:** gh-pages deploy fail after repo create ([#3386](https://github.com/devCrossNet/universal-cli/issues/3386)) ([0a68cc5](https://github.com/devCrossNet/universal-cli/commit/0a68cc5)), closes [#3385](https://github.com/devCrossNet/universal-cli/issues/3385)
+* **deps:** lock [@ngtools](https://github.com/ngtools)/webpack version ([758f1ea](https://github.com/devCrossNet/universal-cli/commit/758f1ea))
+* **deps:** upgrade node-sass & sass-loader ([fa74f3f](https://github.com/devCrossNet/universal-cli/commit/fa74f3f)), closes [#44](https://github.com/devCrossNet/universal-cli/issues/44)
+* **editorconfig:** use off instead of 0 for max line length ([#3186](https://github.com/devCrossNet/universal-cli/issues/3186)) ([f833d25](https://github.com/devCrossNet/universal-cli/commit/f833d25))
+* **gitignore:** No longer ignore VSCode settings ([#3477](https://github.com/devCrossNet/universal-cli/issues/3477)) ([8d88446](https://github.com/devCrossNet/universal-cli/commit/8d88446))
+* **help:** fix `ng help ` ([#3442](https://github.com/devCrossNet/universal-cli/issues/3442)) ([51659b9](https://github.com/devCrossNet/universal-cli/commit/51659b9))
+* **init:** The option '--universal' is not registered with the init command ([37c8357](https://github.com/devCrossNet/universal-cli/commit/37c8357)), closes [#27](https://github.com/devCrossNet/universal-cli/issues/27) [#24](https://github.com/devCrossNet/universal-cli/issues/24)
+* **new:** Make sure the project name is valid. ([#3478](https://github.com/devCrossNet/universal-cli/issues/3478)) ([e836f92](https://github.com/devCrossNet/universal-cli/commit/e836f92))
+* **ngtools/webpack:** move the generate directory to a separate dir ([#3256](https://github.com/devCrossNet/universal-cli/issues/3256)) ([d1037df](https://github.com/devCrossNet/universal-cli/commit/d1037df))
+* **test:** exclude non spec files from test.ts ([#3538](https://github.com/devCrossNet/universal-cli/issues/3538)) ([bcb324f](https://github.com/devCrossNet/universal-cli/commit/bcb324f))
+* **universal:** remove duplicate entry from package.json ([47b34a2](https://github.com/devCrossNet/universal-cli/commit/47b34a2)), closes [#26](https://github.com/devCrossNet/universal-cli/issues/26)
+* **version:** bump ast-tools and webpack versions to correct mismatch with published packages ([54ef738](https://github.com/devCrossNet/universal-cli/commit/54ef738))
+* **webpack:** correctly load component stylesheets ([#3511](https://github.com/devCrossNet/universal-cli/issues/3511)) ([d4da7bd](https://github.com/devCrossNet/universal-cli/commit/d4da7bd))
+* **webpack:** fix some problems with errors not reported. ([#3444](https://github.com/devCrossNet/universal-cli/issues/3444)) ([09f9aa9](https://github.com/devCrossNet/universal-cli/commit/09f9aa9))
+* change apiFilter querystring to query in ng doc([#3383](https://github.com/devCrossNet/universal-cli/issues/3383)) ([5b2a0fb](https://github.com/devCrossNet/universal-cli/commit/5b2a0fb)), closes [#3363](https://github.com/devCrossNet/universal-cli/issues/3363)
+* **webpack:** remove usage of __dirname from the config. ([#3422](https://github.com/devCrossNet/universal-cli/issues/3422)) ([8597786](https://github.com/devCrossNet/universal-cli/commit/8597786))
### Features
-* Make CLI available without install ([761e86f](https://github.com/angular/angular-cli/commit/761e86f)), closes [#3126](https://github.com/angular/angular-cli/issues/3126)
-* **build:** add lazy styles/scripts ([#3402](https://github.com/angular/angular-cli/issues/3402)) ([20bb864](https://github.com/angular/angular-cli/commit/20bb864)), closes [#3401](https://github.com/angular/angular-cli/issues/3401) [#3400](https://github.com/angular/angular-cli/issues/3400)
-* **deps:** Unblock the version of Angular to >= 2.3 ([#3569](https://github.com/angular/angular-cli/issues/3569)) ([bd03100](https://github.com/angular/angular-cli/commit/bd03100))
-* **generate:** change generate --prefix option type from Boolean to string ([#3457](https://github.com/angular/angular-cli/issues/3457)) ([8d5a915](https://github.com/angular/angular-cli/commit/8d5a915))
-* **i18n:** add i18n command line options ([#3098](https://github.com/angular/angular-cli/issues/3098)) ([2a0a42d](https://github.com/angular/angular-cli/commit/2a0a42d))
-* **module:** component optional when generating module ([#3389](https://github.com/angular/angular-cli/issues/3389)) ([2fb2d13](https://github.com/angular/angular-cli/commit/2fb2d13))
-* **serve:** Add support to open with ssl. ([#3432](https://github.com/angular/angular-cli/issues/3432)) ([83dfc96](https://github.com/angular/angular-cli/commit/83dfc96))
+* **angular:** Update Angular2 version to 2.2.3 ([#3295](https://github.com/devCrossNet/universal-cli/issues/3295)) ([ed305a2](https://github.com/devCrossNet/universal-cli/commit/ed305a2))
+* **build:** add --verbose and --progress flags ([#2858](https://github.com/devCrossNet/universal-cli/issues/2858)) ([f6f24e7](https://github.com/devCrossNet/universal-cli/commit/f6f24e7)), closes [#1836](https://github.com/devCrossNet/universal-cli/issues/1836) [#2012](https://github.com/devCrossNet/universal-cli/issues/2012)
+* **build:** add lazy styles/scripts ([#3402](https://github.com/devCrossNet/universal-cli/issues/3402)) ([20bb864](https://github.com/devCrossNet/universal-cli/commit/20bb864)), closes [#3401](https://github.com/devCrossNet/universal-cli/issues/3401) [#3400](https://github.com/devCrossNet/universal-cli/issues/3400)
+* Make CLI available without install ([761e86f](https://github.com/devCrossNet/universal-cli/commit/761e86f)), closes [#3126](https://github.com/devCrossNet/universal-cli/issues/3126)
+* **build:** auto generate vendor chunk ([#3117](https://github.com/devCrossNet/universal-cli/issues/3117)) ([bf9c8f1](https://github.com/devCrossNet/universal-cli/commit/bf9c8f1))
+* **cli:** update to angular-cli beta >= 21 ([ef2104f](https://github.com/devCrossNet/universal-cli/commit/ef2104f)), closes [#21](https://github.com/devCrossNet/universal-cli/issues/21)
+* **deps:** Unblock the version of Angular to >= 2.3 ([#3569](https://github.com/devCrossNet/universal-cli/issues/3569)) ([bd03100](https://github.com/devCrossNet/universal-cli/commit/bd03100))
+* **generate:** change generate --prefix option type from Boolean to string ([#3457](https://github.com/devCrossNet/universal-cli/issues/3457)) ([8d5a915](https://github.com/devCrossNet/universal-cli/commit/8d5a915))
+* **i18n:** add i18n command line options ([#3098](https://github.com/devCrossNet/universal-cli/issues/3098)) ([2a0a42d](https://github.com/devCrossNet/universal-cli/commit/2a0a42d))
+* **module:** component optional when generating module ([#3389](https://github.com/devCrossNet/universal-cli/issues/3389)) ([2fb2d13](https://github.com/devCrossNet/universal-cli/commit/2fb2d13))
+* **new:** include routing in spec and inline template when called with `--routing` ([#3252](https://github.com/devCrossNet/universal-cli/issues/3252)) ([53ab4df](https://github.com/devCrossNet/universal-cli/commit/53ab4df))
+* **serve:** add --hmr flag for HotModuleReplacement support ([#3330](https://github.com/devCrossNet/universal-cli/issues/3330)) ([46efa9e](https://github.com/devCrossNet/universal-cli/commit/46efa9e))
+* **serve:** Add support to open with ssl. ([#3432](https://github.com/devCrossNet/universal-cli/issues/3432)) ([83dfc96](https://github.com/devCrossNet/universal-cli/commit/83dfc96))
### Performance Improvements
-* **install time:** Remove dependency to zopfli. ([#3414](https://github.com/angular/angular-cli/issues/3414)) ([e6364a9](https://github.com/angular/angular-cli/commit/e6364a9))
+* **install time:** Remove dependency to zopfli. ([#3414](https://github.com/devCrossNet/universal-cli/issues/3414)) ([e6364a9](https://github.com/devCrossNet/universal-cli/commit/e6364a9))
### BREAKING CHANGES
* blueprints: The app root module and component must now be imported directly. (e.g., use `import { AppModule } from './app/app.module';` instead of `import { AppModule } from './app/';`)
+* build: `ng build/serve` now generates `vendor.bundle.js` by
+default.
-
-# [1.0.0-beta.22-1](https://github.com/angular/angular-cli/compare/v1.0.0-beta.22...v1.0.0-beta.22-1) (2016-12-05)
-
-
-### Bug Fixes
-
-* **@ngtools/webpack:** performance improvement. ([#3360](https://github.com/angular/angular-cli/issues/3360)) ([4dcfe27](https://github.com/angular/angular-cli/commit/4dcfe27))
-* **deploy:** clean up gh-pages obsolete files ([#3081](https://github.com/angular/angular-cli/issues/3081)) ([#3333](https://github.com/angular/angular-cli/issues/3333)) ([51869fb](https://github.com/angular/angular-cli/commit/51869fb))
-* change apiFilter querystring to query in ng doc([#3383](https://github.com/angular/angular-cli/issues/3383)) ([5b2a0fb](https://github.com/angular/angular-cli/commit/5b2a0fb)), closes [#3363](https://github.com/angular/angular-cli/issues/3363)
-
-
-
-
-# [1.0.0-beta.22](https://github.com/angular/angular-cli/compare/v1.0.0-beta.21...v1.0.0-beta.22) (2016-12-02)
+
+# [1.0.0-alpha.universal.2](https://github.com/devCrossNet/angular-cli/compare/v1.0.0-beta.19...v1.0.0-alpha.universal.2) (2016-11-26)
### Bug Fixes
-* **@ngtools/webpack:** fixed path resolution for entry modules and lazy routes ([#3332](https://github.com/angular/angular-cli/issues/3332)) ([45d5154](https://github.com/angular/angular-cli/commit/45d5154))
-* **build:** don't inline sourcemaps ([#3262](https://github.com/angular/angular-cli/issues/3262)) ([859d905](https://github.com/angular/angular-cli/commit/859d905))
-* **build:** use custom index value when copying to 404.html during github deploy ([#3201](https://github.com/angular/angular-cli/issues/3201)) ([b1cbf17](https://github.com/angular/angular-cli/commit/b1cbf17))
-* **ngtools/webpack:** move the generate directory to a separate dir ([#3256](https://github.com/angular/angular-cli/issues/3256)) ([d1037df](https://github.com/angular/angular-cli/commit/d1037df))
-* **version:** bump ast-tools and webpack versions to correct mismatch with published packages ([54ef738](https://github.com/angular/angular-cli/commit/54ef738))
+* **@ngtools/webpack:** fixed relative path for AoT. ([#3114](https://github.com/devCrossNet/angular-cli/issues/3114)) ([27a034d](https://github.com/devCrossNet/angular-cli/commit/27a034d))
+* **angular-cli:** add necessary dependencies. ([#3152](https://github.com/devCrossNet/angular-cli/issues/3152)) ([8f574e4](https://github.com/devCrossNet/angular-cli/commit/8f574e4)), closes [#3148](https://github.com/devCrossNet/angular-cli/issues/3148)
+* **angular-cli:** add necessary dependency. ([f7704b0](https://github.com/devCrossNet/angular-cli/commit/f7704b0))
+* **angular-cli:** change version of webpack plugin. ([07e96ea](https://github.com/devCrossNet/angular-cli/commit/07e96ea))
+* **aot:** exclude spec files from aot ([#2758](https://github.com/devCrossNet/angular-cli/issues/2758)) ([215e555](https://github.com/devCrossNet/angular-cli/commit/215e555))
+* **aot:** output the sources in the sourcemap. ([#3107](https://github.com/devCrossNet/angular-cli/issues/3107)) ([7127dba](https://github.com/devCrossNet/angular-cli/commit/7127dba))
+* **deps:** explicitely add portfinder ([#2831](https://github.com/devCrossNet/angular-cli/issues/2831)) ([2d8f162](https://github.com/devCrossNet/angular-cli/commit/2d8f162)), closes [#2755](https://github.com/devCrossNet/angular-cli/issues/2755) [#2769](https://github.com/devCrossNet/angular-cli/issues/2769)
+* **generate:** fix module component path if module is created in child folder ([#3066](https://github.com/devCrossNet/angular-cli/issues/3066)) ([38d5f2c](https://github.com/devCrossNet/angular-cli/commit/38d5f2c)), closes [#3063](https://github.com/devCrossNet/angular-cli/issues/3063)
+* **generate:** revert change to component dir in generate module, as it caused component declaration to go to parent module ([#3158](https://github.com/devCrossNet/angular-cli/issues/3158)) ([71bf855](https://github.com/devCrossNet/angular-cli/commit/71bf855))
+* **github-pages-deploy:** Show more accurate url ([#3160](https://github.com/devCrossNet/angular-cli/issues/3160)) ([a431389](https://github.com/devCrossNet/angular-cli/commit/a431389))
+* **universal:** add polyfills.ts ([37770d5](https://github.com/devCrossNet/angular-cli/commit/37770d5)), closes [#1](https://github.com/devCrossNet/angular-cli/issues/1)
+* **version:** update version of [@angular](https://github.com/angular) packages. ([#3145](https://github.com/devCrossNet/angular-cli/issues/3145)) ([a2f0a1a](https://github.com/devCrossNet/angular-cli/commit/a2f0a1a))
### Features
-* **angular:** Update Angular2 version to 2.2.3 ([#3295](https://github.com/angular/angular-cli/issues/3295)) ([ed305a2](https://github.com/angular/angular-cli/commit/ed305a2))
-* **build:** add --verbose and --progress flags ([#2858](https://github.com/angular/angular-cli/issues/2858)) ([f6f24e7](https://github.com/angular/angular-cli/commit/f6f24e7)), closes [#1836](https://github.com/angular/angular-cli/issues/1836) [#2012](https://github.com/angular/angular-cli/issues/2012)
-* **build:** auto generate vendor chunk ([#3117](https://github.com/angular/angular-cli/issues/3117)) ([bf9c8f1](https://github.com/angular/angular-cli/commit/bf9c8f1))
-* **new:** include routing in spec and inline template when called with `--routing` ([#3252](https://github.com/angular/angular-cli/issues/3252)) ([53ab4df](https://github.com/angular/angular-cli/commit/53ab4df))
-* **serve:** add --hmr flag for HotModuleReplacement support ([#3330](https://github.com/angular/angular-cli/issues/3330)) ([46efa9e](https://github.com/angular/angular-cli/commit/46efa9e))
-
-
-### BREAKING CHANGES
-
-* build: `ng build/serve` now generates `vendor.bundle.js` by
-default.
-
-
+* **build:** add sourcemap option ([#3113](https://github.com/devCrossNet/angular-cli/issues/3113)) ([6f9d2c1](https://github.com/devCrossNet/angular-cli/commit/6f9d2c1))
+* **serve:** allow CORS access while running ung serve ([#2872](https://github.com/devCrossNet/angular-cli/issues/2872)) ([#3009](https://github.com/devCrossNet/angular-cli/issues/3009)) ([7c834a8](https://github.com/devCrossNet/angular-cli/commit/7c834a8))
+* **universal:** add custom webpack config ([cdfe1a0](https://github.com/devCrossNet/angular-cli/commit/cdfe1a0))
+* **universal:** Server routes ([5275ae2](https://github.com/devCrossNet/angular-cli/commit/5275ae2))
-
-# [1.0.0-beta.21](https://github.com/angular/angular-cli/compare/v1.0.0-beta.20-1...v1.0.0-beta.21) (2016-11-23)
+### Performance Improvements
-### Bug Fixes
+* **universal:** add compression express middleware ([#4](https://github.com/devCrossNet/angular-cli/issues/4)) ([61d3abf](https://github.com/devCrossNet/angular-cli/commit/61d3abf))
-* **angular-cli:** add necessary dependencies. ([#3152](https://github.com/angular/angular-cli/issues/3152)) ([8f574e4](https://github.com/angular/angular-cli/commit/8f574e4)), closes [#3148](https://github.com/angular/angular-cli/issues/3148)
-* **angular-cli:** add necessary dependency. ([f7704b0](https://github.com/angular/angular-cli/commit/f7704b0))
-* **angular-cli:** change version of webpack plugin. ([07e96ea](https://github.com/angular/angular-cli/commit/07e96ea))
-* **aot:** lock the angular version to 2.2.1. ([#3242](https://github.com/angular/angular-cli/issues/3242)) ([6e8a848](https://github.com/angular/angular-cli/commit/6e8a848))
-* **editorconfig:** use off instead of 0 for max line length ([#3186](https://github.com/angular/angular-cli/issues/3186)) ([f833d25](https://github.com/angular/angular-cli/commit/f833d25))
-* **generate:** revert change to component dir in generate module, as it caused component declaration to go to parent module ([#3158](https://github.com/angular/angular-cli/issues/3158)) ([71bf855](https://github.com/angular/angular-cli/commit/71bf855))
-* **github-pages-deploy:** Show more accurate url ([#3160](https://github.com/angular/angular-cli/issues/3160)) ([a431389](https://github.com/angular/angular-cli/commit/a431389))
-### Features
-
-* **build:** add sourcemap option ([#3113](https://github.com/angular/angular-cli/issues/3113)) ([6f9d2c1](https://github.com/angular/angular-cli/commit/6f9d2c1))
+### BREAKING CHANGES
+* binary `ng` renamed to `ung`
-
-# [1.0.0-beta.20](https://github.com/angular/angular-cli/compare/v1.0.0-beta.19...v1.0.0-beta.20-1) (2016-11-16)
+
+# [1.0.0-alpha.universal.1](https://github.com/devCrossNet/angular-cli/compare/v1.0.0-beta.19...v1.0.0-alpha.universal.1) (2016-11-08)
### Bug Fixes
-* **@ngtools/webpack:** fixed relative path for AoT. ([#3114](https://github.com/angular/angular-cli/issues/3114)) ([27a034d](https://github.com/angular/angular-cli/commit/27a034d))
-* **aot:** exclude spec files from aot ([#2758](https://github.com/angular/angular-cli/issues/2758)) ([215e555](https://github.com/angular/angular-cli/commit/215e555))
-* **aot:** output the sources in the sourcemap. ([#3107](https://github.com/angular/angular-cli/issues/3107)) ([7127dba](https://github.com/angular/angular-cli/commit/7127dba))
-* **aot:** remove the genDir plugin option. ([0e91dfe](https://github.com/angular/angular-cli/commit/0e91dfe)), closes [#2849](https://github.com/angular/angular-cli/issues/2849) [#2876](https://github.com/angular/angular-cli/issues/2876)
-* **aot:** Use the proper path when statically analyzing lazy routes. ([#2992](https://github.com/angular/angular-cli/issues/2992)) ([88131a0](https://github.com/angular/angular-cli/commit/88131a0)), closes [#2452](https://github.com/angular/angular-cli/issues/2452) [#2735](https://github.com/angular/angular-cli/issues/2735) [#2900](https://github.com/angular/angular-cli/issues/2900)
-* **build:** correct forkChecker option for ATS. ([#3011](https://github.com/angular/angular-cli/issues/3011)) ([a987cf5](https://github.com/angular/angular-cli/commit/a987cf5))
-* **build:** enable chunkhash in inline.js ([30cc482](https://github.com/angular/angular-cli/commit/30cc482)), closes [#2899](https://github.com/angular/angular-cli/issues/2899)
-* **build:** show full error stats ([#2879](https://github.com/angular/angular-cli/issues/2879)) ([d59fa1f](https://github.com/angular/angular-cli/commit/d59fa1f))
-* **deps:** explicitely add portfinder ([#2831](https://github.com/angular/angular-cli/issues/2831)) ([2d8f162](https://github.com/angular/angular-cli/commit/2d8f162)), closes [#2755](https://github.com/angular/angular-cli/issues/2755) [#2769](https://github.com/angular/angular-cli/issues/2769)
-* **e2e:** fix broken test pipeline ([#2999](https://github.com/angular/angular-cli/issues/2999)) ([37a1225](https://github.com/angular/angular-cli/commit/37a1225))
-* **generate:** fix module component path if module is created in child folder ([#3066](https://github.com/angular/angular-cli/issues/3066)) ([38d5f2c](https://github.com/angular/angular-cli/commit/38d5f2c)), closes [#3063](https://github.com/angular/angular-cli/issues/3063)
-* **generate:** stop default browser error from ng new --routing ([a45a1f2](https://github.com/angular/angular-cli/commit/a45a1f2)), closes [#2794](https://github.com/angular/angular-cli/issues/2794)
-* **package:** add some more metadata to webpack package.json ([c2dbf88](https://github.com/angular/angular-cli/commit/c2dbf88)), closes [#2854](https://github.com/angular/angular-cli/issues/2854)
-* **serve:** added accept html headers option to webpack-dev-server ([#2990](https://github.com/angular/angular-cli/issues/2990)) ([86f2a1b](https://github.com/angular/angular-cli/commit/86f2a1b)), closes [#2989](https://github.com/angular/angular-cli/issues/2989)
-* **test:** catches module loading errors ([f09439c](https://github.com/angular/angular-cli/commit/f09439c)), closes [#2640](https://github.com/angular/angular-cli/issues/2640) [#2785](https://github.com/angular/angular-cli/issues/2785)
-* **version:** update version of [@angular](https://github.com/angular) packages. ([#3145](https://github.com/angular/angular-cli/issues/3145)) ([a2f0a1a](https://github.com/angular/angular-cli/commit/a2f0a1a))
-* bypass Watchman check ([#2846](https://github.com/angular/angular-cli/issues/2846)) ([9aa1099](https://github.com/angular/angular-cli/commit/9aa1099)), closes [#2791](https://github.com/angular/angular-cli/issues/2791)
+* **aot:** remove the genDir plugin option. ([0e91dfe](https://github.com/devCrossNet/angular-cli/commit/0e91dfe)), closes [#2849](https://github.com/devCrossNet/angular-cli/issues/2849) [#2876](https://github.com/devCrossNet/angular-cli/issues/2876)
+* **aot:** Use the proper path when statically analyzing lazy routes. ([#2992](https://github.com/devCrossNet/angular-cli/issues/2992)) ([88131a0](https://github.com/devCrossNet/angular-cli/commit/88131a0)), closes [#2452](https://github.com/devCrossNet/angular-cli/issues/2452) [#2735](https://github.com/devCrossNet/angular-cli/issues/2735) [#2900](https://github.com/devCrossNet/angular-cli/issues/2900)
+* **build:** correct forkChecker option for ATS. ([#3011](https://github.com/devCrossNet/angular-cli/issues/3011)) ([a987cf5](https://github.com/devCrossNet/angular-cli/commit/a987cf5))
+* **build:** enable chunkhash in inline.js ([30cc482](https://github.com/devCrossNet/angular-cli/commit/30cc482)), closes [#2899](https://github.com/devCrossNet/angular-cli/issues/2899)
+* **build:** show full error stats ([#2879](https://github.com/devCrossNet/angular-cli/issues/2879)) ([d59fa1f](https://github.com/devCrossNet/angular-cli/commit/d59fa1f))
+* **e2e:** fix broken test pipeline ([#2999](https://github.com/devCrossNet/angular-cli/issues/2999)) ([37a1225](https://github.com/devCrossNet/angular-cli/commit/37a1225))
+* **generate:** stop default browser error from ng new --routing ([a45a1f2](https://github.com/devCrossNet/angular-cli/commit/a45a1f2)), closes [#2794](https://github.com/devCrossNet/angular-cli/issues/2794)
+* **package:** add some more metadata to webpack package.json ([c2dbf88](https://github.com/devCrossNet/angular-cli/commit/c2dbf88)), closes [#2854](https://github.com/devCrossNet/angular-cli/issues/2854)
+* **serve:** added accept html headers option to webpack-dev-server ([#2990](https://github.com/devCrossNet/angular-cli/issues/2990)) ([86f2a1b](https://github.com/devCrossNet/angular-cli/commit/86f2a1b)), closes [#2989](https://github.com/devCrossNet/angular-cli/issues/2989)
+* **test:** catches module loading errors ([f09439c](https://github.com/devCrossNet/angular-cli/commit/f09439c)), closes [#2640](https://github.com/devCrossNet/angular-cli/issues/2640) [#2785](https://github.com/devCrossNet/angular-cli/issues/2785)
+* bypass Watchman check ([#2846](https://github.com/devCrossNet/angular-cli/issues/2846)) ([9aa1099](https://github.com/devCrossNet/angular-cli/commit/9aa1099)), closes [#2791](https://github.com/devCrossNet/angular-cli/issues/2791)
### Features
-* **build:** add loaders for fonts ([3497373](https://github.com/angular/angular-cli/commit/3497373)), closes [#1765](https://github.com/angular/angular-cli/issues/1765)
-* **build:** use appConfig.index to set output index file ([d3fd8b0](https://github.com/angular/angular-cli/commit/d3fd8b0)), closes [#2241](https://github.com/angular/angular-cli/issues/2241) [#2767](https://github.com/angular/angular-cli/issues/2767)
-* **build:** use static files for css ([a6415cc](https://github.com/angular/angular-cli/commit/a6415cc)), closes [#2148](https://github.com/angular/angular-cli/issues/2148) [#2020](https://github.com/angular/angular-cli/issues/2020) [#2826](https://github.com/angular/angular-cli/issues/2826) [#2646](https://github.com/angular/angular-cli/issues/2646)
-* **serve:** allow CORS access while running ng serve ([#2872](https://github.com/angular/angular-cli/issues/2872)) ([#3009](https://github.com/angular/angular-cli/issues/3009)) ([7c834a8](https://github.com/angular/angular-cli/commit/7c834a8))
+* **build:** add loaders for fonts ([3497373](https://github.com/devCrossNet/angular-cli/commit/3497373)), closes [#1765](https://github.com/devCrossNet/angular-cli/issues/1765)
+* **build:** use appConfig.index to set output index file ([d3fd8b0](https://github.com/devCrossNet/angular-cli/commit/d3fd8b0)), closes [#2241](https://github.com/devCrossNet/angular-cli/issues/2241) [#2767](https://github.com/devCrossNet/angular-cli/issues/2767)
+* **build:** use static files for css ([a6415cc](https://github.com/devCrossNet/angular-cli/commit/a6415cc)), closes [#2148](https://github.com/devCrossNet/angular-cli/issues/2148) [#2020](https://github.com/devCrossNet/angular-cli/issues/2020) [#2826](https://github.com/devCrossNet/angular-cli/issues/2826) [#2646](https://github.com/devCrossNet/angular-cli/issues/2646)
+* **universal:** add support for Angular Universal ([1ee46ed](https://github.com/devCrossNet/angular-cli/commit/1ee46ed))
### BREAKING CHANGES
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e43ebf41390e..821954cded05 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
-# Contributing to angular-cli
+# Contributing to universal-cli
-We would love for you to contribute to angular-cli and help make it even better
+We would love for you to contribute to universal-cli and help make it even better
than it is today! As a contributor, here are the guidelines we would like you
to follow:
@@ -18,7 +18,7 @@ Help us keep Angular open and inclusive. Please read and follow our [Code of Con
## Got a Question or Problem?
-If you have questions about how to *use* Angular CLI, please direct them to [StackOverflow][stackoverflow]. Please note that angular-cli is still in early developer preview, and the core team's capacity to answer usage questions is limited. We are also available on [Gitter][gitter].
+If you have questions about how to *use* Angular CLI, please direct them to [StackOverflow][stackoverflow]. Please note that universal-cli is still in early developer preview, and the core team's capacity to answer usage questions is limited. We are also available on [Gitter][gitter].
## Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
@@ -57,13 +57,13 @@ chances of your issue being dealt with quickly:
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)
-You can file new issues by providing the above information [here](https://github.com/angular/angular-cli/issues/new).
+You can file new issues by providing the above information [here](https://github.com/angular/universal-cli/issues/new).
### Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
-* Search [GitHub](https://github.com/angular/angular-cli/pulls) for an open or closed PR
+* Search [GitHub](https://github.com/angular/universal-cli/pulls) for an open or closed PR
that relates to your submission. You don't want to duplicate effort.
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without this.
@@ -92,7 +92,7 @@ Before you submit your Pull Request (PR) consider the following guidelines:
git push origin my-fix-branch
```
-* In GitHub, send a pull request to `angular-cli:master`.
+* In GitHub, send a pull request to `universal-cli:master`.
* If we suggest changes then:
* Make the required updates.
* Re-run the Angular CLI test suites for JS and Dart to ensure tests are still passing.
diff --git a/README.md b/README.md
index ea3c808061a8..68613766e806 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,14 @@
-## Angular-CLI
+# this project is no longer maintained!
+
+
+### Universal-CLI
+Universal-CLI is fork from Angular-CLI. It supports Angular Universal (with `--universal` flag after `ung new` or `ung init`), see [Support for server side rendering](#support-for-server-side-rendering) for detail.
+It is a separate package because the Core-CLI team is not able to maintain non-core functionality.
+
+I am looking for maintainers, please let me know if you're interested in supporting `universal-cli`.
+
+### Slack
+Feel free to ask questions related to Angular Universal and Universal-CLI at [angular-universal.slack.com](https://angular-universal.slack.com)
[](https://gitter.im/angular/angular-cli?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -13,10 +23,10 @@ Prototype of a CLI for Angular 2 applications based on the [ember-cli](http://ww
This project is very much still a work in progress.
-The CLI is now in beta.
-If you wish to collaborate while the project is still young, check out [our issue list](https://github.com/angular/angular-cli/issues).
+The CLI is now in alpha.
+If you wish to collaborate while the project is still young, check out [our issue list](https://github.com/devCrossNet/universal-cli/issues).
-Before submitting new issues, have a look at [issues marked with the `type: faq` label](https://github.com/angular/angular-cli/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3A%22type%3A%20faq%22%20).
+Before submitting new issues, have a look at [issues marked with the `type: faq` label](https://github.com/devCrossNet/universal-cli/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3A%22type%3A%20faq%22%20).
## Webpack update
@@ -24,7 +34,7 @@ We changed the build system between beta.10 and beta.14, from SystemJS to Webpac
And with it comes a lot of benefits.
To take advantage of these, your app built with the old beta will need to migrate.
-You can update your `beta.10` projects to `beta.14` by following [these instructions](https://github.com/angular/angular-cli/wiki/Upgrading-from-Beta.10-to-Beta.14).
+You can update your `beta.10` projects to `beta.14` by following [these instructions](https://github.com/devCrossNet/universal-cli/wiki/Upgrading-from-Beta.10-to-Beta.14).
## Prerequisites
@@ -48,71 +58,72 @@ with NPM 3 or higher.
* [Deploying the App via GitHub Pages](#deploying-the-app-via-github-pages)
* [Linting and formatting code](#linting-and-formatting-code)
* [Support for offline applications](#support-for-offline-applications)
+* [Support for server side rendering](#support-for-server-side-rendering)
* [Commands autocompletion](#commands-autocompletion)
* [Project assets](#project-assets)
* [Global styles](#global-styles)
* [CSS preprocessor integration](#css-preprocessor-integration)
* [3rd Party Library Installation](#3rd-party-library-installation)
* [Global Library Installation](#global-library-installation)
-* [Updating angular-cli](#updating-angular-cli)
-* [Development Hints for hacking on angular-cli](#development-hints-for-hacking-on-angular-cli)
+* [Updating universal-cli](#updating-universal-cli)
+* [Development Hints for hacking on universal-cli](#development-hints-for-hacking-on-universal-cli)
## Installation
**BEFORE YOU INSTALL:** please read the [prerequisites](#prerequisites)
```bash
-npm install -g angular-cli
+npm install -g universal-cli
```
## Usage
```bash
-ng help
+ung --help
```
### Generating and serving an Angular2 project via a development server
```bash
-ng new PROJECT_NAME
+ung new PROJECT_NAME
cd PROJECT_NAME
-ng serve
+ung serve
```
Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
You can configure the default HTTP port and the one used by the LiveReload server with two command-line options :
```bash
-ng serve --host 0.0.0.0 --port 4201 --live-reload-port 49153
+ung serve --host 0.0.0.0 --port 4201 --live-reload-port 49153
```
### Generating Components, Directives, Pipes and Services
-You can use the `ng generate` (or just `ng g`) command to generate Angular components:
+You can use the `ung generate` (or just `ung g`) command to generate Angular components:
```bash
-ng generate component my-new-component
-ng g component my-new-component # using the alias
+ung generate component my-new-component
+ung g component my-new-component # using the alias
# components support relative path generation
# if in the directory src/app/feature/ and you run
-ng g component new-cmp
+ung g component new-cmp
# your component will be generated in src/app/feature/new-cmp
# but if you were to run
-ng g component ../newer-cmp
+ung g component ../newer-cmp
# your component will be generated in src/app/newer-cmp
```
You can find all possible blueprints in the table below:
Scaffold | Usage
--- | ---
-Component | `ng g component my-new-component`
-Directive | `ng g directive my-new-directive`
-Pipe | `ng g pipe my-new-pipe`
-Service | `ng g service my-new-service`
-Class | `ng g class my-new-class`
-Interface | `ng g interface my-new-interface`
-Enum | `ng g enum my-new-enum`
-Module | `ng g module my-module`
+Component | `ung g component my-new-component`
+Directive | `ung g directive my-new-directive`
+Pipe | `ung g pipe my-new-pipe`
+Service | `ung g service my-new-service`
+Class | `ung g class my-new-class`
+Interface | `ung g interface my-new-interface`
+Enum | `ung g enum my-new-enum`
+Module | `ung g module my-module`
### Generating a route
@@ -123,14 +134,14 @@ You can read the official documentation for the new Router here: https://angular
### Creating a build
```bash
-ng build
+ung build
```
The build artifacts will be stored in the `dist/` directory.
### Build Targets and Environment Files
-`ng build` can specify both a build target (`--target=production` or `--target=development`) and an
+`ung build` can specify both a build target (`--target=production` or `--target=development`) and an
environment file to be used with that build (`--environment=dev` or `--environment=prod`).
By default, the development build target and environment are used.
@@ -149,14 +160,14 @@ it will default to `dev` for `development` and `prod` for `production`.
```bash
# these are equivalent
-ng build --target=production --environment=prod
-ng build --prod --env=prod
-ng build --prod
+ung build --target=production --environment=prod
+ung build --prod --env=prod
+ung build --prod
# and so are these
-ng build --target=development --environment=dev
-ng build --dev --e=dev
-ng build --dev
-ng build
+ung build --target=development --environment=dev
+ung build --dev --e=dev
+ung build --dev
+ung build
```
You can also add your own env files other than `dev` and `prod` by doing the following:
@@ -170,19 +181,19 @@ When building you can modify base tag (``) in your index.html wit
```bash
# Sets base tag href to /myUrl/ in your index.html
-ng build --base-href /myUrl/
-ng build --bh /myUrl/
+ung build --base-href /myUrl/
+ung build --bh /myUrl/
```
### Bundling
-All builds make use of bundling, and using the `--prod` flag in `ng build --prod`
-or `ng serve --prod` will also make use of uglifying and tree-shaking functionality.
+All builds make use of bundling, and using the `--prod` flag in `ung build --prod`
+or `ung serve --prod` will also make use of uglifying and tree-shaking functionality.
### Running unit tests
```bash
-ng test
+ung test
```
Tests will execute after a build is executed via [Karma](http://karma-runner.github.io/0.13/index.html), and it will automatically watch your files for changes. You can run tests a single time via `--watch=false` or `--single-run`.
@@ -194,10 +205,10 @@ Linting during tests is also available via the `--lint` flag. See [Linting and f
### Running end-to-end tests
```bash
-ng e2e
+ung e2e
```
-Before running the tests make sure you are serving the app via `ng serve`.
+Before running the tests make sure you are serving the app via `ung serve`.
End-to-end tests are run via [Protractor](https://angular.github.io/protractor/).
@@ -234,7 +245,7 @@ now run it with `npm start`
You can deploy your apps quickly via:
```bash
-ng github-pages:deploy --message "Optional commit message"
+ung github-pages:deploy --message "Optional commit message"
```
This will do the following:
@@ -254,7 +265,7 @@ To simplify the authentication, be sure to [setup your ssh keys](https://help.gi
If you are deploying a [user or organization page](https://help.github.com/articles/user-organization-and-project-pages/), you can instead use the following command:
```bash
-ng github-pages:deploy --user-page --message "Optional commit message"
+ung github-pages:deploy --user-page --message "Optional commit message"
```
This command pushes the app to the `master` branch on the github repo instead
@@ -263,7 +274,7 @@ of pushing to `gh-pages`, since user and organization pages require this.
### Linting and formatting code
-You can lint your app code by running `ng lint`.
+You can lint your app code by running `ung lint`.
This will use the `lint` npm script that in generated projects uses `tslint`.
You can modify the these scripts in `package.json` to run whatever tool you prefer.
@@ -272,7 +283,21 @@ You can modify the these scripts in `package.json` to run whatever tool you pref
**The `--mobile` flag has been disabled temporarily. Sorry for the inconvenience.**
-~~Angular-CLI includes support for offline applications via the `--` flag on `ng new`. Support is experimental, please see the angular/mobile-toolkit project and https://mobile.angular.io/ for documentation on how to make use of this functionality.~~
+~~Angular-CLI includes support for offline applications via the `--mobile` flag on `ung new`. Support is experimental,
+please see the angular/mobile-toolkit project and https://mobile.angular.io/ for documentation on how to make use of this functionality.~~
+
+### Support for server side rendering
+
+**Universal-CLI includes Angular Universal via the `--universal` flag on `ung new` and `ung init`.**
+
+**Angular Universal** helps you to seo optimize your application and offers a better user experience through server side rendering.
+Please see the **angular/universal** project and https://universal.angular.io/ for documentation on how to make use of this functionality.
+
+#### Update an existing Project
+
+`cd path/to/project` and init your project with the universal option `ung init --universal`. Take every Pipe, Directive, Component, Module and Routes from `./src/app/app.module.ts`
+and move them to `./src/app/app.browser.module.ts` and `./src/app/app.node.module.ts`. Try `ung serve`, if your application looks like before, then you can delete the files
+`./src/app/app.module.ts` and `./src/main.ts`. **Have fun with Angular Universal!**
### Commands autocompletion
@@ -280,19 +305,19 @@ To turn on auto completion use the following commands:
For bash:
```bash
-ng completion 1>> ~/.bashrc 2>>&1
+ung completion 1>> ~/.bashrc 2>>&1
source ~/.bashrc
```
For zsh:
```bash
-ng completion 1>> ~/.zshrc 2>>&1
+ung completion 1>> ~/.zshrc 2>>&1
source ~/.zshrc
```
Windows users using gitbash:
```bash
-ng completion 1>> ~/.bash_profile 2>>&1
+ung completion 1>> ~/.bash_profile 2>>&1
source ~/.bash_profile
```
@@ -318,7 +343,7 @@ You can add more global styles via the `apps[0].styles` property in `angular-cli
### CSS Preprocessor integration
-Angular-CLI supports all major CSS preprocessors:
+Universal-CLI supports all major CSS preprocessors:
- sass/scss ([http://sass-lang.com/](http://sass-lang.com/))
- less ([http://lesscss.org/](http://lesscss.org/))
- stylus ([http://stylus-lang.com/](http://stylus-lang.com/))
@@ -340,13 +365,13 @@ When generating a new project you can also define which extension you want for
style files:
```bash
-ng new sassy-project --style=sass
+ung new sassy-project --style=sass
```
Or set the default style on an existing project:
```bash
-ng set defaults.styleExt scss
+ung set defaults.styleExt scss
```
### 3rd Party Library Installation
@@ -413,68 +438,68 @@ Finally add the Bootstrap CSS to the `apps[0].styles` array:
],
```
-Restart `ng serve` if you're running it, and Bootstrap 4 should be working on
+Restart `ung serve` if you're running it, and Bootstrap 4 should be working on
your app.
-### Updating angular-cli
+### Updating universal-cli
-To update `angular-cli` to a new version, you must update both the global package and your project's local package.
+To update `universal-cli` to a new version, you must update both the global package and your project's local package.
Global package:
```bash
-npm uninstall -g angular-cli
+npm uninstall -g universal-cli
npm cache clean
-npm install -g angular-cli@latest
+npm install -g universal-cli
```
Local project package:
```bash
rm -rf node_modules dist tmp
-npm install --save-dev angular-cli@latest
+npm install --save-dev universal-cli
npm install
-ng init
+ung init
```
-Running `ng init` will check for changes in all the auto-generated files created by `ng new` and allow you to update yours. You are offered four choices for each changed file: `y` (overwrite), `n` (don't overwrite), `d` (show diff between your file and the updated file) and `h` (help).
+Running `ung init` will check for changes in all the auto-generated files created by `ung new` and allow you to update yours. You are offered four choices for each changed file: `y` (overwrite), `n` (don't overwrite), `d` (show diff between your file and the updated file) and `h` (help).
-Carefully read the diffs for each code file, and either accept the changes or incorporate them manually after `ng init` finishes.
+Carefully read the diffs for each code file, and either accept the changes or incorporate them manually after `ung init` finishes.
**The main cause of errors after an update is failing to incorporate these updates into your code**.
-You can find more details about changes between versions in [CHANGELOG.md](https://github.com/angular/angular-cli/blob/master/CHANGELOG.md).
+You can find more details about changes between versions in [CHANGELOG.md](https://github.com/devCrossNet/universal-cli/blob/master/CHANGELOG.md).
-## Development Hints for hacking on angular-cli
+## Development Hints for hacking on universal-cli
### Working with master
```bash
-git clone https://github.com/angular/angular-cli.git
-cd angular-cli
+git clone https://github.com/devCrossNet/universal-cli.git
+cd universal-cli
npm link
```
`npm link` is very similar to `npm install -g` except that instead of downloading the package
-from the repo, the just cloned `angular-cli/` folder becomes the global package.
-Any changes to the files in the `angular-cli/` folder will immediately affect the global `angular-cli` package,
+from the repo, the just cloned `universal-cli/` folder becomes the global package.
+Any changes to the files in the `universal-cli/` folder will immediately affect the global `universal-cli` package,
allowing you to quickly test any changes you make to the cli project.
-Now you can use `angular-cli` via the command line:
+Now you can use `universal-cli` via the command line:
```bash
-ng new foo
+ung new foo
cd foo
-npm link angular-cli
-ng serve
+npm link universal-cli
+ung serve
```
-`npm link angular-cli` is needed because by default the globally installed `angular-cli` just loads
-the local `angular-cli` from the project which was fetched remotely from npm.
-`npm link angular-cli` symlinks the global `angular-cli` package to the local `angular-cli` package.
-Now the `angular-cli` you cloned before is in three places:
-The folder you cloned it into, npm's folder where it stores global packages and the `angular-cli` project you just created.
+`npm link universal-cli` is needed because by default the globally installed `universal-cli` just loads
+the local `universal-cli` from the project which was fetched remotely from npm.
+`npm link universal-cli` symlinks the global `universal-cli` package to the local `universal-cli` package.
+Now the `universal-cli` you cloned before is in three places:
+The folder you cloned it into, npm's folder where it stores global packages and the `universal-cli` project you just created.
-You can also use `ng new foo --link-cli` to automatically link the `angular-cli` package.
+You can also use `ung new foo --link-cli` to automatically link the `universal-cli` package.
Please read the official [npm-link documentation](https://www.npmjs.org/doc/cli/npm-link.html)
and the [npm-link cheatsheet](http://browsenpm.org/help#linkinganynpmpackagelocally) for more information.
@@ -485,11 +510,11 @@ and the [npm-link cheatsheet](http://browsenpm.org/help#linkinganynpmpackageloca
MIT
-[travis-badge]: https://travis-ci.org/angular/angular-cli.svg?branch=master
-[travis-badge-url]: https://travis-ci.org/angular/angular-cli
-[david-badge]: https://david-dm.org/angular/angular-cli.svg
-[david-badge-url]: https://david-dm.org/angular/angular-cli
-[david-dev-badge]: https://david-dm.org/angular/angular-cli/dev-status.svg
-[david-dev-badge-url]: https://david-dm.org/angular/angular-cli?type=dev
-[npm-badge]: https://img.shields.io/npm/v/angular-cli.svg
-[npm-badge-url]: https://www.npmjs.com/package/angular-cli
+[travis-badge]: https://travis-ci.org/devCrossNet/universal-cli.svg?branch=master
+[travis-badge-url]: https://travis-ci.org/devCrossNet/universal-cli
+[david-badge]: https://david-dm.org/devCrossNet/universal-cli.svg
+[david-badge-url]: https://david-dm.org/devCrossNet/universal-cli
+[david-dev-badge]: https://david-dm.org/devCrossNet/universal-cli/dev-status.svg
+[david-dev-badge-url]: https://david-dm.org/devCrossNet/universal-cli?type=dev
+[npm-badge]: https://img.shields.io/npm/v/universal-cli.svg
+[npm-badge-url]: https://www.npmjs.com/package/universal-cli
diff --git a/bin/ng b/bin/ung
similarity index 58%
rename from bin/ng
rename to bin/ung
index 5e770a2caa95..4b117b0385ba 100755
--- a/bin/ng
+++ b/bin/ung
@@ -2,7 +2,7 @@
'use strict';
// Provide a title to the process in `ps`
-process.title = 'angular-cli';
+process.title = 'universal-cli';
require('../lib/bootstrap-local');
-require('../packages/angular-cli/bin/ng');
+require('../packages/universal-cli/bin/ung');
diff --git a/docs/design/docker-deploy.md b/docs/design/docker-deploy.md
index 256368594ab0..06835e87f121 100644
--- a/docs/design/docker-deploy.md
+++ b/docs/design/docker-deploy.md
@@ -15,11 +15,11 @@ Provide tasks for common Docker workflows:
1. Requires user to have Docker CLI tools installed.
(See also: ["Implementation Approaches"](#implementation-approaches))
-1. User is free to use the Angular CLI without Docker (and vice versa). By default, do not generate Docker files upon creation of a new project (`ng new`, `ng init`).
+1. User is free to use the Angular CLI without Docker (and vice versa). By default, do not generate Docker files upon creation of a new project (`ung new`, `ung init`).
1. Don't recreate the wheel. Docker CLI tools are very full featured on their own. Implement the common Docker use cases that make it convenient for Angular applications.
1. Don't inhibit users from using the standalone Docker CLI tools for other use cases.
1. Assumes 1:1 Dockerfile with the Angular project. Support for multiple services under the same project is outside the scope of this initial design.
-1. Generated starter Dockerfile will use an Nginx base image for the default server. The built ng app and Nginx configuration for HTML5 Fallback will be copied into the image.
+1. Generated starter Dockerfile will use an Nginx base image for the default server. The built ung app and Nginx configuration for HTML5 Fallback will be copied into the image.
1. User is free to modify and customize all generated files directly without involvement by the Angular CLI.
1. Image builds will support all Docker build options.
1. Container deploys will support all Docker run options.
@@ -37,22 +37,22 @@ Provide tasks for common Docker workflows:
Initialize the project for Docker builds and deploys:
```
-$ ng docker init [--environment env]
+$ ung docker init [--environment env]
```
Build and push a Docker image of the Angular app to the registry:
```
-$ ng docker push [--registry url]
+$ ung docker push [--registry url]
```
Deploy and run the Angular app on a Docker Machine:
```
-$ ng docker deploy [--environment env]
+$ ung docker deploy [--environment env]
```
### Command - Docker Init
-The command `ng docker init` generates starter `Dockerfile`, `.dockerignore`, and `docker-compose.yml` files for builds and and deploys.
+The command `ung docker init` generates starter `Dockerfile`, `.dockerignore`, and `docker-compose.yml` files for builds and and deploys.
Most users will start with one local 'default' Docker Machine (Mac/Win), or a local native Docker environment on Linux, where they will perform builds and run containers for development testing. Without additional arguments, this command prepares the Angular project for working with that default environment.
@@ -70,7 +70,7 @@ Most users will start with one local 'default' Docker Machine (Mac/Win), or a lo
**Example - Init default environment:**
```bash
-$ ng docker:init --image-org my-username
+$ ung docker:init --image-org my-username
Generated 'Dockerfile'
Generated '.dockerignore'
@@ -79,10 +79,10 @@ Generated 'docker-compose.yml'
Docker is ready!
You can build and push a Docker image of your application to a docker registry using:
- $ ng docker push
+ $ ung docker push
Build and run your application using:
- $ ng docker deploy
+ $ ung docker deploy
```
**Other requirements:**
@@ -153,16 +153,16 @@ services:
The `\${NG_APP_IMAGE}` is a Compose variable, not an Angilar CLI var. It will be substituted during a `docker deploy` command with an environment variable of the desired tag. (See [Compose Variable Substitution](https://docs.docker.com/compose/compose-file/#variable-substitution) for more info)
-Separate `docker-compose-{environment}.yml` files are used to deploy to different [environments](https://docs.docker.com/compose/extends/#example-use-case), for use with the `ng docker deploy` command.
+Separate `docker-compose-{environment}.yml` files are used to deploy to different [environments](https://docs.docker.com/compose/extends/#example-use-case), for use with the `ung docker deploy` command.
### Command - Docker Push
-The command `ng docker push` builds a Docker image of the Angular app from the `Dockerfile`, and pushes the image with a new tag to a registry address.
+The command `ung docker push` builds a Docker image of the Angular app from the `Dockerfile`, and pushes the image with a new tag to a registry address.
Example - Build and push (with auth):
```bash
-$ ng docker push --tag 1.0.0 --tag-latest
+$ ung docker push --tag 1.0.0 --tag-latest
Building image...
Tagging "1.0.0"...
Tagging "latest"
@@ -194,7 +194,7 @@ The `--no-cache`, `--force-rm`, and `--pull` are [compose build options](https:/
Try an initial push. If an authentication failure occurs, attempt to login via `docker login`, or with `aws ecr get-login` (if the registry address matches `/\.dkr\.ecr\./`). Proxy the CLI input to the login commands. Avoid storing any authentication values in ngConfig.
-The `serviceName`, `registryAddress`, `orgName`, and `imageName` defaults will first be retrieved from ngConfig, which were saved during the initial `ng docker init` command. If any of these values do not exist, warn the user with instructions to add via `ng docker init` or `ng set name=value`.
+The `serviceName`, `registryAddress`, `orgName`, and `imageName` defaults will first be retrieved from ngConfig, which were saved during the initial `ung docker init` command. If any of these values do not exist, warn the user with instructions to add via `ung docker init` or `ung set name=value`.
#### Internal Steps
@@ -210,13 +210,13 @@ The `serviceName`, `registryAddress`, `orgName`, and `imageName` defaults will f
### Command - Docker Deploy
-The command `ng docker deploy` will deploy an environment's compose configuration to a Docker Machine. It starts the containers in the background and leaves them running.
+The command `ung docker deploy` will deploy an environment's compose configuration to a Docker Machine. It starts the containers in the background and leaves them running.
-Consider a command alias: `ng docker run`.
+Consider a command alias: `ung docker run`.
Example - Default environment deploy:
```bash
-$ ng docker deploy
+$ ung docker deploy
Building...
Deploying to default environment...
Deploy complete!
@@ -224,13 +224,13 @@ Deploy complete!
Example - Deploying to a named environment, without builds:
```bash
-$ ng docker:deploy --environment stage
-$ ng docker:deploy --environment prod --tag 1.0.1
+$ ung docker:deploy --environment stage
+$ ung docker:deploy --environment prod --tag 1.0.1
```
Example - Deploying a specific service from the compose file:
```bash
-$ ng docker deploy --services my-ng-app
+$ ung docker deploy --services my-ng-app
```
#### Options
@@ -299,7 +299,7 @@ Example ngConfig model for saved docker command state (per project):
## Other Enhancements
* Ability to list the configured deploy environments.
-* Autocomplete environment names for `ng docker deploy`.
+* Autocomplete environment names for `ung docker deploy`.
* New command wrappers for `docker-compose logs`, and `docker exec` commands.
* Create an Angular development environment image with everything packaged inside. Users can run the container with local volume mounts, and toolset will watch/rebuild for local file changes. Only requires Docker to be installed to get started with Angular development. There are some Node.js complexities to solve when adding new package.json dependencies, and many users report issues with file watchers and docker volume mounts.
* Deployment support to other container scheduling systems: Kubernetes, Marathon/Mesos, AWS ECS and Beanstalk, Azure Service Fabric, etc.
diff --git a/docs/design/third-party-libraries.md b/docs/design/third-party-libraries.md
index ac0a22c458e1..254867668e40 100644
--- a/docs/design/third-party-libraries.md
+++ b/docs/design/third-party-libraries.md
@@ -2,12 +2,12 @@
# Abstract
-The current `ng install` process is faulty; third parties have to add a `bundles/` directory
+The current `ung install` process is faulty; third parties have to add a `bundles/` directory
with metadata that we expect. This document explores ways to improve on the process.
# Requirements
-The following use cases need to be supported by `ng install`:
+The following use cases need to be supported by `ung install`:
1. Support for _any_ thirdparties, ultimately falling back to running `npm install` only and
doing nothing else, if necessary.
@@ -31,29 +31,29 @@ to proper map the imports and move them to `tmp` before compiling, then to `dist
Here's a few stories that should work right off:
```sh
-$ ng new my-app && cd my-app/
-$ ng install jquery
+$ ung new my-app && cd my-app/
+$ ung install jquery
```
^(this makes jQuery available in the index)
```sh
-$ ng install angularfire2
+$ ung install angularfire2
> Please specify your Firebase database URL [my-app.firebaseio.com]: _
```
^(makes firebase available and provided to the App)
```sh
-$ ng install angularfire2 --dbUrl=my-firebase-db.example.com
+$ ung install angularfire2 --dbUrl=my-firebase-db.example.com
```
^(skip prompts for values passed on the command line)
```sh
-$ ng install angularfire2 --quiet
+$ ung install angularfire2 --quiet
```
^(using `--quiet` to skip all prompts and use default values)
```sh
-$ ng install less
+$ ung install less
```
^(now compiles CSS files with less for the appropriate extensions)
@@ -75,7 +75,7 @@ The `install` task will perform the following subtasks:
1. **Run `package["angular-cli"].scripts["install"]` if it exists.** If the script fails,
run `npm uninstall ${libName}` and fail the install process.
1. **Detect if a package named `angular/cli-wrapper-${libName}` exist in the angular
- organization.** If so, run the steps above as if ng install angular/angular-${libName}. If
+ organization.** If so, run the steps above as if ung install angular/angular-${libName}. If
this install fails, ignore the failure.
These packages can be used to wrap libraries that we want to support but can't update
@@ -151,13 +151,13 @@ needs to exist for toolings to be able to understand dependencies. These provide
to the application.
In order to blacklist providers from being global, the user can use the `--no-global-providers`
-flag during installation, or can change the dependencies by using `ng providers`. As an example:
+flag during installation, or can change the dependencies by using `ung providers`. As an example:
```bash
-ng new my-todo-app
-ng generate component database
-ng install --no-global-providers angularfirebase2
-ng providers database angularfirebase2
+ung new my-todo-app
+ung generate component database
+ung install --no-global-providers angularfirebase2
+ung providers database angularfirebase2
```
Or, alternatively, the user can add its own providers and dependencies to its components.
@@ -186,7 +186,7 @@ to leave the liberty to the user to change the SystemJS configuration so that it
We will not use SystemJS bundles in development. This is for better debugging, future proofing
(when moving the build system) and better CDN support, as many of the loaded files will end up
-being pulled from a CDN in production. During the `ng build` process for production, the
+being pulled from a CDN in production. During the `ung build` process for production, the
SystemJS configuration script will be rebuilt to fetch from the CDN.
# Upgrade Strategy
diff --git a/docs/publish.md b/docs/publish.md
new file mode 100644
index 000000000000..70a76656624e
--- /dev/null
+++ b/docs/publish.md
@@ -0,0 +1,16 @@
+#Change versions
+- There is a main `package.json` which should keep with the latest universal-cli version (e.g. `1.0.0-beta.17`).
+- There is one `package.json` per packages. Update the version of every packages independently.
+- Run the CHANGELOG script.
+ - `node ./scripts/publish/changelog.js OLD_VERSION_TAG`
+ - (for example, `v1.0.0-beta.17`)
+- Create a commit. The commit message should be only the version number starting with a v.
+- Create a tag. The tag should be only the version number starting with a v.
+- Push to upstream with tags.
+ - `git push master`
+ - `git push --tags`
+- Publish to npm
+ - `npm run build`
+ - `cd ./dist/universal-cli`
+ - `npm publish --tag experimental` (install it with `npm install -g universal-cli@experimental` and test it)
+ - `npm publish` (the new version is now available at npm)
\ No newline at end of file
diff --git a/lib/bootstrap-local.js b/lib/bootstrap-local.js
index 802e55ebae0e..a7cf31a48b4b 100644
--- a/lib/bootstrap-local.js
+++ b/lib/bootstrap-local.js
@@ -15,8 +15,8 @@ const oldRequireTs = require.extensions['.ts'];
require.extensions['.ts'] = function(m, filename) {
// If we're in node module, either call the old hook or simply compile the
// file without transpilation. We do not touch node_modules/**.
- // We do touch `angular-cli` files anywhere though.
- if (!filename.match(/angular-cli/) && filename.match(/node_modules/)) {
+ // We do touch `universal-cli` files anywhere though.
+ if (!filename.match(/universal-cli/) && filename.match(/node_modules/)) {
if (oldRequireTs) {
return oldRequireTs(m, filename);
}
@@ -54,9 +54,9 @@ if (!__dirname.match(new RegExp(`\\${path.sep}node_modules\\${path.sep}`))) {
Module._load = function (request, parent) {
if (request in packages) {
return oldLoad.call(this, packages[request].main, parent);
- } else if (request.startsWith('angular-cli/')) {
+ } else if (request.startsWith('universal-cli/')) {
// We allow deep imports (for now).
- // TODO: move tests to inside angular-cli package so they don't have to deep import.
+ // TODO: move tests to inside universal-cli package so they don't have to deep import.
const dir = path.dirname(parent.filename);
const newRequest = path.relative(dir, path.join(__dirname, '../packages', request));
return oldLoad.call(this, newRequest, parent);
diff --git a/package.json b/package.json
index f0b96e758815..fb4d227cd72e 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
- "name": "angular-cli",
- "version": "1.0.0-beta.23",
- "description": "CLI tool for Angular",
- "main": "packages/angular-cli/lib/cli/index.js",
- "trackingCode": "UA-8594346-19",
+ "name": "universal-cli",
+ "version": "1.0.0-alpha.universal.3",
+ "description": "CLI tool for Angular with Angular Universal support",
+ "main": "packages/universal-cli/lib/cli/index.js",
+ "trackingCode": "xx-xxxxxxx-xx",
"bin": {
- "ng": "./bin/ng"
+ "ung": "./bin/ung"
},
"keywords": [],
"scripts": {
@@ -21,31 +21,37 @@
"test:deps": "node scripts/publish/validate_dependencies.js",
"test:inspect": "node --inspect --debug-brk tests/runner",
"test:packages": "node scripts/run-packages-spec.js",
- "build-config-interface": "dtsgen packages/angular-cli/lib/config/schema.json --out packages/angular-cli/lib/config/schema.d.ts",
+ "test:universal": "UNIVERSAL=true node tests/e2e_runner.js",
+ "build-config-interface": "dtsgen packages/universal-cli/lib/config/schema.json --out packages/universal-cli/lib/config/schema.d.ts",
"eslint": "eslint .",
"tslint": "tslint \"**/*.ts\" -c tslint.json -e \"**/blueprints/*/files/**/*.ts\" -e \"node_modules/**\" -e \"tmp/**\" -e \"dist/**\"",
"lint": "npm-run-all -c eslint tslint"
},
"repository": {
"type": "git",
- "url": "https://github.com/angular/angular-cli.git"
+ "url": "https://github.com/devCrossNet/universal-cli.git"
},
"engines": {
"node": ">= 4.1.0",
"npm": ">= 3.0.0"
},
"author": "Angular Authors",
+ "contributors": [
+ "Rody Haddad (http://rodyhaddad.com/)",
+ "Igor Minar ",
+ "Johannes Werner "
+ ],
"license": "MIT",
"bugs": {
- "url": "https://github.com/angular/angular-cli/issues"
+ "url": "https://github.com/devCrossNet/universal-cli/issues"
},
- "homepage": "https://github.com/angular/angular-cli",
+ "homepage": "https://github.com/devCrossNet/universal-cli",
"dependencies": {
- "@angular-cli/ast-tools": "^1.0.0",
- "@angular/compiler": "~2.3.1",
- "@angular/compiler-cli": "~2.3.1",
- "@angular/core": "~2.3.1",
- "@angular/tsc-wrapped": "~0.5.0",
+ "@angular-cli/ast-tools": "1.0.10",
+ "@angular/compiler": "2.2.3",
+ "@angular/compiler-cli": "2.2.3",
+ "@angular/core": "2.2.3",
+ "@angular/tsc-wrapped": "0.4.0",
"async": "^2.1.4",
"autoprefixer": "^6.5.3",
"chalk": "^1.1.3",
@@ -60,7 +66,7 @@
"ember-cli-string-utils": "^1.0.0",
"enhanced-resolve": "^2.3.0",
"exists-sync": "0.0.3",
- "extract-text-webpack-plugin": "^2.0.0-beta.4",
+ "extract-text-webpack-plugin": "2.0.0-beta.4",
"file-loader": "^0.8.5",
"findup": "0.1.5",
"fs-extra": "^0.30.0",
@@ -85,8 +91,9 @@
"markdown-it-terminal": "0.0.3",
"minimatch": "^3.0.3",
"node-modules-path": "^1.0.0",
- "node-sass": "^3.10.1",
+ "node-sass": "^4.1.1",
"nopt": "^3.0.1",
+ "nodemon": "^1.11.0",
"offline-plugin": "^3.4.1",
"opn": "4.0.1",
"ora": "^0.2.0",
@@ -101,17 +108,19 @@
"resolve": "^1.1.7",
"rimraf": "^2.5.3",
"rsvp": "^3.0.17",
- "rxjs": "5.0.0-rc.4",
- "sass-loader": "^4.0.1",
+ "rxjs": "5.0.0-beta.12",
+ "sass-loader": "^4.1.1",
"script-loader": "^0.7.0",
"semver": "^5.1.0",
"silent-error": "^1.0.0",
"source-map": "^0.5.6",
"source-map-loader": "^0.1.5",
"sourcemap-istanbul-instrumenter-loader": "^0.2.0",
+ "string-replace-webpack-plugin": "0.0.4",
"style-loader": "^0.13.1",
"stylus": "^0.54.5",
"stylus-loader": "^2.1.0",
+ "tiny-lr": "^0.2.1",
"temp": "0.8.3",
"through": "^2.3.6",
"tslint": "^4.0.2",
@@ -129,7 +138,7 @@
},
"ember-addon": {
"paths": [
- "./packages/angular-cli/lib/addon"
+ "./packages/universal-cli/lib/addon"
]
},
"devDependencies": {
@@ -140,8 +149,8 @@
"@types/express": "^4.0.32",
"@types/fs-extra": "^0.0.31",
"@types/glob": "^5.0.29",
- "@types/jasmine": "^2.2.32",
- "@types/lodash": "^4.14.43",
+ "@types/jasmine": "2.5.41",
+ "@types/lodash": "4.14.50",
"@types/mock-fs": "3.6.28",
"@types/node": "^6.0.36",
"@types/request": "0.0.30",
diff --git a/packages/@angular-cli/ast-tools/package.json b/packages/@angular-cli/ast-tools/package.json
index dd2c6366c0de..555f792bc9f3 100644
--- a/packages/@angular-cli/ast-tools/package.json
+++ b/packages/@angular-cli/ast-tools/package.json
@@ -24,8 +24,8 @@
"npm": ">= 3.0.0"
},
"dependencies": {
- "@angular/tsc-wrapped": "^0.3.0",
- "rxjs": "5.0.0-rc.4",
+ "@angular/tsc-wrapped": "0.4.0",
+ "rxjs": "5.0.0-beta.12",
"denodeify": "^1.2.1",
"typescript": "~2.0.3"
}
diff --git a/packages/@angular-cli/ast-tools/src/change.spec.ts b/packages/@angular-cli/ast-tools/src/change.spec.ts
index 1a3cc1833bcf..bc3c494cf9ba 100644
--- a/packages/@angular-cli/ast-tools/src/change.spec.ts
+++ b/packages/@angular-cli/ast-tools/src/change.spec.ts
@@ -8,7 +8,7 @@ import {InsertChange, NodeHost, RemoveChange, ReplaceChange} from './change';
import fs = require('fs');
let path = require('path');
-let Promise = require('angular-cli/ember-cli/lib/ext/promise');
+let Promise = require('universal-cli/ember-cli/lib/ext/promise');
const readFile = Promise.denodeify(fs.readFile);
diff --git a/packages/@ngtools/webpack/package.json b/packages/@ngtools/webpack/package.json
index 0b3047807fe2..865b2a9863bb 100644
--- a/packages/@ngtools/webpack/package.json
+++ b/packages/@ngtools/webpack/package.json
@@ -1,6 +1,6 @@
{
"name": "@ngtools/webpack",
- "version": "1.2.0",
+ "version": "1.1.9",
"description": "Webpack plugin that AoT compiles your Angular components and modules.",
"main": "./src/index.js",
"typings": "src/index.d.ts",
@@ -31,10 +31,10 @@
"source-map": "^0.5.6"
},
"peerDependencies": {
- "@angular/compiler": "~2.3.1",
- "@angular/compiler-cli": "~2.3.1",
- "@angular/core": "~2.3.1",
- "@angular/tsc-wrapped": "~0.5.0",
+ "@angular/compiler": "2.2.3",
+ "@angular/compiler-cli": "2.2.3",
+ "@angular/core": "2.2.3",
+ "@angular/tsc-wrapped": "0.4.0",
"typescript": "^2.0.2",
"reflect-metadata": "^0.1.8",
"webpack": "^2.1.0-beta.25"
diff --git a/packages/@ngtools/webpack/src/loader.ts b/packages/@ngtools/webpack/src/loader.ts
index b176e558202c..8b51282cd8e0 100644
--- a/packages/@ngtools/webpack/src/loader.ts
+++ b/packages/@ngtools/webpack/src/loader.ts
@@ -17,10 +17,9 @@ function _getContentOfKeyLiteral(source: ts.SourceFile, node: ts.Node): string {
}
function _removeDecorators(refactor: TypeScriptFileRefactor) {
- // TODO: replace this by tsickle.
// Find all decorators.
- // refactor.findAstNodes(refactor.sourceFile, ts.SyntaxKind.Decorator)
- // .forEach(d => refactor.removeNode(d));
+ refactor.findAstNodes(refactor.sourceFile, ts.SyntaxKind.Decorator)
+ .forEach(d => refactor.removeNode(d));
}
diff --git a/packages/@ngtools/webpack/src/plugin.ts b/packages/@ngtools/webpack/src/plugin.ts
index b3d198e71436..e76d445cdd49 100644
--- a/packages/@ngtools/webpack/src/plugin.ts
+++ b/packages/@ngtools/webpack/src/plugin.ts
@@ -2,13 +2,16 @@ import * as fs from 'fs';
import * as path from 'path';
import * as ts from 'typescript';
-import {__NGTOOLS_PRIVATE_API_2} from '@angular/compiler-cli';
-import {AngularCompilerOptions} from '@angular/tsc-wrapped';
+import {NgModule} from '@angular/core';
+import * as ngCompiler from '@angular/compiler-cli';
+import {tsc} from '@angular/tsc-wrapped/src/tsc';
+import {patchReflectorHost} from './reflector_host';
import {WebpackResourceLoader} from './resource_loader';
import {createResolveDependenciesFromContextMap} from './utils';
import {WebpackCompilerHost} from './compiler_host';
import {resolveEntryModuleFromMain} from './entry_resolver';
+import {StaticSymbol} from '@angular/compiler-cli';
import {Tapable} from './webpack';
import {PathsPlugin} from './paths-plugin';
@@ -26,29 +29,54 @@ export interface AotPluginOptions {
i18nFile?: string;
i18nFormat?: string;
locale?: string;
+}
+
- // Use tsconfig to include path globs.
- exclude?: string | string[];
+export interface LazyRoute {
+ moduleRoute: ModuleRoute;
+ absolutePath: string;
+ absoluteGenDirPath: string;
+}
+
+
+export interface LazyRouteMap {
+ [path: string]: LazyRoute;
+}
+
+
+export class ModuleRoute {
+ constructor(public readonly path: string, public readonly className: string = null) {}
+
+ toString() {
+ return `${this.path}#${this.className}`;
+ }
+
+ static fromString(entry: string): ModuleRoute {
+ const split = entry.split('#');
+ return new ModuleRoute(split[0], split[1]);
+ }
}
export class AotPlugin implements Tapable {
+ private _entryModule: ModuleRoute;
private _compilerOptions: ts.CompilerOptions;
- private _angularCompilerOptions: AngularCompilerOptions;
+ private _angularCompilerOptions: ngCompiler.AngularCompilerOptions;
private _program: ts.Program;
+ private _reflector: ngCompiler.StaticReflector;
+ private _reflectorHost: ngCompiler.ReflectorHost;
private _rootFilePath: string[];
private _compilerHost: WebpackCompilerHost;
private _resourceLoader: WebpackResourceLoader;
private _lazyRoutes: { [route: string]: string };
private _tsConfigPath: string;
- private _entryModule: string;
private _donePromise: Promise;
private _compiler: any = null;
private _compilation: any = null;
- private _typeCheck: boolean = true;
- private _skipCodeGeneration: boolean = false;
+ private _typeCheck = true;
+ private _skipCodeGeneration = false;
private _basePath: string;
private _genDir: string;
@@ -65,12 +93,7 @@ export class AotPlugin implements Tapable {
get compilerHost() { return this._compilerHost; }
get compilerOptions() { return this._compilerOptions; }
get done() { return this._donePromise; }
- get entryModule() {
- const splitted = this._entryModule.split('#');
- const path = splitted[0];
- const className = splitted[1] || 'default';
- return {path, className};
- }
+ get entryModule() { return this._entryModule; }
get genDir() { return this._genDir; }
get program() { return this._program; }
get skipCodeGeneration() { return this._skipCodeGeneration; }
@@ -96,59 +119,19 @@ export class AotPlugin implements Tapable {
basePath = path.resolve(process.cwd(), options.basePath);
}
- let tsConfigJson: any = null;
- try {
- tsConfigJson = JSON.parse(fs.readFileSync(this._tsConfigPath, 'utf8'));
- } catch (err) {
- throw new Error(`An error happened while parsing ${this._tsConfigPath} JSON: ${err}.`);
- }
- const tsConfig = ts.parseJsonConfigFileContent(
- tsConfigJson, ts.sys, basePath, null, this._tsConfigPath);
-
- let fileNames = tsConfig.fileNames;
- if (options.hasOwnProperty('exclude')) {
- let exclude: string[] = typeof options.exclude == 'string'
- ? [options.exclude as string] : (options.exclude as string[]);
-
- exclude.forEach((pattern: string) => {
- const basePathPattern = '(' + basePath.replace(/\\/g, '/')
- .replace(/[\-\[\]\/{}()+?.\\^$|*]/g, '\\$&') + ')?';
- pattern = pattern
- // Replace windows path separators with forward slashes.
- .replace(/\\/g, '/')
- // Escape characters that are used normally in regexes, except stars.
- .replace(/[\-\[\]{}()+?.\\^$|]/g, '\\$&')
- // Two stars replacement.
- .replace(/\*\*/g, '(?:.*)')
- // One star replacement.
- .replace(/\*/g, '(?:[^/]*)')
- // Escape characters from the basePath and make sure it's forward slashes.
- .replace(/^/, basePathPattern);
-
- const re = new RegExp('^' + pattern + '$');
- fileNames = fileNames.filter(x => !x.replace(/\\/g, '/').match(re));
- });
- } else {
- fileNames = fileNames.filter(fileName => !/\.spec\.ts$/.test(fileName));
- }
- this._rootFilePath = fileNames;
+ const tsConfig = tsc.readConfiguration(this._tsConfigPath, basePath);
+ this._rootFilePath = tsConfig.parsed.fileNames
+ .filter(fileName => !/\.spec\.ts$/.test(fileName));
// Check the genDir.
let genDir = basePath;
-
- this._compilerOptions = tsConfig.options;
- this._angularCompilerOptions = Object.assign(
- { genDir },
- this._compilerOptions,
- tsConfig.raw['angularCompilerOptions'],
- { basePath }
- );
-
- if (this._angularCompilerOptions.hasOwnProperty('genDir')) {
- genDir = path.resolve(basePath, this._angularCompilerOptions.genDir);
- this._angularCompilerOptions.genDir = genDir;
+ if (tsConfig.ngOptions.hasOwnProperty('genDir')) {
+ genDir = tsConfig.ngOptions.genDir;
}
+ this._compilerOptions = tsConfig.parsed.options;
+
+ this._angularCompilerOptions = Object.assign({}, tsConfig.ngOptions, { basePath, genDir });
this._basePath = basePath;
this._genDir = genDir;
@@ -164,16 +147,21 @@ export class AotPlugin implements Tapable {
this._rootFilePath, this._compilerOptions, this._compilerHost);
if (options.entryModule) {
- this._entryModule = options.entryModule;
+ this._entryModule = ModuleRoute.fromString(options.entryModule);
} else {
if (options.mainPath) {
- this._entryModule = resolveEntryModuleFromMain(options.mainPath, this._compilerHost,
+ const entryModuleString = resolveEntryModuleFromMain(options.mainPath, this._compilerHost,
this._program);
+ this._entryModule = ModuleRoute.fromString(entryModuleString);
} else {
- this._entryModule = (tsConfig.raw['angularCompilerOptions'] as any).entryModule;
+ this._entryModule = ModuleRoute.fromString((tsConfig.ngOptions as any).entryModule);
}
}
+ this._reflectorHost = new ngCompiler.ReflectorHost(
+ this._program, this._compilerHost, this._angularCompilerOptions);
+ this._reflector = new ngCompiler.StaticReflector(this._reflectorHost);
+
if (options.hasOwnProperty('i18nFile')) {
this._i18nFile = options.i18nFile;
}
@@ -213,8 +201,7 @@ export class AotPlugin implements Tapable {
(_: any, cb: any) => cb(null, this._lazyRoutes));
return callback(null, result);
- }, () => callback(null))
- .catch(err => callback(err));
+ }).catch((err) => callback(err));
});
});
@@ -229,7 +216,9 @@ export class AotPlugin implements Tapable {
// Virtual file system.
compiler.resolvers.normal.plugin('resolve', (request: any, cb?: (err?: any) => void) => {
if (request.request.match(/\.ts$/)) {
- this.done.then(() => cb(), () => cb());
+ this.done
+ .then(() => cb())
+ .catch((err) => cb(err));
} else {
cb();
}
@@ -250,6 +239,13 @@ export class AotPlugin implements Tapable {
this._resourceLoader = new WebpackResourceLoader(compilation);
+ const i18nOptions: ngCompiler.NgcCliOptions = {
+ i18nFile: this.i18nFile,
+ i18nFormat: this.i18nFormat,
+ locale: this.locale,
+ basePath: this.basePath
+ };
+
this._donePromise = Promise.resolve()
.then(() => {
if (this._skipCodeGeneration) {
@@ -257,18 +253,20 @@ export class AotPlugin implements Tapable {
}
// Create the Code Generator.
- return __NGTOOLS_PRIVATE_API_2.codeGen({
- basePath: this._basePath,
- compilerOptions: this._compilerOptions,
- program: this._program,
- host: this._compilerHost,
- angularCompilerOptions: this._angularCompilerOptions,
- i18nFile: this.i18nFile,
- i18nFormat: this.i18nFormat,
- locale: this.locale,
-
- readResource: (path: string) => this._resourceLoader.get(path)
- });
+ const codeGenerator = ngCompiler.CodeGenerator.create(
+ this._angularCompilerOptions,
+ i18nOptions,
+ this._program,
+ this._compilerHost,
+ new ngCompiler.NodeReflectorHostContext(this._compilerHost),
+ this._resourceLoader
+ );
+
+ // We need to temporarily patch the CodeGenerator until either it's patched or allows us
+ // to pass in our own ReflectorHost.
+ // TODO: remove this.
+ patchReflectorHost(codeGenerator);
+ return codeGenerator.codegen({ transitiveModules: true });
})
.then(() => {
// Create a new Program, based on the old one. This will trigger a resolution of all
@@ -300,26 +298,155 @@ export class AotPlugin implements Tapable {
.then(() => {
// Process the lazy routes
this._lazyRoutes = {};
- const allLazyRoutes = __NGTOOLS_PRIVATE_API_2.listLazyRoutes({
- program: this._program,
- host: this._compilerHost,
- angularCompilerOptions: this._angularCompilerOptions,
- entryModule: this._entryModule
- });
+ const allLazyRoutes = this._processNgModule(this._entryModule, null);
Object.keys(allLazyRoutes)
.forEach(k => {
const lazyRoute = allLazyRoutes[k];
if (this.skipCodeGeneration) {
- this._lazyRoutes[k] = lazyRoute;
+ this._lazyRoutes[k] = lazyRoute.absolutePath + '.ts';
} else {
- const lr = path.relative(this.basePath, lazyRoute.replace(/\.ts$/, '.ngfactory.ts'));
- this._lazyRoutes[k + '.ngfactory'] = path.join(this.genDir, lr);
+ this._lazyRoutes[k + '.ngfactory'] = lazyRoute.absoluteGenDirPath + '.ngfactory.ts';
}
});
})
- .then(() => cb(), (err: any) => {
- compilation.errors.push(err);
- cb();
+ .then(() => cb(), (err: any) => { cb(err); });
+ }
+
+ private _resolveModulePath(module: ModuleRoute, containingFile: string) {
+ if (module.path.startsWith('.')) {
+ return path.join(path.dirname(containingFile), module.path);
+ }
+ return module.path;
+ }
+
+ private _processNgModule(module: ModuleRoute, containingFile: string | null): LazyRouteMap {
+ const modulePath = containingFile ? module.path : ('./' + path.basename(module.path));
+ if (containingFile === null) {
+ containingFile = module.path + '.ts';
+ }
+ const relativeModulePath = this._resolveModulePath(module, containingFile);
+
+ const staticSymbol = this._reflectorHost
+ .findDeclaration(modulePath, module.className, containingFile);
+ const entryNgModuleMetadata = this.getNgModuleMetadata(staticSymbol);
+ const loadChildrenRoute: LazyRoute[] = this.extractLoadChildren(entryNgModuleMetadata)
+ .map(route => {
+ const moduleRoute = ModuleRoute.fromString(route);
+ const resolvedModule = ts.resolveModuleName(moduleRoute.path,
+ relativeModulePath, this._compilerOptions, this._compilerHost);
+
+ if (!resolvedModule.resolvedModule) {
+ throw new Error(`Could not resolve route "${route}" from file "${relativeModulePath}".`);
+ }
+
+ const relativePath = path.relative(this.basePath,
+ resolvedModule.resolvedModule.resolvedFileName).replace(/\.ts$/, '');
+
+ const absolutePath = path.join(this.basePath, relativePath);
+ const absoluteGenDirPath = path.join(this._genDir, relativePath);
+
+ return {
+ moduleRoute,
+ absoluteGenDirPath,
+ absolutePath
+ };
});
+ const resultMap: LazyRouteMap = loadChildrenRoute
+ .reduce((acc: LazyRouteMap, curr: LazyRoute) => {
+ const key = curr.moduleRoute.path;
+ if (acc[key]) {
+ if (acc[key].absolutePath != curr.absolutePath) {
+ throw new Error(`Duplicated path in loadChildren detected: "${key}" is used in 2 ` +
+ 'loadChildren, but they point to different modules. Webpack cannot distinguish ' +
+ 'between the two based on context and would fail to load the proper one.');
+ }
+ } else {
+ acc[key] = curr;
+ }
+ return acc;
+ }, {});
+
+ // Also concatenate every child of child modules.
+ for (const lazyRoute of loadChildrenRoute) {
+ const mr = lazyRoute.moduleRoute;
+ const children = this._processNgModule(mr, relativeModulePath);
+ Object.keys(children).forEach(p => {
+ const child = children[p];
+ const key = child.moduleRoute.path;
+ if (resultMap[key]) {
+ if (resultMap[key].absolutePath != child.absolutePath) {
+ throw new Error(`Duplicated path in loadChildren detected: "${key}" is used in 2 ` +
+ 'loadChildren, but they point to different modules. Webpack cannot distinguish ' +
+ 'between the two based on context and would fail to load the proper one.');
+ }
+ } else {
+ resultMap[key] = child;
+ }
+ });
+ }
+ return resultMap;
+ }
+
+ private getNgModuleMetadata(staticSymbol: ngCompiler.StaticSymbol) {
+ const ngModules = this._reflector.annotations(staticSymbol).filter(s => s instanceof NgModule);
+ if (ngModules.length === 0) {
+ throw new Error(`${staticSymbol.name} is not an NgModule`);
+ }
+ return ngModules[0];
+ }
+
+ private extractLoadChildren(ngModuleDecorator: any): any[] {
+ const routes = (ngModuleDecorator.imports || []).reduce((mem: any[], m: any) => {
+ return mem.concat(this.collectRoutes(m.providers));
+ }, this.collectRoutes(ngModuleDecorator.providers));
+ return this.collectLoadChildren(routes)
+ .concat((ngModuleDecorator.imports || [])
+ // Also recursively extractLoadChildren of modules we import.
+ .map((staticSymbol: any) => {
+ if (staticSymbol instanceof StaticSymbol) {
+ const entryNgModuleMetadata = this.getNgModuleMetadata(staticSymbol);
+ return this.extractLoadChildren(entryNgModuleMetadata);
+ } else {
+ return [];
+ }
+ })
+ // Poor man's flat map.
+ .reduce((acc: any[], i: any) => acc.concat(i), []))
+ .filter(x => !!x);
+ }
+
+ private collectRoutes(providers: any[]): any[] {
+ if (!providers) {
+ return [];
+ }
+ const ROUTES = this._reflectorHost.findDeclaration(
+ '@angular/router/src/router_config_loader', 'ROUTES', undefined);
+
+ return providers.reduce((m, p) => {
+ if (p.provide === ROUTES) {
+ return m.concat(p.useValue);
+ } else if (Array.isArray(p)) {
+ return m.concat(this.collectRoutes(p));
+ } else {
+ return m;
+ }
+ }, []);
+ }
+
+ private collectLoadChildren(routes: any[]): any[] {
+ if (!routes) {
+ return [];
+ }
+ return routes.reduce((m, r) => {
+ if (r.loadChildren) {
+ return m.concat(r.loadChildren);
+ } else if (Array.isArray(r)) {
+ return m.concat(this.collectLoadChildren(r));
+ } else if (r.children) {
+ return m.concat(this.collectLoadChildren(r.children));
+ } else {
+ return m;
+ }
+ }, []);
}
}
diff --git a/packages/@ngtools/webpack/src/refactor.ts b/packages/@ngtools/webpack/src/refactor.ts
index 3ad8fc76d922..47c50d0e6227 100644
--- a/packages/@ngtools/webpack/src/refactor.ts
+++ b/packages/@ngtools/webpack/src/refactor.ts
@@ -16,12 +16,7 @@ function resolve(filePath: string, host: ts.CompilerHost, program: ts.Program) {
if (path.isAbsolute(filePath)) {
return filePath;
}
- const compilerOptions = program.getCompilerOptions();
- const basePath = compilerOptions.baseUrl || compilerOptions.rootDir;
- if (!basePath) {
- throw new Error(`Trying to resolve '${filePath}' without a basePath.`);
- }
- return path.join(basePath, filePath);
+ return path.join(program.getCompilerOptions().baseUrl || process.cwd(), filePath);
}
@@ -30,7 +25,7 @@ export class TypeScriptFileRefactor {
private _sourceFile: ts.SourceFile;
private _sourceString: any;
private _sourceText: string;
- private _changed: boolean = false;
+ private _changed = false;
get fileName() { return this._fileName; }
get sourceFile() { return this._sourceFile; }
diff --git a/packages/angular-cli/blueprints/ng2/files/README.md b/packages/angular-cli/blueprints/ng2/files/README.md
deleted file mode 100755
index 851fb1af4de2..000000000000
--- a/packages/angular-cli/blueprints/ng2/files/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# <%= jsComponentName %>
-
-This project was generated with [angular-cli](https://github.com/angular/angular-cli) version <%= version %>.
-
-## Development server
-Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
-
-## Code scaffolding
-
-Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
-
-## Build
-
-Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
-
-## Running unit tests
-
-Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
-
-## Running end-to-end tests
-
-Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
-Before running the tests make sure you are serving the app via `ng serve`.
-
-## Deploying to Github Pages
-
-Run `ng github-pages:deploy` to deploy to Github Pages.
-
-## Further help
-
-To get more help on the `angular-cli` use `ng help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
diff --git a/packages/angular-cli/blueprints/ng2/files/package.json b/packages/angular-cli/blueprints/ng2/files/package.json
deleted file mode 100644
index 1bbbb1f52530..000000000000
--- a/packages/angular-cli/blueprints/ng2/files/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "<%= htmlComponentName %>",
- "version": "0.0.0",
- "license": "MIT",
- "angular-cli": {},
- "scripts": {
- "ng": "ng",
- "start": "ng serve",
- "lint": "tslint \"<%= sourceDir %>/**/*.ts\"",
- "test": "ng test",
- "pree2e": "webdriver-manager update --standalone false --gecko false",
- "e2e": "protractor"
- },
- "private": true,
- "dependencies": {
- "@angular/common": "~2.3.1",
- "@angular/compiler": "~2.3.1",
- "@angular/core": "~2.3.1",
- "@angular/forms": "~2.3.1",
- "@angular/http": "~2.3.1",
- "@angular/platform-browser": "~2.3.1",
- "@angular/platform-browser-dynamic": "~2.3.1",
- "@angular/router": "3.2.3",
- "core-js": "^2.4.1",
- "rxjs": "5.0.0-rc.4",
- "ts-helpers": "^1.1.1",
- "zone.js": "^0.7.2"
- },
- "devDependencies": {
- "@angular/compiler-cli": "~2.3.1",
- "@types/jasmine": "2.5.38",
- "@types/node": "^6.0.42",
- "angular-cli": "<%= version %>",
- "codelyzer": "~2.0.0-beta.1",
- "jasmine-core": "2.5.2",
- "jasmine-spec-reporter": "2.5.0",
- "karma": "1.2.0",
- "karma-chrome-launcher": "^2.0.0",
- "karma-cli": "^1.0.1",
- "karma-jasmine": "^1.0.2",
- "karma-remap-istanbul": "^0.2.1",
- "protractor": "~4.0.13",
- "ts-node": "1.2.1",
- "tslint": "^4.0.2",
- "typescript": "~2.0.3"
- }
-}
diff --git a/packages/angular-cli/ember-cli/lib/commands.js b/packages/angular-cli/ember-cli/lib/commands.js
deleted file mode 100644
index 801330451d53..000000000000
--- a/packages/angular-cli/ember-cli/lib/commands.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-module.exports = { 'Unknown': require('./commands/unknown') };
diff --git a/packages/angular-cli/ember-cli/lib/models/blueprint.js b/packages/angular-cli/ember-cli/lib/models/blueprint.js
deleted file mode 100644
index f167fdbdfbcb..000000000000
--- a/packages/angular-cli/ember-cli/lib/models/blueprint.js
+++ /dev/null
@@ -1,1571 +0,0 @@
-'use strict';
-
-/**
-@module ember-cli
-*/
-var FileInfo = require('./file-info');
-var Promise = require('../ext/promise');
-var chalk = require('chalk');
-var MarkdownColor = require('../utilities/markdown-color');
-var printableProperties = require('../utilities/printable-properties').blueprint;
-var sequence = require('../utilities/sequence');
-var printCommand = require('../utilities/print-command');
-var fs = require('fs-extra');
-var existsSync = require('exists-sync');
-var inflector = require('inflection');
-var minimatch = require('minimatch');
-var path = require('path');
-var stat = Promise.denodeify(fs.stat);
-var stringUtils = require('ember-cli-string-utils');
-var compact = require('lodash/compact');
-var intersect = require('lodash/intersection');
-var uniq = require('lodash/uniq');
-var zipObject = require('lodash/zipObject');
-var includes = require('lodash/includes');
-var any = require('lodash/some');
-var cloneDeep = require('lodash/cloneDeep');
-var keys = require('lodash/keys');
-var merge = require('lodash/merge');
-var values = require('lodash/values');
-var walkSync = require('walk-sync');
-var writeFile = Promise.denodeify(fs.outputFile);
-var removeFile = Promise.denodeify(fs.remove);
-var SilentError = require('silent-error');
-var CoreObject = require('../ext/core-object');
-var EOL = require('os').EOL;
-var debug = require('debug')('ember-cli:blueprint');
-var normalizeEntityName = require('ember-cli-normalize-entity-name');
-
-module.exports = Blueprint;
-
-/**
- A blueprint is a bundle of template files with optional install
- logic.
-
- Blueprints follow a simple structure. Let's take the built-in
- `controller` blueprint as an example:
-
- ```
- blueprints/controller
- ├── files
- │ ├── app
- │ │ └── __path__
- │ │ └── __name__.js
- └── index.js
-
- blueprints/controller-test
- ├── files
- │ └── tests
- │ └── unit
- │ └── controllers
- │ └── __test__.js
- └── index.js
- ```
-
- ## Files
-
- `files` contains templates for the all the files to be
- installed into the target directory.
-
- The `__name__` token is subtituted with the dasherized
- entity name at install time. For example, when the user
- invokes `ember generate controller foo` then `__name__` becomes
- `foo`. When the `--pod` flag is used, for example `ember
- generate controller foo --pod` then `__name__` becomes
- `controller`.
-
- The `__path__` token is substituted with the blueprint
- name at install time. For example, when the user invokes
- `ember generate controller foo` then `__path__` becomes
- `controller`. When the `--pod` flag is used, for example
- `ember generate controller foo --pod` then `__path__`
- becomes `foo` (or `/foo` if the
- podModulePrefix is defined). This token is primarily for
- pod support, and is only necessary if the blueprint can be
- used in pod structure. If the blueprint does not require pod
- support, simply use the blueprint name instead of the
- `__path__` token.
-
- The `__test__` token is substituted with the dasherized
- entity name and appended with `-test` at install time.
- This token is primarily for pod support and only necessary
- if the blueprint requires support for a pod structure. If
- the blueprint does not require pod support, simply use the
- `__name__` token instead.
-
- ## Template Variables (AKA Locals)
-
- Variables can be inserted into templates with
- `<%= someVariableName %>`.
-
- For example, the built-in `util` blueprint
- `files/app/utils/__name__.js` looks like this:
-
- ```js
- export default function <%= camelizedModuleName %>() {
- return true;
- }
- ```
-
- `<%= camelizedModuleName %>` is replaced with the real
- value at install time.
-
- The following template variables are provided by default:
-
- - `dasherizedPackageName`
- - `classifiedPackageName`
- - `dasherizedModuleName`
- - `classifiedModuleName`
- - `camelizedModuleName`
-
- `packageName` is the project name as found in the project's
- `package.json`.
-
- `moduleName` is the name of the entity being generated.
-
- The mechanism for providing custom template variables is
- described below.
-
- ## Index.js
-
- Custom installation and uninstallation behaviour can be added
- by overriding the hooks documented below. `index.js` should
- export a plain object, which will extend the prototype of the
- `Blueprint` class. If needed, the original `Blueprint` prototype
- can be accessed through the `_super` property.
-
- ```js
- module.exports = {
- locals: function(options) {
- // Return custom template variables here.
- return {};
- },
-
- normalizeEntityName: function(entityName) {
- // Normalize and validate entity name here.
- return entityName;
- },
-
- fileMapTokens: function(options) (
- // Return custom tokens to be replaced in your files
- return {
- __token__: function(options){
- // logic to determine value goes here
- return 'value';
- }
- }
- },
-
- filesPath: function(options) {
- return path.join(this.path, 'files');
- },
-
- beforeInstall: function(options) {},
- afterInstall: function(options) {},
- beforeUninstall: function(options) {},
- afterUninstall: function(options) {}
-
- };
- ```
-
- ## Blueprint Hooks
-
- As shown above, the following hooks are available to
- blueprint authors:
-
- - `locals`
- - `normalizeEntityName`
- - `fileMapTokens`
- - `filesPath`
- - `beforeInstall`
- - `afterInstall`
- - `beforeUninstall`
- - `afterUninstall`
-
- ### locals
-
- Use `locals` to add custom tempate variables. The method
- receives one argument: `options`. Options is an object
- containing general and entity-specific options.
-
- When the following is called on the command line:
-
- ```sh
- ember generate controller foo --type=array --dry-run
- ```
-
- The object passed to `locals` looks like this:
-
- ```js
- {
- entity: {
- name: 'foo',
- options: {
- type: 'array'
- }
- },
- dryRun: true
- }
- ```
-
- This hook must return an object or a Promise which resolves to an object.
- The resolved object will be merged with the aforementioned default locals.
-
- ### normalizeEntityName
-
- Use the `normalizeEntityName` hook to add custom normalization and
- validation of the provided entity name. The default hook does not
- make any changes to the entity name, but makes sure an entity name
- is present and that it doesn't have a trailing slash.
-
- This hook receives the entity name as its first argument. The string
- returned by this hook will be used as the new entity name.
-
- ### fileMapTokens
-
- Use `fileMapTokens` to add custom fileMap tokens for use
- in the `mapFile` method. The hook must return an object in the
- following pattern:
-
- ```js
- {
- __token__: function(options){
- // logic to determine value goes here
- return 'value';
- }
- }
- ```
-
- It will be merged with the default `fileMapTokens`, and can be used
- to override any of the default tokens.
-
- Tokens are used in the files folder (see `files`), and get replaced with
- values when the `mapFile` method is called.
-
- ### filesPath
-
- Use `filesPath` to define where the blueprint files to install are located.
- This can be used to customize which set of files to install based on options
- or environmental variables. It defaults to the `files` directory within the
- blueprint's folder.
-
- ### beforeInstall & beforeUninstall
-
- Called before any of the template files are processed and receives
- the the `options` and `locals` hashes as parameters. Typically used for
- validating any additional command line options or for any asynchronous
- setup that is needed. As an example, the `controller` blueprint validates
- its `--type` option in this hook. If you need to run any asynchronous code,
- wrap it in a promise and return that promise from these hooks. This will
- ensure that your code is executed correctly.
-
- ### afterInstall & afterUninstall
-
- The `afterInstall` and `afterUninstall` hooks receives the same
- arguments as `locals`. Use it to perform any custom work after the
- files are processed. For example, the built-in `route` blueprint
- uses these hooks to add and remove relevant route declarations in
- `app/router.js`.
-
- ### Overriding Install
-
- If you don't want your blueprint to install the contents of
- `files` you can override the `install` method. It receives the
- same `options` object described above and must return a promise.
- See the built-in `resource` blueprint for an example of this.
-
- @class Blueprint
- @constructor
- @extends CoreObject
- @param {String} [blueprintPath]
-*/
-function Blueprint(blueprintPath) {
- this.path = blueprintPath;
- this.name = path.basename(blueprintPath);
-}
-
-Blueprint.__proto__ = CoreObject;
-Blueprint.prototype.constructor = Blueprint;
-
-Blueprint.prototype.availableOptions = [];
-Blueprint.prototype.anonymousOptions = ['name'];
-
-/**
- Hook to specify the path to the blueprint's files. By default this is
- `path.join(this.path, 'files)`.
-
- @method filesPath
- @param {Object} options
- @return {String} Path to the blueprints files directory.
-*/
-
-Blueprint.prototype.filesPath = function() {
- return path.join(this.path, 'files');
-};
-
-/**
- Used to retrieve files for blueprint. The `file` param is an
- optional string that is turned into a glob.
-
- @method files
- @return {Array} Contents of the blueprint's files directory
-*/
-Blueprint.prototype.files = function() {
- if (this._files) { return this._files; }
-
- var filesPath = this.filesPath(this.options);
- if (existsSync(filesPath)) {
- this._files = walkSync(filesPath);
- } else {
- this._files = [];
- }
-
- return this._files;
-};
-
-/**
- @method srcPath
- @param {String} file
- @return {String} Resolved path to the file
-*/
-Blueprint.prototype.srcPath = function(file) {
- return path.resolve(this.filesPath(this.options), file);
-};
-
-/**
- Hook for normalizing entity name
- @method normalizeEntityName
- @param {String} entityName
- @return {null}
-*/
-Blueprint.prototype.normalizeEntityName = function(entityName) {
- return normalizeEntityName(entityName);
-};
-
-/**
- Write a status and message to the UI
- @private
- @method _writeStatusToUI
- @param {Function} chalkColor
- @param {String} keyword
- @param {String} message
-*/
-Blueprint.prototype._writeStatusToUI = function(chalkColor, keyword, message) {
- if (this.ui) {
- this.ui.writeLine(' ' + chalkColor(keyword) + ' ' + message);
- }
-};
-
-/**
- @private
- @method _writeFile
- @param {Object} info
- @return {Promise}
-*/
-Blueprint.prototype._writeFile = function(info) {
- if (!this.dryRun) {
- return writeFile(info.outputPath, info.render());
- }
-};
-
-/**
- Actions lookup
- @private
-*/
-
-Blueprint.prototype._actions = {
- write: function(info) {
- this._writeStatusToUI(chalk.green, 'create', info.displayPath);
- return this._writeFile(info);
- },
- skip: function(info) {
- var label = 'skip';
-
- if (info.resolution === 'identical') {
- label = 'identical';
- }
-
- this._writeStatusToUI(chalk.yellow, label, info.displayPath);
- },
-
- overwrite: function(info) {
- this._writeStatusToUI(chalk.yellow, 'overwrite', info.displayPath);
- return this._writeFile(info);
- },
-
- edit: function(info) {
- this._writeStatusToUI(chalk.green, 'edited', info.displayPath);
- },
-
- remove: function(info) {
- this._writeStatusToUI(chalk.red, 'remove', info.displayPath);
- if (!this.dryRun) {
- return removeFile(info.outputPath);
- }
- }
-};
-
-/**
- Calls an action.
- @private
- @method _commit
- @param {Object} result
- @return {Promise}
- @throws {Error} Action doesn't exist.
-*/
-Blueprint.prototype._commit = function(result) {
- var action = this._actions[result.action];
-
- if (action) {
- return action.call(this, result);
- } else {
- throw new Error('Tried to call action \"' + result.action + '\" but it does not exist');
- }
-};
-
-/**
- Prints warning for pod unsupported.
- @private
- @method _checkForPod
-*/
-Blueprint.prototype._checkForPod = function(verbose) {
- if (!this.hasPathToken && this.pod && verbose) {
- this.ui.writeLine(chalk.yellow('You specified the pod flag, but this' +
- ' blueprint does not support pod structure. It will be generated with' +
- ' the default structure.'));
- }
-};
-
-/**
- @private
- @method _normalizeEntityName
- @param {Object} entity
-*/
-Blueprint.prototype._normalizeEntityName = function(entity) {
- if (entity) {
- entity.name = this.normalizeEntityName(entity.name);
- }
-};
-
-/**
- @private
- @method _checkInRepoAddonExists
- @param {String} inRepoAddon
-*/
-Blueprint.prototype._checkInRepoAddonExists = function(inRepoAddon) {
- if (inRepoAddon) {
- if (!inRepoAddonExists(inRepoAddon, this.project.root)) {
- throw new SilentError('You specified the in-repo-addon flag, but the' +
- ' in-repo-addon \'' + inRepoAddon + '\' does not exist. Please' +
- ' check the name and try again.');
- }
- }
-};
-
-/**
- @private
- @method _process
- @param {Object} options
- @param {Function} beforeHook
- @param {Function} process
- @param {Function} afterHook
-*/
-Blueprint.prototype._process = function(options, beforeHook, process, afterHook) {
- var self = this;
- var intoDir = options.target;
-
- return this._locals(options).then(function (locals) {
- return Promise.resolve()
- .then(beforeHook.bind(self, options, locals))
- .then(process.bind(self, intoDir, locals)).map(self._commit.bind(self))
- .then(afterHook.bind(self, options));
- });
-};
-
-/**
- @method install
- @param {Object} options
- @return {Promise}
-*/
-Blueprint.prototype.install = function(options) {
- var ui = this.ui = options.ui;
- var dryRun = this.dryRun = options.dryRun;
- this.project = options.project;
- this.pod = options.pod;
- this.options = options;
- this.hasPathToken = hasPathToken(this.files());
-
- podDeprecations(this.project.config(), ui);
-
- ui.writeLine('installing ' + this.name);
-
- if (dryRun) {
- ui.writeLine(chalk.yellow('You specified the dry-run flag, so no' +
- ' changes will be written.'));
- }
-
- this._normalizeEntityName(options.entity);
- this._checkForPod(options.verbose);
- this._checkInRepoAddonExists(options.inRepoAddon);
-
- debug('START: processing blueprint: `%s`', this.name);
- var start = new Date();
- return this._process(
- options,
- this.beforeInstall,
- this.processFiles,
- this.afterInstall).finally(function() {
- debug('END: processing blueprint: `%s` in (%dms)', this.name, new Date() - start);
- }.bind(this));
-};
-
-/**
- @method uninstall
- @param {Object} options
- @return {Promise}
-*/
-Blueprint.prototype.uninstall = function(options) {
- var ui = this.ui = options.ui;
- var dryRun = this.dryRun = options.dryRun;
- this.project = options.project;
- this.pod = options.pod;
- this.options = options;
- this.hasPathToken = hasPathToken(this.files());
-
- podDeprecations(this.project.config(), ui);
-
- ui.writeLine('uninstalling ' + this.name);
-
- if (dryRun) {
- ui.writeLine(chalk.yellow('You specified the dry-run flag, so no' +
- ' files will be deleted.'));
- }
-
- this._normalizeEntityName(options.entity);
- this._checkForPod(options.verbose);
-
- return this._process(
- options,
- this.beforeUninstall,
- this.processFilesForUninstall,
- this.afterUninstall);
-};
-
-/**
- Hook for running operations before install.
- @method beforeInstall
- @return {Promise|null}
-*/
-Blueprint.prototype.beforeInstall = function() {};
-
-/**
- Hook for running operations after install.
- @method afterInstall
- @return {Promise|null}
-*/
-Blueprint.prototype.afterInstall = function() {};
-
-/**
- Hook for running operations before uninstall.
- @method beforeUninstall
- @return {Promise|null}
-*/
-Blueprint.prototype.beforeUninstall = function() {};
-
-/**
- Hook for running operations after uninstall.
- @method afterUninstall
- @return {Promise|null}
-*/
-Blueprint.prototype.afterUninstall = function() {};
-
-/**
- Hook for adding additional locals
- @method locals
- @return {Object|null}
-*/
-Blueprint.prototype.locals = function() {};
-
-/**
- Hook to add additional or override existing fileMapTokens.
- @method fileMapTokens
- @return {Object|null}
-*/
-Blueprint.prototype.fileMapTokens = function() {
-};
-
-/**
- @private
- @method _fileMapTokens
- @param {Object} options
- @return {Object}
-*/
-Blueprint.prototype._fileMapTokens = function(options) {
- var standardTokens = {
- __name__: function(options) {
- if (options.pod && options.hasPathToken) {
- return options.blueprintName;
- }
- return options.dasherizedModuleName;
- },
- __path__: function(options) {
- var blueprintName = options.blueprintName;
-
- if (blueprintName.match(/-test/)) {
- blueprintName = options.blueprintName.slice(0, options.blueprintName.indexOf('-test'));
- }
- if (options.pod && options.hasPathToken) {
- return path.join(options.podPath, options.dasherizedModuleName);
- }
- return inflector.pluralize(blueprintName);
- },
- __root__: function(options) {
- if (options.inRepoAddon) {
- return path.join('lib',options.inRepoAddon, 'addon');
- }
- if (options.inDummy) {
- return path.join('tests','dummy','app');
- }
- if (options.inAddon) {
- return 'addon';
- }
- return 'app';
- },
- __test__: function(options) {
- if (options.pod && options.hasPathToken) {
- return options.blueprintName;
- }
- return options.dasherizedModuleName + '-test';
- }
- };
-
- var customTokens = this.fileMapTokens(options) || options.fileMapTokens || {};
- return merge(standardTokens, customTokens);
-};
-
-/**
- Used to generate fileMap tokens for mapFile.
-
- @method generateFileMap
- @param {Object} fileMapVariables
- @return {Object}
-*/
-Blueprint.prototype.generateFileMap = function(fileMapVariables) {
- var tokens = this._fileMapTokens(fileMapVariables);
- var fileMapValues = values(tokens);
- var tokenValues = fileMapValues.map(function(token) { return token(fileMapVariables); });
- var tokenKeys = keys(tokens);
- return zipObject(tokenKeys,tokenValues);
-};
-
-/**
- @method buildFileInfo
- @param {Function} destPath
- @param {Object} templateVariables
- @param {String} file
- @return {FileInfo}
-*/
-Blueprint.prototype.buildFileInfo = function(destPath, templateVariables, file) {
- var mappedPath = this.mapFile(file, templateVariables);
-
- return new FileInfo({
- action: 'write',
- outputPath: destPath(mappedPath),
- displayPath: path.normalize(mappedPath),
- inputPath: this.srcPath(file),
- templateVariables: templateVariables,
- ui: this.ui
- });
-};
-
-/**
- @method isUpdate
- @return {Boolean}
-*/
-Blueprint.prototype.isUpdate = function() {
- if (this.project && this.project.isEmberCLIProject) {
- return this.project.isEmberCLIProject();
- }
-};
-
-/**
- @private
- @method _getFileInfos
- @param {Array} files
- @param {String} intoDir
- @param {Object} templateVariables
- @return {Array} file infos
-*/
-Blueprint.prototype._getFileInfos = function(files, intoDir, templateVariables) {
- return files.map(this.buildFileInfo.bind(this, destPath.bind(null, intoDir), templateVariables));
-};
-
-/**
- Add update files to ignored files
- @private
- @method _ignoreUpdateFiles
-*/
-Blueprint.prototype._ignoreUpdateFiles = function() {
- if (this.isUpdate()) {
- Blueprint.ignoredFiles = Blueprint.ignoredFiles.concat(Blueprint.ignoredUpdateFiles);
- }
-};
-
-/**
- @private
- @method _getFilesForInstall
- @param {Array} targetFiles
- @return {Array} files
-*/
-Blueprint.prototype._getFilesForInstall = function(targetFiles) {
- var files = this.files();
-
- // if we've defined targetFiles, get file info on ones that match
- return targetFiles && targetFiles.length > 0 && intersect(files, targetFiles) || files;
-};
-
-/**
- @private
- @method _checkForNoMatch
- @param {Array} fileInfos
- @param {String} rawArgs
-*/
-Blueprint.prototype._checkForNoMatch = function(fileInfos, rawArgs) {
- if (fileInfos.filter(isFilePath).length < 1 && rawArgs) {
- this.ui.writeLine(chalk.yellow('The globPattern \"' + rawArgs +
- '\" did not match any files, so no file updates will be made.'));
- }
-};
-
-function finishProcessingForInstall(infos) {
- infos.forEach(markIdenticalToBeSkipped);
-
- var infosNeedingConfirmation = infos.reduce(gatherConfirmationMessages, []);
-
- return sequence(infosNeedingConfirmation).returns(infos);
-}
-
-function finishProcessingForUninstall(infos) {
- infos.forEach(markToBeRemoved);
- return infos;
-}
-
-/**
- @method processFiles
- @param {String} intoDir
- @param {Object} templateVariables
-*/
-Blueprint.prototype.processFiles = function(intoDir, templateVariables) {
- var files = this._getFilesForInstall(templateVariables.targetFiles);
- var fileInfos = this._getFileInfos(files, intoDir, templateVariables);
- this._checkForNoMatch(fileInfos, templateVariables.rawArgs);
-
- this._ignoreUpdateFiles();
-
- return Promise.filter(fileInfos, isValidFile).
- map(prepareConfirm).
- then(finishProcessingForInstall);
-};
-
-/**
- @method processFilesForUninstall
- @param {String} intoDir
- @param {Object} templateVariables
-*/
-Blueprint.prototype.processFilesForUninstall = function(intoDir, templateVariables) {
- var fileInfos = this._getFileInfos(this.files(), intoDir, templateVariables);
-
- this._ignoreUpdateFiles();
-
- return Promise.filter(fileInfos, isValidFile).
- then(finishProcessingForUninstall);
-};
-
-
-/**
- @method mapFile
- @param {String} file
- @return {String}
-*/
-Blueprint.prototype.mapFile = function(file, locals) {
- var pattern, i;
- var fileMap = locals.fileMap || { __name__: locals.dasherizedModuleName };
- file = Blueprint.renamedFiles[file] || file;
- for (i in fileMap) {
- pattern = new RegExp(i, 'g');
- file = file.replace(pattern, fileMap[i]);
- }
- return file;
-};
-
-/**
- Looks for a __root__ token in the files folder. Must be present for
- the blueprint to support addon tokens. The `server`, `blueprints`, and `test`
-
- @private
- @method supportsAddon
- @return {Boolean}
-*/
-Blueprint.prototype.supportsAddon = function() {
- return this.files().join().match(/__root__/);
-};
-
-/**
- @private
- @method _generateFileMapVariables
- @param {Object} options
- @return {Object}
-*/
-Blueprint.prototype._generateFileMapVariables = function(moduleName, locals, options) {
- var originBlueprintName = options.originBlueprintName || this.name;
- var podModulePrefix = this.project.config().podModulePrefix || '';
- var podPath = podModulePrefix.substr(podModulePrefix.lastIndexOf('/') + 1);
- var inAddon = this.project.isEmberCLIAddon() || !!options.inRepoAddon;
- var inDummy = this.project.isEmberCLIAddon() ? options.dummy : false;
-
- return {
- pod: this.pod,
- podPath: podPath,
- hasPathToken: this.hasPathToken,
- inAddon: inAddon,
- inRepoAddon: options.inRepoAddon,
- inDummy: inDummy,
- blueprintName: this.name,
- originBlueprintName: originBlueprintName,
- dasherizedModuleName: stringUtils.dasherize(moduleName),
- locals: locals
- };
-};
-
-/**
- @private
- @method _locals
- @param {Object} options
- @return {Object}
-*/
-Blueprint.prototype._locals = function(options) {
- var packageName = options.project.name();
- var moduleName = options.entity && options.entity.name || packageName;
- var sanitizedModuleName = moduleName.replace(/\//g, '-');
-
- return new Promise(function(resolve) {
- resolve(this.locals(options));
- }.bind(this)).then(function (customLocals) {
- var fileMapVariables = this._generateFileMapVariables(moduleName, customLocals, options);
- var fileMap = this.generateFileMap(fileMapVariables);
- var standardLocals = {
- dasherizedPackageName: stringUtils.dasherize(packageName),
- classifiedPackageName: stringUtils.classify(packageName),
- dasherizedModuleName: stringUtils.dasherize(moduleName),
- classifiedModuleName: stringUtils.classify(sanitizedModuleName),
- camelizedModuleName: stringUtils.camelize(sanitizedModuleName),
- decamelizedModuleName: stringUtils.decamelize(sanitizedModuleName),
- fileMap: fileMap,
- hasPathToken: this.hasPathToken,
- targetFiles: options.targetFiles,
- rawArgs: options.rawArgs
- };
-
- return merge({}, standardLocals, customLocals);
- }.bind(this));
-};
-
-/**
- Used to add a package to the project's `package.json`.
-
- Generally, this would be done from the `afterInstall` hook, to
- ensure that a package that is required by a given blueprint is
- available.
-
- @method addPackageToProject
- @param {String} packageName
- @param {String} target
- @return {Promise}
-*/
-Blueprint.prototype.addPackageToProject = function(packageName, target) {
- var packageObject = {name: packageName};
-
- if (target) {
- packageObject.target = target;
- }
-
- return this.addPackagesToProject([packageObject]);
-};
-
-/**
- Used to add multiple packages to the project's `package.json`.
-
- Generally, this would be done from the `afterInstall` hook, to
- ensure that a package that is required by a given blueprint is
- available.
-
- Expects each array item to be an object with a `name`. Each object
- may optionally have a `target` to specify a specific version.
-
- @method addPackagesToProject
- @param {Array} packages
- @return {Promise}
-*/
-Blueprint.prototype.addPackagesToProject = function(packages) {
- var task = this.taskFor('npm-install');
- var installText = (packages.length > 1) ? 'install packages' : 'install package';
- var packageNames = [];
- var packageArray = [];
-
- for (var i = 0; i < packages.length; i++) {
- packageNames.push(packages[i].name);
-
- var packageNameAndVersion = packages[i].name;
-
- if (packages[i].target) {
- packageNameAndVersion += '@' + packages[i].target;
- }
-
- packageArray.push(packageNameAndVersion);
- }
-
- this._writeStatusToUI(chalk.green, installText, packageNames.join(', '));
-
- return task.run({
- 'save-dev': true,
- verbose: false,
- packages: packageArray
- });
-};
-
-/**
- Used to remove a package from the project's `package.json`.
-
- Generally, this would be done from the `afterInstall` hook, to
- ensure that any package conflicts can be resolved before the
- addon is used.
-
- @method removePackageFromProject
- @param {String} packageName
- @return {Promise}
-*/
-Blueprint.prototype.removePackageFromProject = function(packageName) {
- var packageObject = {name: packageName};
-
- return this.removePackagesFromProject([packageObject]);
-};
-
-/**
- Used to remove multiple packages from the project's `package.json`.
-
- Generally, this would be done from the `afterInstall` hook, to
- ensure that any package conflicts can be resolved before the
- addon is used.
-
- Expects each array item to be an object with a `name` property.
-
- @method removePackagesFromProject
- @param {Array} packages
- @return {Promise}
-*/
-Blueprint.prototype.removePackagesFromProject = function(packages) {
- var task = this.taskFor('npm-uninstall');
- var installText = (packages.length > 1) ? 'uninstall packages' : 'uninstall package';
- var packageNames = [];
- var packageArray = [];
-
- for (var i = 0; i < packages.length; i++) {
- packageNames.push(packages[i].name);
-
- var packageNameAndVersion = packages[i].name;
-
- packageArray.push(packageNameAndVersion);
- }
-
- this._writeStatusToUI(chalk.green, installText, packageNames.join(', '));
-
- return task.run({
- 'save-dev': true,
- verbose: false,
- packages: packageArray
- });
-};
-
-/**
- Used to add a package to the projects `bower.json`.
-
- Generally, this would be done from the `afterInstall` hook, to
- ensure that a package that is required by a given blueprint is
- available.
-
- `localPackageName` and `target` may be thought of as equivalent
- to the key-value pairs in the `dependency` or `devDepencency`
- objects contained within a bower.json file.
-
- Examples:
-
- addBowerPackageToProject('jquery', '~1.11.1');
- addBowerPackageToProject('old_jquery', 'jquery#~1.9.1');
- addBowerPackageToProject('bootstrap-3', 'http://twitter.github.io/bootstrap/assets/bootstrap');
-
- @method addBowerPackageToProject
- @param {String} localPackageName
- @param {String} target
- @param {Object} installOptions
- @return {Promise}
-*/
-Blueprint.prototype.addBowerPackageToProject = function(localPackageName, target, installOptions) {
- // var lpn = localPackageName;
- // var tar = target;
- // if (localPackageName.indexOf('#') >= 0) {
- // if (arguments.length === 1) {
- // var parts = localPackageName.split('#');
- // lpn = parts[0];
- // tar = parts[1];
- // this.ui.writeDeprecateLine('passing ' + localPackageName +
- // ' directly to `addBowerPackageToProject` will soon be unsupported. \n' +
- // 'You may want to replace this with ' +
- // '`addBowerPackageToProject(\'' + lpn + '\', \'' + tar + '\')`');
- // } else {
- // this.ui.writeDeprecateLine('passing ' + localPackageName +
- // ' directly to `addBowerPackageToProject` will soon be unsupported');
- // }
- // }
- // var packageObject = bowEpParser.json2decomposed(lpn, tar);
- // return this.addBowerPackagesToProject([packageObject], installOptions);
- return Promise.resolve();
-};
-
-/**
- Used to add an array of packages to the projects `bower.json`.
-
- Generally, this would be done from the `afterInstall` hook, to
- ensure that a package that is required by a given blueprint is
- available.
-
- Expects each array item to be an object with a `name`. Each object
- may optionally have a `target` to specify a specific version.
-
- @method addBowerPackagesToProject
- @param {Array} packages
- @param {Object} installOptions
- @return {Promise}
-*/
-Blueprint.prototype.addBowerPackagesToProject = function(packages, installOptions) {
- var task = this.taskFor('bower-install');
- var installText = (packages.length > 1) ? 'install bower packages' : 'install bower package';
- var packageNames = [];
- var packageNamesAndVersions = packages.map(function (pkg) {
- pkg.source = pkg.source || pkg.name;
- packageNames.push(pkg.name);
- return pkg;
- }).map(bowEpParser.compose);
-
- this._writeStatusToUI(chalk.green, installText, packageNames.join(', '));
-
- return task.run({
- verbose: true,
- packages: packageNamesAndVersions,
- installOptions: installOptions
- });
-};
-
-/**
- Used to retrieve a task with the given name. Passes the new task
- the standard information available (like `ui`, `analytics`, `project`, etc).
-
- @method taskFor
- @param dasherizedName
- @public
-*/
-Blueprint.prototype.taskFor = function(dasherizedName) {
- var Task = require('../tasks/' + dasherizedName);
-
- return new Task({
- ui: this.ui,
- project: this.project,
- analytics: this.analytics
- });
-};
-
-/*
-
- Inserts the given content into a file. If the `contentsToInsert` string is already
- present in the current contents, the file will not be changed unless `force` option
- is passed.
-
- If `options.before` is specified, `contentsToInsert` will be inserted before
- the first instance of that string. If `options.after` is specified, the
- contents will be inserted after the first instance of that string.
- If the string specified by options.before or options.after is not in the file,
- no change will be made.
-
- If neither `options.before` nor `options.after` are present, `contentsToInsert`
- will be inserted at the end of the file.
-
- Example:
- ```
- // app/router.js
- Router.map(function() {
- });
-
- insertIntoFile('app/router.js',
- ' this.route("admin");',
- {after:'Router.map(function() {'+EOL});
-
- // new app/router.js
- Router.map(function() {
- this.route("admin");
- });
- ```
-
- @method insertIntoFile
- @param {String} pathRelativeToProjectRoot
- @param {String} contentsToInsert
- @param {Object} options
- @return {Promise}
-*/
-Blueprint.prototype.insertIntoFile = function(pathRelativeToProjectRoot, contentsToInsert, providedOptions) {
- var fullPath = path.join(this.project.root, pathRelativeToProjectRoot);
- var originalContents = '';
-
- if (existsSync(fullPath)) {
- originalContents = fs.readFileSync(fullPath, { encoding: 'utf8' });
- }
-
- var contentsToWrite = originalContents;
-
- var options = providedOptions || {};
- var alreadyPresent = originalContents.indexOf(contentsToInsert) > -1;
- var insert = !alreadyPresent;
- var insertBehavior = 'end';
-
- if (options.before) { insertBehavior = 'before'; }
- if (options.after) { insertBehavior = 'after'; }
-
- if (options.force) { insert = true; }
-
- if (insert) {
- if (insertBehavior === 'end') {
- contentsToWrite += contentsToInsert;
- } else {
- var contentMarker = options[insertBehavior];
- var contentMarkerIndex = contentsToWrite.indexOf(contentMarker);
-
- if (contentMarkerIndex !== -1) {
- var insertIndex = contentMarkerIndex;
- if (insertBehavior === 'after') { insertIndex += contentMarker.length; }
-
- contentsToWrite = contentsToWrite.slice(0, insertIndex) +
- contentsToInsert + EOL +
- contentsToWrite.slice(insertIndex);
- }
- }
- }
-
- var returnValue = {
- path: fullPath,
- originalContents: originalContents,
- contents: contentsToWrite,
- inserted: false
- };
-
- if (contentsToWrite !== originalContents) {
- returnValue.inserted = true;
-
- return writeFile(fullPath, contentsToWrite)
- .then(function() {
- return returnValue;
- });
- } else {
- return Promise.resolve(returnValue);
- }
-};
-
-Blueprint.prototype._printCommand = printCommand;
-
-Blueprint.prototype.printBasicHelp = function(verbose) {
- var initialMargin = ' ';
- var output = initialMargin;
- if (this.overridden) {
- output += chalk.grey('(overridden) ' + this.name);
- } else {
- output += this.name;
-
- output += this._printCommand(initialMargin, true);
-
- if (verbose) {
- output += EOL + this.printDetailedHelp(this.availableOptions);
- }
- }
-
- return output;
-};
-
-Blueprint.prototype.printDetailedHelp = function() {
- var markdownColor = new MarkdownColor();
- var filePath = getDetailedHelpPath(this.path);
-
- if (existsSync(filePath)) {
- return markdownColor.renderFile(filePath, { indent: ' ' });
- }
- return '';
-};
-
-Blueprint.prototype.getJson = function(verbose) {
- var json = {};
-
- printableProperties.forEachWithProperty(function(key) {
- var value = this[key];
- if (key === 'availableOptions') {
- value = cloneDeep(value);
- value.forEach(function(option) {
- if (typeof option.type === 'function') {
- option.type = option.type.name;
- }
- });
- }
- json[key] = value;
- }, this);
-
- if (verbose) {
- var detailedHelp = this.printDetailedHelp(this.availableOptions);
- if (detailedHelp) {
- json.detailedHelp = detailedHelp;
- }
- }
-
- return json;
-};
-
-/**
- Used to retrieve a blueprint with the given name.
-
- @method lookupBlueprint
- @param dasherizedName
- @public
-*/
-Blueprint.prototype.lookupBlueprint = function(dasherizedName) {
- var projectPaths = this.project ? this.project.blueprintLookupPaths() : [];
-
- return Blueprint.lookup(dasherizedName, {
- paths: projectPaths
- });
-};
-
-/**
- @static
- @method lookup
- @namespace Blueprint
- @param {String} [name]
- @param {Object} [options]
- @param {Array} [options.paths] Extra paths to search for blueprints
- @param {Object} [options.properties] Properties
- @return {Blueprint}
-*/
-Blueprint.lookup = function(name, options) {
- options = options || {};
-
- var lookupPaths = generateLookupPaths(options.paths);
-
- var lookupPath;
- var blueprintPath;
-
- for (var i = 0; (lookupPath = lookupPaths[i]); i++) {
- blueprintPath = path.resolve(lookupPath, name);
-
- if (existsSync(blueprintPath)) {
- return Blueprint.load(blueprintPath);
- }
- }
-
- if (!options.ignoreMissing) {
- throw new SilentError('Unknown blueprint: ' + name);
- }
-};
-
-/**
- Loads a blueprint from given path.
- @static
- @method load
- @namespace Blueprint
- @param {String} blueprintPath
- @return {Blueprint} blueprint instance
-*/
-Blueprint.load = function(blueprintPath) {
- var constructorPath = path.resolve(blueprintPath, 'index.js');
- var blueprintModule;
- var Constructor = Blueprint;
-
- if (fs.lstatSync(blueprintPath).isDirectory()) {
-
- if (existsSync(constructorPath)) {
- blueprintModule = require(constructorPath);
-
- if (typeof blueprintModule === 'function') {
- Constructor = blueprintModule;
- } else {
- Constructor = Blueprint.extend(blueprintModule);
- }
- }
-
- return new Constructor(blueprintPath);
- }
-
- return;
-};
-
-/**
- @static
- @method list
- @namespace Blueprint
- @param {Object} [options]
- @param {Array} [options.paths] Extra paths to search for blueprints
- @return {Blueprint}
-*/
-Blueprint.list = function(options) {
- options = options || {};
-
- var lookupPaths = generateLookupPaths(options.paths);
- var seen = [];
-
- return lookupPaths.map(function(lookupPath) {
- var blueprints = dir(lookupPath);
- var packagePath = path.join(lookupPath, '../package.json');
- var source;
-
- if (existsSync(packagePath)) {
- source = require(packagePath).name;
- } else {
- source = path.basename(path.join(lookupPath, '..'));
- }
-
- blueprints = blueprints.map(function(blueprintPath) {
- var blueprint = Blueprint.load(blueprintPath);
- var name;
-
- if (blueprint) {
- name = blueprint.name;
- blueprint.overridden = includes(seen, name);
- seen.push(name);
-
- return blueprint;
- }
-
- return;
- });
-
- return {
- source: source,
- blueprints: compact(blueprints)
- };
- });
-};
-
-/**
- @static
- @property renameFiles
-*/
-Blueprint.renamedFiles = {
- 'gitignore': '.gitignore'
-};
-
-/**
- @static
- @property ignoredFiles
-*/
-Blueprint.ignoredFiles = [
- '.DS_Store'
-];
-
-/**
- @static
- @property ignoredUpdateFiles
-*/
-Blueprint.ignoredUpdateFiles = [
- '.gitkeep',
- 'app.css'
-];
-
-/**
- @static
- @property defaultLookupPaths
-*/
-Blueprint.defaultLookupPaths = function() {
- return [
- path.resolve(__dirname, '..', '..', 'blueprints')
- ];
-};
-
-/**
- @private
- @method prepareConfirm
- @param {FileInfo} info
- @return {Promise}
-*/
-function prepareConfirm(info) {
- return info.checkForConflict().then(function(resolution) {
- info.resolution = resolution;
- return info;
- });
-}
-
-/**
- @private
- @method markIdenticalToBeSkipped
- @param {FileInfo} info
-*/
-function markIdenticalToBeSkipped(info) {
- if (info.resolution === 'identical') {
- info.action = 'skip';
- }
-}
-
-/**
- @private
- @method markToBeRemoved
- @param {FileInfo} info
-*/
-function markToBeRemoved(info) {
- info.action = 'remove';
-}
-
-/**
- @private
- @method gatherConfirmationMessages
- @param {Array} collection
- @param {FileInfo} info
- @return {Array}
-*/
-function gatherConfirmationMessages(collection, info) {
- if (info.resolution === 'confirm') {
- collection.push(info.confirmOverwriteTask());
- }
- return collection;
-}
-
-/**
- @private
- @method isFile
- @param {FileInfo} info
- @return {Boolean}
-*/
-function isFile(info) {
- return stat(info.inputPath).invoke('isFile');
-}
-
-/**
- @private
- @method isIgnored
- @param {FileInfo} info
- @return {Boolean}
-*/
-function isIgnored(info) {
- var fn = info.inputPath;
-
- return any(Blueprint.ignoredFiles, function(ignoredFile) {
- return minimatch(fn, ignoredFile, { matchBase: true });
- });
-}
-
-/**
- Combines provided lookup paths with defaults and removes
- duplicates.
-
- @private
- @method generateLookupPaths
- @param {Array} lookupPaths
- @return {Array}
-*/
-function generateLookupPaths(lookupPaths) {
- lookupPaths = lookupPaths || [];
- lookupPaths = lookupPaths.concat(Blueprint.defaultLookupPaths());
- return uniq(lookupPaths);
-}
-
-/**
- Looks for a __path__ token in the files folder. Must be present for
- the blueprint to support pod tokens.
-
- @private
- @method hasPathToken
- @param {files} files
- @return {Boolean}
-*/
-function hasPathToken(files) {
- return files.join().match(/__path__/);
-}
-
-function inRepoAddonExists(name, root) {
- var addonPath = path.join(root, 'lib', name);
- return existsSync(addonPath);
-}
-
-function podDeprecations(config, ui) {
- /*
- var podModulePrefix = config.podModulePrefix || '';
- var podPath = podModulePrefix.substr(podModulePrefix.lastIndexOf('/') + 1);
- // Disabled until we are ready to deprecate podModulePrefix
- deprecateUI(ui)('`podModulePrefix` is deprecated and will be removed from future versions of ember-cli.'+
- ' Please move existing pods from \'app/' + podPath + '/\' to \'app/\'.', config.podModulePrefix);
- */
- if (config.usePodsByDefault) {
- ui.writeDeprecateLine('`usePodsByDefault` is no longer supported in \'config/environment.js\',' +
- ' use `usePods` in \'.ember-cli\' instead.');
- }
-}
-
-/**
- @private
- @method destPath
- @param {String} intoDir
- @param {String} file
- @return {String} new path
-*/
-function destPath(intoDir, file) {
- return path.join(intoDir, file);
-}
-
-/**
- @private
- @method isValidFile
- @param {Object} fileInfo
- @return {Promise}
-*/
-function isValidFile(fileInfo) {
- if (isIgnored(fileInfo)) {
- return Promise.resolve(false);
- } else {
- return isFile(fileInfo);
- }
-}
-
-/**
- @private
- @method isFilePath
- @param {Object} fileInfo
- @return {Promise}
-*/
-function isFilePath(fileInfo) {
- return fs.statSync(fileInfo.inputPath).isFile();
-}
-
-/**
- @private
- @method dir
- @returns {Array} list of files in the given directory or and empty array if no directory exists
-*/
-function dir(fullPath) {
- if (existsSync(fullPath)) {
- return fs.readdirSync(fullPath).map(function(fileName) {
- return path.join(fullPath, fileName);
- });
- } else {
- return [];
- }
-}
-
-/**
- @private
- @method getDetailedHelpPath
- @param {String} thisPath
- @return {String} help path
-*/
-function getDetailedHelpPath(thisPath) {
- return path.join(thisPath, './HELP.md');
-}
diff --git a/packages/angular-cli/utilities/INITIAL_COMMIT_MESSAGE.txt b/packages/angular-cli/utilities/INITIAL_COMMIT_MESSAGE.txt
deleted file mode 100644
index 0c4e93225506..000000000000
--- a/packages/angular-cli/utilities/INITIAL_COMMIT_MESSAGE.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-chore: initial commit from angular-cli
- _ _ _
- __ _ _ __ __ _ _ _| | __ _ _ __ ___| (_)
- / _ | _ \ / _ | | | | |/ _ | __|____ / __| | |
- | (_| | | | | (_| | |_| | | (_| | | |_____| (__| | |
- \____|_| |_|\__ |\____|_|\____|_| \___|_|_|
- |___/
-
\ No newline at end of file
diff --git a/packages/angular-cli/addon/index.js b/packages/universal-cli/addon/index.js
similarity index 98%
rename from packages/angular-cli/addon/index.js
rename to packages/universal-cli/addon/index.js
index 8b294f9a2718..14a2a7a36953 100644
--- a/packages/angular-cli/addon/index.js
+++ b/packages/universal-cli/addon/index.js
@@ -5,7 +5,7 @@ const config = require('../models/config');
const path = require('path');
module.exports = {
- name: 'ng2',
+ name: 'ung',
config: function () {
this.project.ngConfigObj = this.project.ngConfigObj || config.CliConfig.fromProject();
diff --git a/packages/angular-cli/bin/ng b/packages/universal-cli/bin/ung
similarity index 90%
rename from packages/angular-cli/bin/ng
rename to packages/universal-cli/bin/ung
index 7739921364c4..51b16d800585 100755
--- a/packages/angular-cli/bin/ng
+++ b/packages/universal-cli/bin/ung
@@ -2,7 +2,7 @@
'use strict';
// Provide a title to the process in `ps`
-process.title = 'angular-cli';
+process.title = 'universal-cli';
const resolve = require('resolve');
const packageJson = require('../package.json');
@@ -10,14 +10,14 @@ const Leek = require('leek');
const Version = require('../upgrade/version').Version;
-resolve('angular-cli', { basedir: process.cwd() },
+resolve('universal-cli', { basedir: process.cwd() },
function (error, projectLocalCli) {
var cli;
if (error) {
// If there is an error, resolve could not find the ng-cli
// library from a package.json. Instead, include it from a relative
// path to this script file (which is likely a globally installed
- // npm package). Most common cause for hitting this is `ng new`
+ // npm package). Most common cause for hitting this is `ung new`
cli = require('../lib/cli');
} else {
// Verify that package's version.
diff --git a/packages/angular-cli/blueprints/class/files/__path__/__name__.spec.ts b/packages/universal-cli/blueprints/class/files/__path__/__name__.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/class/files/__path__/__name__.spec.ts
rename to packages/universal-cli/blueprints/class/files/__path__/__name__.spec.ts
diff --git a/packages/angular-cli/blueprints/class/files/__path__/__name__.ts b/packages/universal-cli/blueprints/class/files/__path__/__name__.ts
similarity index 100%
rename from packages/angular-cli/blueprints/class/files/__path__/__name__.ts
rename to packages/universal-cli/blueprints/class/files/__path__/__name__.ts
diff --git a/packages/angular-cli/blueprints/class/index.js b/packages/universal-cli/blueprints/class/index.js
similarity index 100%
rename from packages/angular-cli/blueprints/class/index.js
rename to packages/universal-cli/blueprints/class/index.js
diff --git a/packages/angular-cli/blueprints/component/files/__path__/__name__.component.__styleext__ b/packages/universal-cli/blueprints/component/files/__path__/__name__.component.__styleext__
similarity index 100%
rename from packages/angular-cli/blueprints/component/files/__path__/__name__.component.__styleext__
rename to packages/universal-cli/blueprints/component/files/__path__/__name__.component.__styleext__
diff --git a/packages/angular-cli/blueprints/component/files/__path__/__name__.component.html b/packages/universal-cli/blueprints/component/files/__path__/__name__.component.html
similarity index 100%
rename from packages/angular-cli/blueprints/component/files/__path__/__name__.component.html
rename to packages/universal-cli/blueprints/component/files/__path__/__name__.component.html
diff --git a/packages/angular-cli/blueprints/component/files/__path__/__name__.component.spec.ts b/packages/universal-cli/blueprints/component/files/__path__/__name__.component.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/component/files/__path__/__name__.component.spec.ts
rename to packages/universal-cli/blueprints/component/files/__path__/__name__.component.spec.ts
diff --git a/packages/angular-cli/blueprints/component/files/__path__/__name__.component.ts b/packages/universal-cli/blueprints/component/files/__path__/__name__.component.ts
similarity index 100%
rename from packages/angular-cli/blueprints/component/files/__path__/__name__.component.ts
rename to packages/universal-cli/blueprints/component/files/__path__/__name__.component.ts
diff --git a/packages/angular-cli/blueprints/component/index.js b/packages/universal-cli/blueprints/component/index.js
similarity index 89%
rename from packages/angular-cli/blueprints/component/index.js
rename to packages/universal-cli/blueprints/component/index.js
index 92556d32fabb..113d9e194abb 100644
--- a/packages/angular-cli/blueprints/component/index.js
+++ b/packages/universal-cli/blueprints/component/index.js
@@ -24,7 +24,7 @@ module.exports = {
beforeInstall: function(options) {
try {
- this.pathToModule = findParentModule(this.project, this.dynamicPath.dir);
+ this.modulePaths = findParentModule(this.project, this.dynamicPath.dir);
} catch(e) {
if (!options.skipImport) {
throw `Error locating module for declaration\n\t${e}`;
@@ -134,7 +134,7 @@ module.exports = {
};
},
- afterInstall: function(options) {
+ afterInstall: function (options) {
if (options.dryRun) {
return;
}
@@ -142,14 +142,17 @@ module.exports = {
const returns = [];
const className = stringUtils.classify(`${options.entity.name}Component`);
const fileName = stringUtils.dasherize(`${options.entity.name}.component`);
- const componentDir = path.relative(path.dirname(this.pathToModule), this.generatePath);
- const importPath = componentDir ? `./${componentDir}/${fileName}` : `./${fileName}`;
- if (!options.skipImport) {
- returns.push(
- astUtils.addDeclarationToModule(this.pathToModule, className, importPath)
- .then(change => change.apply(NodeHost)));
- }
+ this.modulePaths.forEach((pathToModule) => {
+ const componentDir = path.relative(path.dirname(pathToModule), this.generatePath);
+ const importPath = componentDir ? `./${componentDir}/${fileName}` : `./${fileName}`;
+
+ if (!options.skipImport) {
+ returns.push(
+ astUtils.addDeclarationToModule(pathToModule, className, importPath)
+ .then(change => change.apply(NodeHost)));
+ }
+ });
return Promise.all(returns);
}
diff --git a/packages/angular-cli/blueprints/directive/files/__path__/__name__.directive.spec.ts b/packages/universal-cli/blueprints/directive/files/__path__/__name__.directive.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/directive/files/__path__/__name__.directive.spec.ts
rename to packages/universal-cli/blueprints/directive/files/__path__/__name__.directive.spec.ts
diff --git a/packages/angular-cli/blueprints/directive/files/__path__/__name__.directive.ts b/packages/universal-cli/blueprints/directive/files/__path__/__name__.directive.ts
similarity index 100%
rename from packages/angular-cli/blueprints/directive/files/__path__/__name__.directive.ts
rename to packages/universal-cli/blueprints/directive/files/__path__/__name__.directive.ts
diff --git a/packages/angular-cli/blueprints/directive/index.js b/packages/universal-cli/blueprints/directive/index.js
similarity index 80%
rename from packages/angular-cli/blueprints/directive/index.js
rename to packages/universal-cli/blueprints/directive/index.js
index 062ca02a9645..0399f8f5ce7d 100644
--- a/packages/angular-cli/blueprints/directive/index.js
+++ b/packages/universal-cli/blueprints/directive/index.js
@@ -19,7 +19,7 @@ module.exports = {
beforeInstall: function(options) {
try {
- this.pathToModule = findParentModule(this.project, this.dynamicPath.dir);
+ this.modulePaths = findParentModule(this.project, this.dynamicPath.dir);
} catch(e) {
if (!options.skipImport) {
throw `Error locating module for declaration\n\t${e}`;
@@ -83,7 +83,7 @@ module.exports = {
};
},
- afterInstall: function(options) {
+ afterInstall: function (options) {
if (options.dryRun) {
return;
}
@@ -91,16 +91,19 @@ module.exports = {
const returns = [];
const className = stringUtils.classify(`${options.entity.name}Directive`);
const fileName = stringUtils.dasherize(`${options.entity.name}.directive`);
- const fullGeneratePath = path.join(this.project.root, this.generatePath);
- const moduleDir = path.parse(this.pathToModule).dir;
- const relativeDir = path.relative(moduleDir, fullGeneratePath);
- const importPath = relativeDir ? `./${relativeDir}/${fileName}` : `./${fileName}`;
-
- if (!options.skipImport) {
- returns.push(
- astUtils.addDeclarationToModule(this.pathToModule, className, importPath)
- .then(change => change.apply(NodeHost)));
- }
+
+ this.modulePaths.forEach((pathToModule) => {
+ const fullGeneratePath = path.join(this.project.root, this.generatePath);
+ const moduleDir = path.parse(pathToModule).dir;
+ const relativeDir = path.relative(moduleDir, fullGeneratePath);
+ const importPath = relativeDir ? `./${relativeDir}/${fileName}` : `./${fileName}`;
+
+ if (!options.skipImport) {
+ returns.push(
+ astUtils.addDeclarationToModule(pathToModule, className, importPath)
+ .then(change => change.apply(NodeHost)));
+ }
+ });
return Promise.all(returns);
}
diff --git a/packages/angular-cli/blueprints/enum/files/__path__/__name__.enum.ts b/packages/universal-cli/blueprints/enum/files/__path__/__name__.enum.ts
similarity index 100%
rename from packages/angular-cli/blueprints/enum/files/__path__/__name__.enum.ts
rename to packages/universal-cli/blueprints/enum/files/__path__/__name__.enum.ts
diff --git a/packages/angular-cli/blueprints/enum/index.js b/packages/universal-cli/blueprints/enum/index.js
similarity index 100%
rename from packages/angular-cli/blueprints/enum/index.js
rename to packages/universal-cli/blueprints/enum/index.js
diff --git a/packages/angular-cli/blueprints/interface/files/__path__/__name__.ts b/packages/universal-cli/blueprints/interface/files/__path__/__name__.ts
similarity index 100%
rename from packages/angular-cli/blueprints/interface/files/__path__/__name__.ts
rename to packages/universal-cli/blueprints/interface/files/__path__/__name__.ts
diff --git a/packages/angular-cli/blueprints/interface/index.js b/packages/universal-cli/blueprints/interface/index.js
similarity index 100%
rename from packages/angular-cli/blueprints/interface/index.js
rename to packages/universal-cli/blueprints/interface/index.js
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-144x144.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-144x144.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-144x144.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-144x144.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-192x192.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-192x192.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-192x192.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-192x192.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-36x36.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-36x36.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-36x36.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-36x36.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-48x48.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-48x48.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-48x48.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-48x48.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-72x72.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-72x72.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-72x72.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-72x72.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-96x96.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-96x96.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/android-chrome-96x96.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/android-chrome-96x96.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-114x114.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-114x114.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-114x114.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-114x114.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-120x120.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-120x120.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-120x120.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-120x120.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-144x144.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-144x144.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-144x144.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-144x144.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-152x152.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-152x152.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-152x152.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-152x152.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-180x180.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-180x180.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-180x180.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-180x180.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-57x57.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-57x57.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-57x57.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-57x57.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-60x60.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-60x60.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-60x60.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-60x60.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-72x72.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-72x72.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-72x72.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-72x72.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-76x76.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-76x76.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-76x76.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-76x76.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-precomposed.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-precomposed.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-precomposed.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon-precomposed.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/apple-touch-icon.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/favicon-16x16.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/favicon-16x16.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/favicon-16x16.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/favicon-16x16.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/favicon-32x32.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/favicon-32x32.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/favicon-32x32.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/favicon-32x32.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/favicon-96x96.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/favicon-96x96.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/favicon-96x96.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/favicon-96x96.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/icon.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/icon.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/icon.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/icon.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-144x144.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-144x144.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-144x144.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-144x144.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-150x150.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-150x150.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-150x150.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-150x150.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-310x150.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-310x150.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-310x150.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-310x150.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-310x310.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-310x310.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-310x310.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-310x310.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-70x70.png b/packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-70x70.png
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/mstile-70x70.png
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/mstile-70x70.png
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/icons/safari-pinned-tab.svg b/packages/universal-cli/blueprints/mobile/files/__path__/icons/safari-pinned-tab.svg
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/icons/safari-pinned-tab.svg
rename to packages/universal-cli/blueprints/mobile/files/__path__/icons/safari-pinned-tab.svg
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/main-app-shell.ts b/packages/universal-cli/blueprints/mobile/files/__path__/main-app-shell.ts
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/main-app-shell.ts
rename to packages/universal-cli/blueprints/mobile/files/__path__/main-app-shell.ts
diff --git a/packages/angular-cli/blueprints/mobile/files/__path__/manifest.webapp b/packages/universal-cli/blueprints/mobile/files/__path__/manifest.webapp
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/files/__path__/manifest.webapp
rename to packages/universal-cli/blueprints/mobile/files/__path__/manifest.webapp
diff --git a/packages/angular-cli/blueprints/mobile/index.js b/packages/universal-cli/blueprints/mobile/index.js
similarity index 100%
rename from packages/angular-cli/blueprints/mobile/index.js
rename to packages/universal-cli/blueprints/mobile/index.js
diff --git a/packages/angular-cli/blueprints/module/files/__path__/__name__-routing.module.ts b/packages/universal-cli/blueprints/module/files/__path__/__name__-routing.module.ts
similarity index 100%
rename from packages/angular-cli/blueprints/module/files/__path__/__name__-routing.module.ts
rename to packages/universal-cli/blueprints/module/files/__path__/__name__-routing.module.ts
diff --git a/packages/angular-cli/blueprints/module/files/__path__/__name__.module.spec.ts b/packages/universal-cli/blueprints/module/files/__path__/__name__.module.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/module/files/__path__/__name__.module.spec.ts
rename to packages/universal-cli/blueprints/module/files/__path__/__name__.module.spec.ts
diff --git a/packages/angular-cli/blueprints/module/files/__path__/__name__.module.ts b/packages/universal-cli/blueprints/module/files/__path__/__name__.module.ts
similarity index 100%
rename from packages/angular-cli/blueprints/module/files/__path__/__name__.module.ts
rename to packages/universal-cli/blueprints/module/files/__path__/__name__.module.ts
diff --git a/packages/angular-cli/blueprints/module/index.js b/packages/universal-cli/blueprints/module/index.js
similarity index 100%
rename from packages/angular-cli/blueprints/module/index.js
rename to packages/universal-cli/blueprints/module/index.js
diff --git a/packages/angular-cli/blueprints/ng2/files/.editorconfig b/packages/universal-cli/blueprints/ng2/files/.editorconfig
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/.editorconfig
rename to packages/universal-cli/blueprints/ng2/files/.editorconfig
diff --git a/packages/universal-cli/blueprints/ng2/files/README.md b/packages/universal-cli/blueprints/ng2/files/README.md
new file mode 100755
index 000000000000..1fabd5a79f3e
--- /dev/null
+++ b/packages/universal-cli/blueprints/ng2/files/README.md
@@ -0,0 +1,31 @@
+# <%= jsComponentName %>
+
+This project was generated with [universal-cli](https://github.com/devCrossNet/universal-cli) version <%= version %>.
+
+## Development server
+Run `ung serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
+
+## Code scaffolding
+
+Run `ung generate component component-name` to generate a new component. You can also use `ung generate directive/pipe/service/class`.
+
+## Build
+
+Run `ung build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
+
+## Running unit tests
+
+Run `ung test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+
+## Running end-to-end tests
+
+Run `ung e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
+Before running the tests make sure you are serving the app via `ung serve`.
+
+## Deploying to Github Pages
+
+Run `ung github-pages:deploy` to deploy to Github Pages.
+
+## Further help
+
+To get more help on the `universal-cli` use `ung --help` or go check out the [Universal-CLI README](https://github.com/devCrossNet/universal-cli/blob/master/README.md).
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/app/app-routing.module.ts b/packages/universal-cli/blueprints/ng2/files/__path__/app/app-routing.module.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/app/app-routing.module.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/app/app-routing.module.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.__styleext__ b/packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.__styleext__
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.__styleext__
rename to packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.__styleext__
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.html b/packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.html
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.html
rename to packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.html
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.spec.ts b/packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.spec.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.spec.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.ts b/packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/app/app.component.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/app/app.component.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/app/app.module.ts b/packages/universal-cli/blueprints/ng2/files/__path__/app/app.module.ts
similarity index 54%
rename from packages/angular-cli/blueprints/ng2/files/__path__/app/app.module.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/app/app.module.ts
index 51485d6538e3..21486bfbe784 100644
--- a/packages/angular-cli/blueprints/ng2/files/__path__/app/app.module.ts
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/app/app.module.ts
@@ -1,4 +1,6 @@
-import { BrowserModule } from '@angular/platform-browser';
+<% if(!universal) { %>
+import { BrowserModule } from '@angular/platform-browser';<% } else { %>
+import { CommonModule } from '@angular/common';<% } %>
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';<% if (routing) { %>
@@ -10,13 +12,15 @@ import { AppComponent } from './app.component';
declarations: [
AppComponent
],
- imports: [
- BrowserModule,
+ imports: [<% if(!universal) { %>
+ BrowserModule,<% } else { %>
+ CommonModule,<% } %>
FormsModule,
HttpModule<% if (routing) { %>,
AppRoutingModule<% } %>
],
- providers: [],
- bootstrap: [AppComponent]
+ providers: [],<% if(universal) { %>
+ exports: [AppComponent]<% } else { %>
+ bootstrap: [AppComponent]<% } %>
})
export class AppModule { }
diff --git a/packages/universal-cli/blueprints/ng2/files/__path__/app/index.ts b/packages/universal-cli/blueprints/ng2/files/__path__/app/index.ts
new file mode 100644
index 000000000000..1e84369cbdfb
--- /dev/null
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/app/index.ts
@@ -0,0 +1,2 @@
+export * from './app.component';<% if(!universal) { %>
+export * from './app.module';<% } %>
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/assets/.gitkeep b/packages/universal-cli/blueprints/ng2/files/__path__/assets/.gitkeep
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/assets/.gitkeep
rename to packages/universal-cli/blueprints/ng2/files/__path__/assets/.gitkeep
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/environments/environment.prod.ts b/packages/universal-cli/blueprints/ng2/files/__path__/environments/environment.prod.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/environments/environment.prod.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/environments/environment.prod.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/environments/environment.ts b/packages/universal-cli/blueprints/ng2/files/__path__/environments/environment.ts
similarity index 80%
rename from packages/angular-cli/blueprints/ng2/files/__path__/environments/environment.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/environments/environment.ts
index 00313f16648e..2c3e356cabe2 100644
--- a/packages/angular-cli/blueprints/ng2/files/__path__/environments/environment.ts
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/environments/environment.ts
@@ -1,6 +1,6 @@
// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
-// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// `ung build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `angular-cli.json`.
export const environment = {
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/favicon.ico b/packages/universal-cli/blueprints/ng2/files/__path__/favicon.ico
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/favicon.ico
rename to packages/universal-cli/blueprints/ng2/files/__path__/favicon.ico
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/index.html b/packages/universal-cli/blueprints/ng2/files/__path__/index.html
similarity index 93%
rename from packages/angular-cli/blueprints/ng2/files/__path__/index.html
rename to packages/universal-cli/blueprints/ng2/files/__path__/index.html
index 1f8c4ad70d2d..4706edbde256 100644
--- a/packages/angular-cli/blueprints/ng2/files/__path__/index.html
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/index.html
@@ -22,6 +22,7 @@
<% } %>
+ <% if (universal) { %><% } %>
<<%= prefix %>-root>Loading...<%= prefix %>-root>
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/main.ts b/packages/universal-cli/blueprints/ng2/files/__path__/main.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/main.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/main.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/polyfills.ts b/packages/universal-cli/blueprints/ng2/files/__path__/polyfills.ts
similarity index 77%
rename from packages/angular-cli/blueprints/ng2/files/__path__/polyfills.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/polyfills.ts
index 3b4c55b09656..96564549cf9a 100644
--- a/packages/angular-cli/blueprints/ng2/files/__path__/polyfills.ts
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/polyfills.ts
@@ -1,5 +1,7 @@
// This file includes polyfills needed by Angular 2 and is loaded before
// the app. You can add your own extra polyfills to this file.
+<% if(universal) { %>
+import 'angular2-universal-polyfills';<% } %>
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
@@ -15,5 +17,5 @@ import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-import 'zone.js/dist/zone';
+import 'core-js/es7/reflect';<% if(!universal) { %>
+import 'zone.js/dist/zone';<% } %>
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/styles.__styleext__ b/packages/universal-cli/blueprints/ng2/files/__path__/styles.__styleext__
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/__path__/styles.__styleext__
rename to packages/universal-cli/blueprints/ng2/files/__path__/styles.__styleext__
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/test.ts b/packages/universal-cli/blueprints/ng2/files/__path__/test.ts
similarity index 94%
rename from packages/angular-cli/blueprints/ng2/files/__path__/test.ts
rename to packages/universal-cli/blueprints/ng2/files/__path__/test.ts
index be44dc587f3a..f1fc7a814880 100644
--- a/packages/angular-cli/blueprints/ng2/files/__path__/test.ts
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/test.ts
@@ -1,4 +1,5 @@
import './polyfills.ts';
+<% if(universal) { %>import './__2.1.1.workaround.ts';<% } %>
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
diff --git a/packages/angular-cli/blueprints/ng2/files/__path__/tsconfig.json b/packages/universal-cli/blueprints/ng2/files/__path__/tsconfig.json
similarity index 87%
rename from packages/angular-cli/blueprints/ng2/files/__path__/tsconfig.json
rename to packages/universal-cli/blueprints/ng2/files/__path__/tsconfig.json
index fa3fcc8abcee..d1b2e55bf96e 100644
--- a/packages/angular-cli/blueprints/ng2/files/__path__/tsconfig.json
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/tsconfig.json
@@ -13,6 +13,7 @@
"target": "es5",
"typeRoots": [
"<%= relativeRootPath %>/node_modules/@types"
- ]
+ ]<% if(universal) { %>,
+ "types": [ "node" ]<% } %>
}
}
diff --git a/packages/universal-cli/blueprints/ng2/files/__path__/typings.d.ts b/packages/universal-cli/blueprints/ng2/files/__path__/typings.d.ts
new file mode 100644
index 000000000000..ea52695ac509
--- /dev/null
+++ b/packages/universal-cli/blueprints/ng2/files/__path__/typings.d.ts
@@ -0,0 +1,2 @@
+// Typings reference file, you can add your own global typings here
+// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
diff --git a/packages/angular-cli/blueprints/ng2/files/angular-cli.json b/packages/universal-cli/blueprints/ng2/files/angular-cli.json
similarity index 72%
rename from packages/angular-cli/blueprints/ng2/files/angular-cli.json
rename to packages/universal-cli/blueprints/ng2/files/angular-cli.json
index 4fd88b98c1cf..2fe5efd02441 100644
--- a/packages/angular-cli/blueprints/ng2/files/angular-cli.json
+++ b/packages/universal-cli/blueprints/ng2/files/angular-cli.json
@@ -6,17 +6,20 @@
"apps": [
{
"root": "<%= sourceDir %>",
- "outDir": "dist",
+ "outDir": "dist<% if(universal) { %>/client<% } %>",
"assets": [
"assets",
"favicon.ico"
],
- "index": "index.html",
- "main": "main.ts",
+ "index": "index.html",<% if(!universal) { %>
+ "main": "main.ts",<% } %><% if(universal) { %>
+ "main": "client.ts",
+ "nodeMain": "server.ts",<% } %>
"test": "test.ts",
"tsconfig": "tsconfig.json",
"prefix": "<%= prefix %>",
"mobile": <%= isMobile %>,
+ "universal": <%= universal %>,
"styles": [
"styles.<%= styleExt %>"
],
@@ -25,7 +28,11 @@
"source": "environments/environment.ts",
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
- }
+ }<% if(universal) { %>,
+ "webpackCustom": {
+ "client": "webpack.client.ts",
+ "server": "webpack.server.ts"
+ }<% } %>
}
],
"addons": [],
diff --git a/packages/angular-cli/blueprints/ng2/files/e2e/app.e2e-spec.ts b/packages/universal-cli/blueprints/ng2/files/e2e/app.e2e-spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/e2e/app.e2e-spec.ts
rename to packages/universal-cli/blueprints/ng2/files/e2e/app.e2e-spec.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/e2e/app.po.ts b/packages/universal-cli/blueprints/ng2/files/e2e/app.po.ts
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/e2e/app.po.ts
rename to packages/universal-cli/blueprints/ng2/files/e2e/app.po.ts
diff --git a/packages/angular-cli/blueprints/ng2/files/e2e/tsconfig.json b/packages/universal-cli/blueprints/ng2/files/e2e/tsconfig.json
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/e2e/tsconfig.json
rename to packages/universal-cli/blueprints/ng2/files/e2e/tsconfig.json
diff --git a/packages/angular-cli/blueprints/ng2/files/gitignore b/packages/universal-cli/blueprints/ng2/files/gitignore
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/gitignore
rename to packages/universal-cli/blueprints/ng2/files/gitignore
diff --git a/packages/angular-cli/blueprints/ng2/files/karma.conf.js b/packages/universal-cli/blueprints/ng2/files/karma.conf.js
similarity index 87%
rename from packages/angular-cli/blueprints/ng2/files/karma.conf.js
rename to packages/universal-cli/blueprints/ng2/files/karma.conf.js
index 2ec744bb0530..bdb6c61e365a 100644
--- a/packages/angular-cli/blueprints/ng2/files/karma.conf.js
+++ b/packages/universal-cli/blueprints/ng2/files/karma.conf.js
@@ -4,18 +4,18 @@
module.exports = function (config) {
config.set({
basePath: '',
- frameworks: ['jasmine', 'angular-cli'],
+ frameworks: ['jasmine', 'universal-cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-remap-istanbul'),
- require('angular-cli/plugins/karma')
+ require('universal-cli/plugins/karma')
],
files: [
{ pattern: './<%= sourceDir %>/test.ts', watched: false }
],
preprocessors: {
- './<%= sourceDir %>/test.ts': ['angular-cli']
+ './<%= sourceDir %>/test.ts': ['universal-cli']
},
mime: {
'text/x-typescript': ['ts','tsx']
diff --git a/packages/universal-cli/blueprints/ng2/files/package.json b/packages/universal-cli/blueprints/ng2/files/package.json
new file mode 100644
index 000000000000..ffb0befcedb3
--- /dev/null
+++ b/packages/universal-cli/blueprints/ng2/files/package.json
@@ -0,0 +1,67 @@
+{
+ "name": "<%= htmlComponentName %>",
+ "version": "0.0.0",
+ "license": "MIT",
+ "angular-cli": {},
+ "scripts": {
+ "start": "ung serve",
+ "lint": "tslint \"<%= sourceDir %>/**/*.ts\"",
+ "test": "ung test",
+ "pree2e": "webdriver-manager update --standalone false --gecko false",
+ "e2e": "protractor"
+ },
+ "private": true,
+ "dependencies": {
+ "@angular/common": "2.2.3",
+ "@angular/compiler": "2.2.3",
+ "@angular/core": "2.2.3",
+ "@angular/forms": "2.2.3",
+ "@angular/http": "2.2.3",
+ "@angular/platform-browser": "2.2.3",
+ "@angular/platform-browser-dynamic": "2.2.3",
+ "@angular/router": "3.2.3",<% if(universal) { %>
+ "@angular/platform-server": "2.2.3",
+ "angular2-platform-node": "2.1.0-rc.1",
+ "angular2-universal": "2.1.0-rc.1",
+ "angular2-universal-polyfills": "2.1.0-rc.1",
+ "angular2-express-engine": "2.1.0-rc.1",
+ "compression": "1.6.2",
+ "express": "^4.14.0",<% } %>
+ "core-js": "^2.4.1",
+ "rxjs": "5.0.0-beta.12",
+ "ts-helpers": "^1.1.1",
+ "zone.js": "^0.6.23"
+ },
+ "devDependencies": {
+ "@angular/compiler-cli": "2.2.3",<% if(isMobile) { %>
+ "@angular/platform-server": "2.2.3",
+ "@angular/service-worker": "0.2.0",
+ "@angular/app-shell": "0.0.0",
+ "angular2-universal":"2.1.0-rc.1",
+ "angular2-universal-polyfills": "2.1.0-rc.1",
+ "preboot": "2.1.2",
+ "parse5": "1.5.1",<% } %>
+ "@types/jasmine": "2.5.38",
+ "@types/node": "^6.0.42",<% if(universal) { %>
+ "@types/body-parser": "0.0.29",
+ "@types/compression": "0.0.29",
+ "@types/cookie-parser": "^1.3.29",
+ "@types/express": "^4.0.29",
+ "@types/express-serve-static-core": "^4.0.29",
+ "@types/mime": "0.0.28",
+ "@types/serve-static": "^1.7.27",<% } %>
+ "universal-cli": "<%= version %>",
+ "codelyzer": "2.0.0",
+ "jasmine-core": "2.5.2",
+ "jasmine-spec-reporter": "2.5.0",
+ "karma": "1.2.0",
+ "karma-chrome-launcher": "^2.0.0",
+ "karma-cli": "^1.0.1",
+ "karma-jasmine": "^1.0.2",
+ "karma-remap-istanbul": "^0.2.1",
+ "protractor": "~4.0.13",
+ "ts-node": "1.2.1",
+ "tslint": "^4.0.2",
+ "typescript": "~2.0.3"
+ }
+}
diff --git a/packages/angular-cli/blueprints/ng2/files/protractor.conf.js b/packages/universal-cli/blueprints/ng2/files/protractor.conf.js
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/protractor.conf.js
rename to packages/universal-cli/blueprints/ng2/files/protractor.conf.js
diff --git a/packages/angular-cli/blueprints/ng2/files/tslint.json b/packages/universal-cli/blueprints/ng2/files/tslint.json
similarity index 100%
rename from packages/angular-cli/blueprints/ng2/files/tslint.json
rename to packages/universal-cli/blueprints/ng2/files/tslint.json
diff --git a/packages/angular-cli/blueprints/ng2/index.js b/packages/universal-cli/blueprints/ng2/index.js
similarity index 78%
rename from packages/angular-cli/blueprints/ng2/index.js
rename to packages/universal-cli/blueprints/ng2/index.js
index 3ab5dd53ea42..f994cd0f9870 100644
--- a/packages/angular-cli/blueprints/ng2/index.js
+++ b/packages/universal-cli/blueprints/ng2/index.js
@@ -1,5 +1,5 @@
-const Blueprint = require('../../ember-cli/lib/models/blueprint');
-const path = require('path');
+const Blueprint = require('../../ember-cli/lib/models/blueprint');
+const path = require('path');
const stringUtils = require('ember-cli-string-utils');
const getFiles = Blueprint.prototype.files;
@@ -11,24 +11,33 @@ module.exports = {
{ name: 'prefix', type: String, default: 'app', aliases: ['p'] },
{ name: 'style', type: String, default: 'css' },
{ name: 'mobile', type: Boolean, default: false },
+ { name: 'universal', type: Boolean, default: false },
{ name: 'routing', type: Boolean, default: false },
{ name: 'inline-style', type: Boolean, default: false, aliases: ['is'] },
{ name: 'inline-template', type: Boolean, default: false, aliases: ['it'] }
],
- beforeInstall: function(options) {
+ beforeInstall: function (options) {
if (options.ignoredUpdateFiles && options.ignoredUpdateFiles.length > 0) {
return Blueprint.ignoredUpdateFiles = Blueprint.ignoredUpdateFiles.concat(options.ignoredUpdateFiles);
}
},
afterInstall: function (options) {
+ var bluePrints = [];
+
if (options.mobile) {
- return Blueprint.load(path.join(__dirname, '../mobile')).install(options);
+ bluePrints.push(Blueprint.load(path.join(__dirname, '../mobile')).install(options));
+ }
+ if (options.universal) {
+ Blueprint.load(path.join(__dirname, '../ng2'));
+ bluePrints.push(Blueprint.load(path.join(__dirname, '../universal')).install(options));
}
+
+ return Promise.all(bluePrints);
},
- locals: function(options) {
+ locals: function (options) {
this.styleExt = options.style;
this.version = require(path.resolve(__dirname, '../../package.json')).version;
@@ -54,13 +63,14 @@ module.exports = {
styleExt: this.styleExt,
relativeRootPath: relativeRootPath,
isMobile: options.mobile,
+ universal: options.universal,
routing: options.routing,
inlineStyle: options.inlineStyle,
inlineTemplate: options.inlineTemplate
};
},
- files: function() {
+ files: function () {
var fileList = getFiles.call(this);
if (this.options && !this.options.routing) {
@@ -73,6 +83,10 @@ module.exports = {
fileList = fileList.filter(p => p.indexOf('app.component.__styleext__') < 0);
}
+ if (this.options && this.options.universal) {
+ fileList = fileList.filter(p => p.indexOf('main.ts') < 0);
+ }
+
return fileList;
},
diff --git a/packages/angular-cli/blueprints/pipe/files/__path__/__name__.pipe.spec.ts b/packages/universal-cli/blueprints/pipe/files/__path__/__name__.pipe.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/pipe/files/__path__/__name__.pipe.spec.ts
rename to packages/universal-cli/blueprints/pipe/files/__path__/__name__.pipe.spec.ts
diff --git a/packages/angular-cli/blueprints/pipe/files/__path__/__name__.pipe.ts b/packages/universal-cli/blueprints/pipe/files/__path__/__name__.pipe.ts
similarity index 100%
rename from packages/angular-cli/blueprints/pipe/files/__path__/__name__.pipe.ts
rename to packages/universal-cli/blueprints/pipe/files/__path__/__name__.pipe.ts
diff --git a/packages/angular-cli/blueprints/pipe/index.js b/packages/universal-cli/blueprints/pipe/index.js
similarity index 76%
rename from packages/angular-cli/blueprints/pipe/index.js
rename to packages/universal-cli/blueprints/pipe/index.js
index e4d80411732e..710adf146a85 100644
--- a/packages/angular-cli/blueprints/pipe/index.js
+++ b/packages/universal-cli/blueprints/pipe/index.js
@@ -18,7 +18,7 @@ module.exports = {
beforeInstall: function(options) {
try {
- this.pathToModule = findParentModule(this.project, this.dynamicPath.dir);
+ this.modulePaths = findParentModule(this.project, this.dynamicPath.dir);
} catch(e) {
if (!options.skipImport) {
throw `Error locating module for declaration\n\t${e}`;
@@ -68,7 +68,7 @@ module.exports = {
};
},
- afterInstall: function(options) {
+ afterInstall: function (options) {
if (options.dryRun) {
return;
}
@@ -76,16 +76,19 @@ module.exports = {
const returns = [];
const className = stringUtils.classify(`${options.entity.name}Pipe`);
const fileName = stringUtils.dasherize(`${options.entity.name}.pipe`);
- const fullGeneratePath = path.join(this.project.root, this.generatePath);
- const moduleDir = path.parse(this.pathToModule).dir;
- const relativeDir = path.relative(moduleDir, fullGeneratePath);
- const importPath = relativeDir ? `./${relativeDir}/${fileName}` : `./${fileName}`;
-
- if (!options.skipImport) {
- returns.push(
- astUtils.addDeclarationToModule(this.pathToModule, className, importPath)
- .then(change => change.apply(NodeHost)));
- }
+
+ this.modulePaths.forEach((pathToModule) => {
+ const fullGeneratePath = path.join(this.project.root, this.generatePath);
+ const moduleDir = path.parse(pathToModule).dir;
+ const relativeDir = path.relative(moduleDir, fullGeneratePath);
+ const importPath = relativeDir ? `./${relativeDir}/${fileName}` : `./${fileName}`;
+
+ if (!options.skipImport) {
+ returns.push(
+ astUtils.addDeclarationToModule(pathToModule, className, importPath)
+ .then(change => change.apply(NodeHost)));
+ }
+ });
return Promise.all(returns);
}
diff --git a/packages/angular-cli/blueprints/service/files/__path__/__name__.service.spec.ts b/packages/universal-cli/blueprints/service/files/__path__/__name__.service.spec.ts
similarity index 100%
rename from packages/angular-cli/blueprints/service/files/__path__/__name__.service.spec.ts
rename to packages/universal-cli/blueprints/service/files/__path__/__name__.service.spec.ts
diff --git a/packages/angular-cli/blueprints/service/files/__path__/__name__.service.ts b/packages/universal-cli/blueprints/service/files/__path__/__name__.service.ts
similarity index 100%
rename from packages/angular-cli/blueprints/service/files/__path__/__name__.service.ts
rename to packages/universal-cli/blueprints/service/files/__path__/__name__.service.ts
diff --git a/packages/angular-cli/blueprints/service/index.js b/packages/universal-cli/blueprints/service/index.js
similarity index 100%
rename from packages/angular-cli/blueprints/service/index.js
rename to packages/universal-cli/blueprints/service/index.js
diff --git a/packages/universal-cli/blueprints/universal/files/__path__/__2.1.1.workaround.ts b/packages/universal-cli/blueprints/universal/files/__path__/__2.1.1.workaround.ts
new file mode 100644
index 000000000000..320e42c5adbd
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/__path__/__2.1.1.workaround.ts
@@ -0,0 +1,29 @@
+/*
+ * THIS IS TEMPORARY TO PATCH 2.1.1+ Core bugs
+ */
+
+/* tslint:disable */
+let __compiler__: any = require('@angular/compiler');
+import { __platform_browser_private__ } from '@angular/platform-browser';
+var __core_private__: any = require('@angular/core');
+let patch: Boolean = false;
+
+if (!__core_private__.hasOwnProperty('ViewUtils')) {
+ patch = true;
+ __core_private__.ViewUtils = __core_private__.view_utils;
+}
+
+if (!__compiler__.__compiler_private__) {
+ patch = true;
+ (__compiler__).__compiler_private__ = {
+ SelectorMatcher: __compiler__.SelectorMatcher,
+ CssSelector: __compiler__.CssSelector
+ }
+}
+
+var __universal__: any = require('angular2-platform-node/__private_imports__');
+if (patch) {
+ __universal__.ViewUtils = __core_private__.view_utils;
+ __universal__.CssSelector = __compiler__.CssSelector
+ __universal__.SelectorMatcher = __compiler__.SelectorMatcher
+}
diff --git a/packages/universal-cli/blueprints/universal/files/__path__/app/app.browser.module.ts b/packages/universal-cli/blueprints/universal/files/__path__/app/app.browser.module.ts
new file mode 100644
index 000000000000..063c9e20b255
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/__path__/app/app.browser.module.ts
@@ -0,0 +1,38 @@
+/**
+ * This file and `main.node.ts` are identical, at the moment(!)
+ * By splitting these, you're able to create logic, imports, etc that are "Platform" specific.
+ * If you want your code to be completely Universal and don't need that
+ * You can also just have 1 file, that is imported into both
+ * client.ts and server.ts
+ */
+
+import { NgModule } from '@angular/core';
+import { UniversalModule } from 'angular2-universal';
+import { FormsModule } from '@angular/forms';
+import { AppModule } from './app.module';
+import { AppComponent } from './index';
+// import { RouterModule } from '@angular/router';
+// import { appRoutes } from './app/app.routing';
+
+/**
+ * Top-level NgModule "container"
+ */
+@NgModule({
+ /** Root App Component */
+ bootstrap: [ AppComponent ],
+ imports: [
+ /**
+ * NOTE: Needs to be your first import (!)
+ * BrowserModule, HttpModule, and JsonpModule are included
+ */
+ UniversalModule,
+ AppModule
+ /**
+ * using routes
+ */
+ // RouterModule.forRoot(appRoutes)
+ ]
+})
+export class BrowserAppModule {
+
+}
diff --git a/packages/universal-cli/blueprints/universal/files/__path__/app/app.node.module.ts b/packages/universal-cli/blueprints/universal/files/__path__/app/app.node.module.ts
new file mode 100644
index 000000000000..8257d956ea9d
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/__path__/app/app.node.module.ts
@@ -0,0 +1,37 @@
+/**
+ * This file and `main.browser.ts` are identical, at the moment(!)
+ * By splitting these, you're able to create logic, imports, etc that are "Platform" specific.
+ * If you want your code to be completely Universal and don't need that
+ * You can also just have 1 file, that is imported into both
+ * client.ts and server.ts
+ */
+
+import { NgModule } from '@angular/core';
+import { UniversalModule } from 'angular2-universal';
+import { AppModule } from './app.module';
+import { AppComponent } from './index';
+// import { RouterModule } from '@angular/router';
+// import { appRoutes } from './app/app.routing';
+
+/**
+ * Top-level NgModule "container"
+ */
+@NgModule({
+ /** Root App Component */
+ bootstrap: [ AppComponent ],
+ imports: [
+ /**
+ * NOTE: Needs to be your first import (!)
+ * NodeModule, NodeHttpModule, NodeJsonpModule are included
+ */
+ UniversalModule,
+ AppModule
+ /**
+ * using routes
+ */
+ // RouterModule.forRoot(appRoutes)
+ ]
+})
+export class NodeAppModule {
+
+}
diff --git a/packages/universal-cli/blueprints/universal/files/__path__/client.ts b/packages/universal-cli/blueprints/universal/files/__path__/client.ts
new file mode 100644
index 000000000000..323be2847c1c
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/__path__/client.ts
@@ -0,0 +1,18 @@
+/**
+ * the polyfills must be the first thing imported
+ */
+import './polyfills.ts';
+import './__2.1.1.workaround.ts'; // temporary until 2.1.1 things are patched in Core
+import { enableProdMode } from '@angular/core';
+import { environment } from './environments/environment';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { BrowserAppModule } from './app/app.browser.module';
+
+/**
+ * enable prod mode for production environments
+ */
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(BrowserAppModule);
diff --git a/packages/universal-cli/blueprints/universal/files/__path__/server.routes.ts b/packages/universal-cli/blueprints/universal/files/__path__/server.routes.ts
new file mode 100644
index 000000000000..4011f826c7fe
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/__path__/server.routes.ts
@@ -0,0 +1,14 @@
+/**
+ * Server-side routes. Only the listed routes support html5pushstate.
+ * Has to match client side routes.
+ *
+ * Index (/) route does not have to be listed here.
+ *
+ * @example
+ * export const routes: string[] = [
+ * 'home', 'about'
+ * ];
+ **/
+export const routes: string[] = [
+
+];
diff --git a/packages/universal-cli/blueprints/universal/files/__path__/server.ts b/packages/universal-cli/blueprints/universal/files/__path__/server.ts
new file mode 100644
index 000000000000..93108419e767
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/__path__/server.ts
@@ -0,0 +1,89 @@
+/**
+ * the polyfills must be the first thing imported
+ */
+import './polyfills.ts';
+import './__2.1.1.workaround.ts'; // temporary until 2.1.1 things are patched in Core
+import * as path from 'path';
+import * as express from 'express';
+import * as compression from 'compression';
+import { createEngine } from 'angular2-express-engine';
+import { enableProdMode } from '@angular/core';
+import { NodeAppModule } from './app/app.node.module';
+import { environment } from './environments/environment';
+import { routes } from './server.routes';
+
+// App
+
+const app = express();
+const ROOT = path.join(path.resolve(__dirname, '..'));
+const port = process.env.PORT || 4200;
+
+/**
+ * enable prod mode for production environments
+ */
+if (environment.production) {
+ enableProdMode();
+}
+
+/**
+ * Express View
+ */
+app.engine('.html', createEngine({}));
+app.set('views', path.join(ROOT, 'client'));
+app.set('view engine', 'html');
+
+/**
+ * Enable compression
+ */
+app.use(compression());
+
+/**
+ * serve static files
+ */
+app.use('/', express.static(path.join(ROOT, 'client'), {index: false}));
+
+/**
+ * place your api routes here
+ */
+// app.use('/api', api);
+
+/**
+ * bootstrap universal app
+ * @param req
+ * @param res
+ */
+function ngApp(req: any, res: any) {
+ res.render('index', {
+ req,
+ res,
+ ngModule: NodeAppModule,
+ preboot: false,
+ baseUrl: '/',
+ requestUrl: req.originalUrl,
+ originUrl: req.hostname
+ });
+}
+
+/**
+ * use universal for specific routes
+ */
+app.get('/', ngApp);
+routes.forEach(route => {
+ app.get(`/${route}`, ngApp);
+ app.get(`/${route}/*`, ngApp);
+});
+
+/**
+ * if you want to use universal for all routes, you can use the '*' wildcard
+ */
+
+app.get('*', function (req: any, res: any) {
+ res.setHeader('Content-Type', 'application/json');
+ const pojo = {status: 404, message: 'No Content'};
+ const json = JSON.stringify(pojo, null, 2);
+ res.status(404).send(json);
+});
+
+app.listen(port, () => {
+ console.log(`Listening on port ${port}`);
+});
diff --git a/packages/universal-cli/blueprints/universal/files/webpack.client.ts b/packages/universal-cli/blueprints/universal/files/webpack.client.ts
new file mode 100644
index 000000000000..f053ebf7976e
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/webpack.client.ts
@@ -0,0 +1 @@
+module.exports = {};
diff --git a/packages/universal-cli/blueprints/universal/files/webpack.server.ts b/packages/universal-cli/blueprints/universal/files/webpack.server.ts
new file mode 100644
index 000000000000..f053ebf7976e
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/files/webpack.server.ts
@@ -0,0 +1 @@
+module.exports = {};
diff --git a/packages/universal-cli/blueprints/universal/index.js b/packages/universal-cli/blueprints/universal/index.js
new file mode 100644
index 000000000000..ff091e6806a3
--- /dev/null
+++ b/packages/universal-cli/blueprints/universal/index.js
@@ -0,0 +1,32 @@
+const stringUtils = require('ember-cli-string-utils');
+
+module.exports = {
+ description: '',
+
+ availableOptions: [
+ { name: 'source-dir', type: String, default: 'src', aliases: ['sd'] },
+ { name: 'prefix', type: String, default: 'app', aliases: ['p'] }
+ ],
+
+ locals: function (options) {
+ const fullAppName = stringUtils.dasherize(options.entity.name)
+ .replace(/-(.)/g, (_, l) => ' ' + l.toUpperCase())
+ .replace(/^./, (l) => l.toUpperCase());
+
+ return {
+ jsComponentName: stringUtils.classify(options.entity.name),
+ fullAppName: fullAppName,
+ sourceDir: options.sourceDir,
+ prefix: options.prefix
+ };
+ },
+
+ fileMapTokens: function (options) {
+ // Return custom template variables here.
+ return {
+ __path__: () => {
+ return options.locals.sourceDir;
+ }
+ };
+ }
+};
diff --git a/packages/angular-cli/commands/build.ts b/packages/universal-cli/commands/build.ts
similarity index 96%
rename from packages/angular-cli/commands/build.ts
rename to packages/universal-cli/commands/build.ts
index 6584be61078d..8a61349ae278 100644
--- a/packages/angular-cli/commands/build.ts
+++ b/packages/universal-cli/commands/build.ts
@@ -1,4 +1,4 @@
-import {Version} from '../upgrade/version';
+// import {Version} from '../upgrade/version';
const Command = require('../ember-cli/lib/models/command');
import WebpackBuild from '../tasks/build-webpack';
import WebpackBuildWatch from '../tasks/build-webpack-watch';
@@ -62,7 +62,7 @@ const BuildCommand = Command.extend({
const project = this.project;
// Check angular version.
- Version.assertAngularVersionIs2_3_1OrHigher(project.root);
+ // Version.assertAngularVersionIs2_3_1OrHigher(project.root);
const ui = this.ui;
const buildTask = commandOptions.watch ?
diff --git a/packages/angular-cli/commands/completion.ts b/packages/universal-cli/commands/completion.ts
similarity index 100%
rename from packages/angular-cli/commands/completion.ts
rename to packages/universal-cli/commands/completion.ts
diff --git a/packages/angular-cli/commands/destroy.ts b/packages/universal-cli/commands/destroy.ts
similarity index 71%
rename from packages/angular-cli/commands/destroy.ts
rename to packages/universal-cli/commands/destroy.ts
index 57745599d2fe..cccd9f07e30c 100644
--- a/packages/angular-cli/commands/destroy.ts
+++ b/packages/universal-cli/commands/destroy.ts
@@ -12,7 +12,10 @@ const DestroyCommand = Command.extend({
],
run: function() {
- return Promise.reject(new SilentError('The destroy command is not supported by Angular-CLI.'));
+ console.log('RUN');
+ return Promise.reject(
+ new SilentError('The destroy command is not supported by Universal-CLI.')
+ );
}
});
diff --git a/packages/angular-cli/commands/doc.ts b/packages/universal-cli/commands/doc.ts
similarity index 100%
rename from packages/angular-cli/commands/doc.ts
rename to packages/universal-cli/commands/doc.ts
diff --git a/packages/angular-cli/commands/e2e.ts b/packages/universal-cli/commands/e2e.ts
similarity index 100%
rename from packages/angular-cli/commands/e2e.ts
rename to packages/universal-cli/commands/e2e.ts
diff --git a/packages/angular-cli/commands/easter-egg.ts b/packages/universal-cli/commands/easter-egg.ts
similarity index 100%
rename from packages/angular-cli/commands/easter-egg.ts
rename to packages/universal-cli/commands/easter-egg.ts
diff --git a/packages/angular-cli/commands/generate.ts b/packages/universal-cli/commands/generate.ts
similarity index 87%
rename from packages/angular-cli/commands/generate.ts
rename to packages/universal-cli/commands/generate.ts
index 94adafed29c8..09355515b21f 100644
--- a/packages/angular-cli/commands/generate.ts
+++ b/packages/universal-cli/commands/generate.ts
@@ -21,12 +21,13 @@ const GenerateCommand = EmberGenerateCommand.extend({
if (rawArgs[0] !== '--help' &&
!fs.existsSync(path.join(__dirname, '..', 'blueprints', rawArgs[0]))) {
- SilentError.debugOrThrow('angular-cli/commands/generate', `Invalid blueprint: ${rawArgs[0]}`);
+ SilentError
+ .debugOrThrow('universal-cli/commands/generate', `Invalid blueprint: ${rawArgs[0]}`);
}
if (!rawArgs[1]) {
- SilentError.debugOrThrow('angular-cli/commands/generate',
- `The \`ng generate ${rawArgs[0]}\` command requires a name to be specified.`);
+ SilentError.debugOrThrow('universal-cli/commands/generate',
+ `The \`ung generate ${rawArgs[0]}\` command requires a name to be specified.`);
}
// Override default help to hide ember blueprints
diff --git a/packages/angular-cli/commands/get.ts b/packages/universal-cli/commands/get.ts
similarity index 100%
rename from packages/angular-cli/commands/get.ts
rename to packages/universal-cli/commands/get.ts
diff --git a/packages/angular-cli/commands/github-pages-deploy.ts b/packages/universal-cli/commands/github-pages-deploy.ts
similarity index 100%
rename from packages/angular-cli/commands/github-pages-deploy.ts
rename to packages/universal-cli/commands/github-pages-deploy.ts
diff --git a/packages/angular-cli/commands/help.ts b/packages/universal-cli/commands/help.ts
similarity index 100%
rename from packages/angular-cli/commands/help.ts
rename to packages/universal-cli/commands/help.ts
diff --git a/packages/angular-cli/commands/init.ts b/packages/universal-cli/commands/init.ts
similarity index 74%
rename from packages/angular-cli/commands/init.ts
rename to packages/universal-cli/commands/init.ts
index cf7bd381b1ad..e99a647dfcc6 100644
--- a/packages/angular-cli/commands/init.ts
+++ b/packages/universal-cli/commands/init.ts
@@ -11,24 +11,25 @@ const GitInit = require('../tasks/git-init');
const InitCommand: any = Command.extend({
name: 'init',
- description: 'Creates a new angular-cli project in the current folder.',
+ description: 'Creates a new universal-cli project in the current folder.',
aliases: ['i'],
works: 'everywhere',
availableOptions: [
- { name: 'dry-run', type: Boolean, default: false, aliases: ['d'] },
- { name: 'verbose', type: Boolean, default: false, aliases: ['v'] },
- { name: 'link-cli', type: Boolean, default: false, aliases: ['lc'] },
- { name: 'skip-npm', type: Boolean, default: false, aliases: ['sn'] },
- { name: 'skip-bower', type: Boolean, default: true, aliases: ['sb'] },
- { name: 'name', type: String, default: '', aliases: ['n'] },
- { name: 'source-dir', type: String, default: 'src', aliases: ['sd'] },
- { name: 'style', type: String, default: 'css' },
- { name: 'prefix', type: String, default: 'app', aliases: ['p'] },
- { name: 'mobile', type: Boolean, default: false },
- { name: 'routing', type: Boolean, default: false },
- { name: 'inline-style', type: Boolean, default: false, aliases: ['is'] },
- { name: 'inline-template', type: Boolean, default: false, aliases: ['it'] }
+ {name: 'dry-run', type: Boolean, default: false, aliases: ['d']},
+ {name: 'verbose', type: Boolean, default: false, aliases: ['v']},
+ {name: 'link-cli', type: Boolean, default: false, aliases: ['lc']},
+ {name: 'skip-npm', type: Boolean, default: false, aliases: ['sn']},
+ {name: 'skip-bower', type: Boolean, default: true, aliases: ['sb']},
+ {name: 'name', type: String, default: '', aliases: ['n']},
+ {name: 'source-dir', type: String, default: 'src', aliases: ['sd']},
+ {name: 'style', type: String, default: 'css'},
+ {name: 'prefix', type: String, default: 'app', aliases: ['p']},
+ {name: 'mobile', type: Boolean, default: false},
+ {name: 'universal', type: Boolean, default: false},
+ {name: 'routing', type: Boolean, default: false},
+ {name: 'inline-style', type: Boolean, default: false, aliases: ['is']},
+ {name: 'inline-template', type: Boolean, default: false, aliases: ['it']}
],
anonymousOptions: [''],
@@ -39,6 +40,13 @@ const InitCommand: any = Command.extend({
commandOptions.skipBower = true;
}
+ this.project.addons = this.project.addons.filter((addon: any) => {
+ if (this.analytics.version === undefined) {
+ return true;
+ }
+ return addon.pkg.version === this.analytics.version;
+ });
+
const installBlueprint = new this.tasks.InstallBlueprint({
ui: this.ui,
analytics: this.analytics,
@@ -86,9 +94,9 @@ const InitCommand: any = Command.extend({
const packageName = commandOptions.name !== '.' && commandOptions.name || project.name();
if (!packageName) {
- const message = 'The `ng ' + this.name + '` command requires a ' +
+ const message = 'The `ung ' + this.name + '` command requires a ' +
'package.json in current folder with name attribute or a specified name via arguments. ' +
- 'For more details, use `ng help`.';
+ 'For more details, use `ung help`.';
return Promise.reject(new SilentError(message));
}
@@ -103,6 +111,7 @@ const InitCommand: any = Command.extend({
style: commandOptions.style,
prefix: commandOptions.prefix,
mobile: commandOptions.mobile,
+ universal: commandOptions.universal,
routing: commandOptions.routing,
inlineStyle: commandOptions.inlineStyle,
inlineTemplate: commandOptions.inlineTemplate,
diff --git a/packages/angular-cli/commands/lint.ts b/packages/universal-cli/commands/lint.ts
similarity index 100%
rename from packages/angular-cli/commands/lint.ts
rename to packages/universal-cli/commands/lint.ts
diff --git a/packages/angular-cli/commands/new.ts b/packages/universal-cli/commands/new.ts
similarity index 93%
rename from packages/angular-cli/commands/new.ts
rename to packages/universal-cli/commands/new.ts
index 4a9dcdf9b9af..e4d648f0d555 100644
--- a/packages/angular-cli/commands/new.ts
+++ b/packages/universal-cli/commands/new.ts
@@ -10,7 +10,7 @@ const validProjectName = require('../ember-cli/lib/utilities/valid-project-name'
const NewCommand = Command.extend({
name: 'new',
- description: `Creates a new directory and runs ${chalk.green('ng init')} in it.`,
+ description: `Creates a new directory and runs ${chalk.green('ung init')} in it.`,
works: 'outsideProject',
availableOptions: [
@@ -25,6 +25,7 @@ const NewCommand = Command.extend({
{ name: 'style', type: String, default: 'css' },
{ name: 'prefix', type: String, default: 'app', aliases: ['p'] },
{ name: 'mobile', type: Boolean, default: false },
+ { name: 'universal', type: Boolean, default: false },
{ name: 'routing', type: Boolean, default: false },
{ name: 'inline-style', type: Boolean, default: false, aliases: ['is'] },
{ name: 'inline-template', type: Boolean, default: false, aliases: ['it'] }
@@ -35,8 +36,8 @@ const NewCommand = Command.extend({
if (!packageName) {
return Promise.reject(new SilentError(
- `The "ng ${this.name}" command requires a name argument to be specified. ` +
- `For more details, use "ng help".`));
+ `The "ung ${this.name}" command requires a name argument to be specified. ` +
+ `For more details, use "ung help".`));
}
if (!packageName.match(/^[a-zA-Z][.0-9a-zA-Z]*(-[a-zA-Z][.0-9a-zA-Z]*)*$/)) {
return Promise.reject(new SilentError(oneLine`
@@ -52,7 +53,7 @@ const NewCommand = Command.extend({
if (packageName === '.') {
return Promise.reject(new SilentError(
- `Trying to generate an application structure in this directory? Use "ng init" ` +
+ `Trying to generate an application structure in this directory? Use "ung init" ` +
`instead.`));
}
diff --git a/packages/angular-cli/commands/serve.ts b/packages/universal-cli/commands/serve.ts
similarity index 97%
rename from packages/angular-cli/commands/serve.ts
rename to packages/universal-cli/commands/serve.ts
index abb0013f8e3d..325241012578 100644
--- a/packages/angular-cli/commands/serve.ts
+++ b/packages/universal-cli/commands/serve.ts
@@ -4,7 +4,7 @@ const SilentError = require('silent-error');
const PortFinder = require('portfinder');
const Command = require('../ember-cli/lib/models/command');
import ServeWebpackTask from '../tasks/serve-webpack';
-import {Version} from '../upgrade/version';
+// import {Version} from '../upgrade/version';
PortFinder.basePort = 49152;
@@ -123,7 +123,7 @@ const ServeCommand = Command.extend({
}
// Check angular version.
- Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
+ // Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);
commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host;
return this._checkExpressPort(commandOptions)
diff --git a/packages/angular-cli/commands/set.ts b/packages/universal-cli/commands/set.ts
similarity index 100%
rename from packages/angular-cli/commands/set.ts
rename to packages/universal-cli/commands/set.ts
diff --git a/packages/angular-cli/commands/test.ts b/packages/universal-cli/commands/test.ts
similarity index 100%
rename from packages/angular-cli/commands/test.ts
rename to packages/universal-cli/commands/test.ts
diff --git a/packages/angular-cli/commands/version.ts b/packages/universal-cli/commands/version.ts
similarity index 89%
rename from packages/angular-cli/commands/version.ts
rename to packages/universal-cli/commands/version.ts
index b455d22f821a..2c8d1ead0022 100644
--- a/packages/angular-cli/commands/version.ts
+++ b/packages/universal-cli/commands/version.ts
@@ -4,7 +4,7 @@ import * as child_process from 'child_process';
const VersionCommand = Command.extend({
name: 'version',
- description: 'outputs angular-cli version',
+ description: 'outputs universal-cli version',
aliases: ['v', '--version', '-v'],
works: 'everywhere',
@@ -33,7 +33,8 @@ const VersionCommand = Command.extend({
ngCliVersion = `local (v${pkg.version}, branch: ${gitBranch})`;
}
- this.printVersion('angular-cli', ngCliVersion);
+ this.printVersion('universal-cli', ngCliVersion);
+ this.printVersion('angular-cli', pkg.cliVersion);
for (const module of Object.keys(versions)) {
if (options.verbose || alwaysPrint.indexOf(module) > -1) {
diff --git a/packages/angular-cli/custom-typings.d.ts b/packages/universal-cli/custom-typings.d.ts
similarity index 100%
rename from packages/angular-cli/custom-typings.d.ts
rename to packages/universal-cli/custom-typings.d.ts
diff --git a/packages/angular-cli/ember-cli/LICENSE.md b/packages/universal-cli/ember-cli/LICENSE.md
similarity index 100%
rename from packages/angular-cli/ember-cli/LICENSE.md
rename to packages/universal-cli/ember-cli/LICENSE.md
diff --git a/packages/angular-cli/ember-cli/lib/cli/cli.js b/packages/universal-cli/ember-cli/lib/cli/cli.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/cli/cli.js
rename to packages/universal-cli/ember-cli/lib/cli/cli.js
diff --git a/packages/angular-cli/ember-cli/lib/cli/index.js b/packages/universal-cli/ember-cli/lib/cli/index.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/cli/index.js
rename to packages/universal-cli/ember-cli/lib/cli/index.js
diff --git a/packages/angular-cli/ember-cli/lib/cli/lookup-command.js b/packages/universal-cli/ember-cli/lib/cli/lookup-command.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/cli/lookup-command.js
rename to packages/universal-cli/ember-cli/lib/cli/lookup-command.js
diff --git a/packages/universal-cli/ember-cli/lib/commands.js b/packages/universal-cli/ember-cli/lib/commands.js
new file mode 100644
index 000000000000..0f41faee1a38
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/commands.js
@@ -0,0 +1,2 @@
+
+module.exports = { 'Unknown': require('./commands/unknown') };
\ No newline at end of file
diff --git a/packages/angular-cli/ember-cli/lib/commands/generate.js b/packages/universal-cli/ember-cli/lib/commands/generate.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/commands/generate.js
rename to packages/universal-cli/ember-cli/lib/commands/generate.js
diff --git a/packages/angular-cli/ember-cli/lib/commands/test.js b/packages/universal-cli/ember-cli/lib/commands/test.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/commands/test.js
rename to packages/universal-cli/ember-cli/lib/commands/test.js
diff --git a/packages/angular-cli/ember-cli/lib/commands/unknown.js b/packages/universal-cli/ember-cli/lib/commands/unknown.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/commands/unknown.js
rename to packages/universal-cli/ember-cli/lib/commands/unknown.js
diff --git a/packages/angular-cli/ember-cli/lib/ext/core-object.js b/packages/universal-cli/ember-cli/lib/ext/core-object.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/ext/core-object.js
rename to packages/universal-cli/ember-cli/lib/ext/core-object.js
diff --git a/packages/angular-cli/ember-cli/lib/ext/promise.js b/packages/universal-cli/ember-cli/lib/ext/promise.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/ext/promise.js
rename to packages/universal-cli/ember-cli/lib/ext/promise.js
diff --git a/packages/angular-cli/ember-cli/lib/models/addon-discovery.js b/packages/universal-cli/ember-cli/lib/models/addon-discovery.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/addon-discovery.js
rename to packages/universal-cli/ember-cli/lib/models/addon-discovery.js
diff --git a/packages/angular-cli/ember-cli/lib/models/addon.js b/packages/universal-cli/ember-cli/lib/models/addon.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/addon.js
rename to packages/universal-cli/ember-cli/lib/models/addon.js
diff --git a/packages/angular-cli/ember-cli/lib/models/addons-factory.js b/packages/universal-cli/ember-cli/lib/models/addons-factory.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/addons-factory.js
rename to packages/universal-cli/ember-cli/lib/models/addons-factory.js
diff --git a/packages/universal-cli/ember-cli/lib/models/blueprint.js b/packages/universal-cli/ember-cli/lib/models/blueprint.js
new file mode 100644
index 000000000000..9227a3a148e7
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/models/blueprint.js
@@ -0,0 +1,1585 @@
+'use strict';
+
+/**
+ @module ember-cli
+ */
+var FileInfo = require('./file-info');
+var Promise = require('../ext/promise');
+var chalk = require('chalk');
+var MarkdownColor = require('../utilities/markdown-color');
+var printableProperties = require('../utilities/printable-properties').blueprint;
+var sequence = require('../utilities/sequence');
+var printCommand = require('../utilities/print-command');
+var fs = require('fs-extra');
+var existsSync = require('exists-sync');
+var inflector = require('inflection');
+var minimatch = require('minimatch');
+var path = require('path');
+var stat = Promise.denodeify(fs.stat);
+var stringUtils = require('ember-cli-string-utils');
+var compact = require('lodash/compact');
+var intersect = require('lodash/intersection');
+var uniq = require('lodash/uniq');
+var zipObject = require('lodash/zipObject');
+var includes = require('lodash/includes');
+var any = require('lodash/some');
+var cloneDeep = require('lodash/cloneDeep');
+var keys = require('lodash/keys');
+var merge = require('lodash/merge');
+var values = require('lodash/values');
+var walkSync = require('walk-sync');
+var writeFile = Promise.denodeify(fs.outputFile);
+var removeFile = Promise.denodeify(fs.remove);
+var SilentError = require('silent-error');
+var CoreObject = require('../ext/core-object');
+var EOL = require('os').EOL;
+var debug = require('debug')('ember-cli:blueprint');
+var normalizeEntityName = require('ember-cli-normalize-entity-name');
+
+module.exports = Blueprint;
+
+/**
+ A blueprint is a bundle of template files with optional install
+ logic.
+
+ Blueprints follow a simple structure. Let's take the built-in
+ `controller` blueprint as an example:
+
+ ```
+ blueprints/controller
+ ├── files
+ │ ├── app
+ │ │ └── __path__
+ │ │ └── __name__.js
+ └── index.js
+
+ blueprints/controller-test
+ ├── files
+ │ └── tests
+ │ └── unit
+ │ └── controllers
+ │ └── __test__.js
+ └── index.js
+ ```
+
+ ## Files
+
+ `files` contains templates for the all the files to be
+ installed into the target directory.
+
+ The `__name__` token is subtituted with the dasherized
+ entity name at install time. For example, when the user
+ invokes `ember generate controller foo` then `__name__` becomes
+ `foo`. When the `--pod` flag is used, for example `ember
+ generate controller foo --pod` then `__name__` becomes
+ `controller`.
+
+ The `__path__` token is substituted with the blueprint
+ name at install time. For example, when the user invokes
+ `ember generate controller foo` then `__path__` becomes
+ `controller`. When the `--pod` flag is used, for example
+ `ember generate controller foo --pod` then `__path__`
+ becomes `foo` (or `/foo` if the
+ podModulePrefix is defined). This token is primarily for
+ pod support, and is only necessary if the blueprint can be
+ used in pod structure. If the blueprint does not require pod
+ support, simply use the blueprint name instead of the
+ `__path__` token.
+
+ The `__test__` token is substituted with the dasherized
+ entity name and appended with `-test` at install time.
+ This token is primarily for pod support and only necessary
+ if the blueprint requires support for a pod structure. If
+ the blueprint does not require pod support, simply use the
+ `__name__` token instead.
+
+ ## Template Variables (AKA Locals)
+
+ Variables can be inserted into templates with
+ `<%= someVariableName %>`.
+
+ For example, the built-in `util` blueprint
+ `files/app/utils/__name__.js` looks like this:
+
+ ```js
+ export default function <%= camelizedModuleName %>() {
+ return true;
+ }
+ ```
+
+ `<%= camelizedModuleName %>` is replaced with the real
+ value at install time.
+
+ The following template variables are provided by default:
+
+ - `dasherizedPackageName`
+ - `classifiedPackageName`
+ - `dasherizedModuleName`
+ - `classifiedModuleName`
+ - `camelizedModuleName`
+
+ `packageName` is the project name as found in the project's
+ `package.json`.
+
+ `moduleName` is the name of the entity being generated.
+
+ The mechanism for providing custom template variables is
+ described below.
+
+ ## Index.js
+
+ Custom installation and uninstallation behaviour can be added
+ by overriding the hooks documented below. `index.js` should
+ export a plain object, which will extend the prototype of the
+ `Blueprint` class. If needed, the original `Blueprint` prototype
+ can be accessed through the `_super` property.
+
+ ```js
+ module.exports = {
+ locals: function(options) {
+ // Return custom template variables here.
+ return {};
+ },
+
+ normalizeEntityName: function(entityName) {
+ // Normalize and validate entity name here.
+ return entityName;
+ },
+
+ fileMapTokens: function(options) (
+ // Return custom tokens to be replaced in your files
+ return {
+ __token__: function(options){
+ // logic to determine value goes here
+ return 'value';
+ }
+ }
+ },
+
+ filesPath: function(options) {
+ return path.join(this.path, 'files');
+ },
+
+ beforeInstall: function(options) {},
+ afterInstall: function(options) {},
+ beforeUninstall: function(options) {},
+ afterUninstall: function(options) {}
+
+ };
+ ```
+
+ ## Blueprint Hooks
+
+ As shown above, the following hooks are available to
+ blueprint authors:
+
+ - `locals`
+ - `normalizeEntityName`
+ - `fileMapTokens`
+ - `filesPath`
+ - `beforeInstall`
+ - `afterInstall`
+ - `beforeUninstall`
+ - `afterUninstall`
+
+ ### locals
+
+ Use `locals` to add custom tempate variables. The method
+ receives one argument: `options`. Options is an object
+ containing general and entity-specific options.
+
+ When the following is called on the command line:
+
+ ```sh
+ ember generate controller foo --type=array --dry-run
+ ```
+
+ The object passed to `locals` looks like this:
+
+ ```js
+ {
+ entity: {
+ name: 'foo',
+ options: {
+ type: 'array'
+ }
+ },
+ dryRun: true
+ }
+ ```
+
+ This hook must return an object or a Promise which resolves to an object.
+ The resolved object will be merged with the aforementioned default locals.
+
+ ### normalizeEntityName
+
+ Use the `normalizeEntityName` hook to add custom normalization and
+ validation of the provided entity name. The default hook does not
+ make any changes to the entity name, but makes sure an entity name
+ is present and that it doesn't have a trailing slash.
+
+ This hook receives the entity name as its first argument. The string
+ returned by this hook will be used as the new entity name.
+
+ ### fileMapTokens
+
+ Use `fileMapTokens` to add custom fileMap tokens for use
+ in the `mapFile` method. The hook must return an object in the
+ following pattern:
+
+ ```js
+ {
+ __token__: function(options){
+ // logic to determine value goes here
+ return 'value';
+ }
+ }
+ ```
+
+ It will be merged with the default `fileMapTokens`, and can be used
+ to override any of the default tokens.
+
+ Tokens are used in the files folder (see `files`), and get replaced with
+ values when the `mapFile` method is called.
+
+ ### filesPath
+
+ Use `filesPath` to define where the blueprint files to install are located.
+ This can be used to customize which set of files to install based on options
+ or environmental variables. It defaults to the `files` directory within the
+ blueprint's folder.
+
+ ### beforeInstall & beforeUninstall
+
+ Called before any of the template files are processed and receives
+ the the `options` and `locals` hashes as parameters. Typically used for
+ validating any additional command line options or for any asynchronous
+ setup that is needed. As an example, the `controller` blueprint validates
+ its `--type` option in this hook. If you need to run any asynchronous code,
+ wrap it in a promise and return that promise from these hooks. This will
+ ensure that your code is executed correctly.
+
+ ### afterInstall & afterUninstall
+
+ The `afterInstall` and `afterUninstall` hooks receives the same
+ arguments as `locals`. Use it to perform any custom work after the
+ files are processed. For example, the built-in `route` blueprint
+ uses these hooks to add and remove relevant route declarations in
+ `app/router.js`.
+
+ ### Overriding Install
+
+ If you don't want your blueprint to install the contents of
+ `files` you can override the `install` method. It receives the
+ same `options` object described above and must return a promise.
+ See the built-in `resource` blueprint for an example of this.
+
+ @class Blueprint
+ @constructor
+ @extends CoreObject
+ @param {String} [blueprintPath]
+ */
+function Blueprint(blueprintPath) {
+ this.path = blueprintPath;
+ this.name = path.basename(blueprintPath);
+}
+
+Blueprint.__proto__ = CoreObject;
+Blueprint.prototype.constructor = Blueprint;
+
+Blueprint.prototype.availableOptions = [];
+Blueprint.prototype.anonymousOptions = ['name'];
+
+/**
+ Hook to specify the path to the blueprint's files. By default this is
+ `path.join(this.path, 'files)`.
+
+ @method filesPath
+ @param {Object} options
+ @return {String} Path to the blueprints files directory.
+ */
+
+Blueprint.prototype.filesPath = function () {
+ return path.join(this.path, 'files');
+};
+
+/**
+ Used to retrieve files for blueprint. The `file` param is an
+ optional string that is turned into a glob.
+
+ @method files
+ @return {Array} Contents of the blueprint's files directory
+ */
+Blueprint.prototype.files = function () {
+ if (this._files) {
+ return this._files;
+ }
+
+ var filesPath = this.filesPath(this.options);
+ if (existsSync(filesPath)) {
+ this._files = walkSync(filesPath);
+ } else {
+ this._files = [];
+ }
+
+ return this._files;
+};
+
+/**
+ @method srcPath
+ @param {String} file
+ @return {String} Resolved path to the file
+ */
+Blueprint.prototype.srcPath = function (file) {
+ return path.resolve(this.filesPath(this.options), file);
+};
+
+/**
+ Hook for normalizing entity name
+ @method normalizeEntityName
+ @param {String} entityName
+ @return {null}
+ */
+Blueprint.prototype.normalizeEntityName = function (entityName) {
+ return normalizeEntityName(entityName);
+};
+
+/**
+ Write a status and message to the UI
+ @private
+ @method _writeStatusToUI
+ @param {Function} chalkColor
+ @param {String} keyword
+ @param {String} message
+ */
+Blueprint.prototype._writeStatusToUI = function (chalkColor, keyword, message) {
+ if (this.ui) {
+ this.ui.writeLine(' ' + chalkColor(keyword) + ' ' + message);
+ }
+};
+
+/**
+ @private
+ @method _writeFile
+ @param {Object} info
+ @return {Promise}
+ */
+Blueprint.prototype._writeFile = function (info) {
+ if (!this.dryRun) {
+ return writeFile(info.outputPath, info.render());
+ }
+};
+
+/**
+ Actions lookup
+ @private
+ */
+
+Blueprint.prototype._actions = {
+ write: function (info) {
+ this._writeStatusToUI(chalk.green, 'create', info.displayPath);
+ return this._writeFile(info);
+ },
+ skip: function (info) {
+ var label = 'skip';
+
+ if (info.resolution === 'identical') {
+ label = 'identical';
+ }
+
+ this._writeStatusToUI(chalk.yellow, label, info.displayPath);
+ },
+
+ overwrite: function (info) {
+ this._writeStatusToUI(chalk.yellow, 'overwrite', info.displayPath);
+ return this._writeFile(info);
+ },
+
+ edit: function (info) {
+ this._writeStatusToUI(chalk.green, 'edited', info.displayPath);
+ },
+
+ remove: function (info) {
+ this._writeStatusToUI(chalk.red, 'remove', info.displayPath);
+ if (!this.dryRun) {
+ return removeFile(info.outputPath);
+ }
+ }
+};
+
+/**
+ Calls an action.
+ @private
+ @method _commit
+ @param {Object} result
+ @return {Promise}
+ @throws {Error} Action doesn't exist.
+ */
+Blueprint.prototype._commit = function (result) {
+ var action = this._actions[result.action];
+
+ if (action) {
+ return action.call(this, result);
+ } else {
+ throw new Error('Tried to call action \"' + result.action + '\" but it does not exist');
+ }
+};
+
+/**
+ Prints warning for pod unsupported.
+ @private
+ @method _checkForPod
+ */
+Blueprint.prototype._checkForPod = function (verbose) {
+ if (!this.hasPathToken && this.pod && verbose) {
+ this.ui.writeLine(chalk.yellow('You specified the pod flag, but this' +
+ ' blueprint does not support pod structure. It will be generated with' +
+ ' the default structure.'));
+ }
+};
+
+/**
+ @private
+ @method _normalizeEntityName
+ @param {Object} entity
+ */
+Blueprint.prototype._normalizeEntityName = function (entity) {
+ if (entity) {
+ entity.name = this.normalizeEntityName(entity.name);
+ }
+};
+
+/**
+ @private
+ @method _checkInRepoAddonExists
+ @param {String} inRepoAddon
+ */
+Blueprint.prototype._checkInRepoAddonExists = function (inRepoAddon) {
+ if (inRepoAddon) {
+ if (!inRepoAddonExists(inRepoAddon, this.project.root)) {
+ throw new SilentError('You specified the in-repo-addon flag, but the' +
+ ' in-repo-addon \'' + inRepoAddon + '\' does not exist. Please' +
+ ' check the name and try again.');
+ }
+ }
+};
+
+/**
+ @private
+ @method _process
+ @param {Object} options
+ @param {Function} beforeHook
+ @param {Function} process
+ @param {Function} afterHook
+ */
+Blueprint.prototype._process = function (options, beforeHook, process, afterHook) {
+ var self = this;
+ var intoDir = options.target;
+
+ return this._locals(options).then(function (locals) {
+ return Promise.resolve()
+ .then(beforeHook.bind(self, options, locals))
+ .then(process.bind(self, intoDir, locals)).map(self._commit.bind(self))
+ .then(afterHook.bind(self, options));
+ });
+};
+
+/**
+ @method install
+ @param {Object} options
+ @return {Promise}
+ */
+Blueprint.prototype.install = function (options) {
+ var ui = this.ui = options.ui;
+ var dryRun = this.dryRun = options.dryRun;
+ this.project = options.project;
+ this.pod = options.pod;
+ this.options = options;
+ this.hasPathToken = hasPathToken(this.files());
+
+ podDeprecations(this.project.config(), ui);
+
+ ui.writeLine('installing ' + this.name);
+
+ if (dryRun) {
+ ui.writeLine(chalk.yellow('You specified the dry-run flag, so no' +
+ ' changes will be written.'));
+ }
+
+ this._normalizeEntityName(options.entity);
+ this._checkForPod(options.verbose);
+ this._checkInRepoAddonExists(options.inRepoAddon);
+
+ debug('START: processing blueprint: `%s`', this.name);
+ var start = new Date();
+ return this._process(
+ options,
+ this.beforeInstall,
+ this.processFiles,
+ this.afterInstall).finally(function () {
+ debug('END: processing blueprint: `%s` in (%dms)', this.name, new Date() - start);
+ }.bind(this));
+};
+
+/**
+ @method uninstall
+ @param {Object} options
+ @return {Promise}
+ */
+Blueprint.prototype.uninstall = function (options) {
+ var ui = this.ui = options.ui;
+ var dryRun = this.dryRun = options.dryRun;
+ this.project = options.project;
+ this.pod = options.pod;
+ this.options = options;
+ this.hasPathToken = hasPathToken(this.files());
+
+ podDeprecations(this.project.config(), ui);
+
+ ui.writeLine('uninstalling ' + this.name);
+
+ if (dryRun) {
+ ui.writeLine(chalk.yellow('You specified the dry-run flag, so no' +
+ ' files will be deleted.'));
+ }
+
+ this._normalizeEntityName(options.entity);
+ this._checkForPod(options.verbose);
+
+ return this._process(
+ options,
+ this.beforeUninstall,
+ this.processFilesForUninstall,
+ this.afterUninstall);
+};
+
+/**
+ Hook for running operations before install.
+ @method beforeInstall
+ @return {Promise|null}
+ */
+Blueprint.prototype.beforeInstall = function () {
+};
+
+/**
+ Hook for running operations after install.
+ @method afterInstall
+ @return {Promise|null}
+ */
+Blueprint.prototype.afterInstall = function () {
+};
+
+/**
+ Hook for running operations before uninstall.
+ @method beforeUninstall
+ @return {Promise|null}
+ */
+Blueprint.prototype.beforeUninstall = function () {
+};
+
+/**
+ Hook for running operations after uninstall.
+ @method afterUninstall
+ @return {Promise|null}
+ */
+Blueprint.prototype.afterUninstall = function () {
+};
+
+/**
+ Hook for adding additional locals
+ @method locals
+ @return {Object|null}
+ */
+Blueprint.prototype.locals = function () {
+};
+
+/**
+ Hook to add additional or override existing fileMapTokens.
+ @method fileMapTokens
+ @return {Object|null}
+ */
+Blueprint.prototype.fileMapTokens = function () {
+};
+
+/**
+ @private
+ @method _fileMapTokens
+ @param {Object} options
+ @return {Object}
+ */
+Blueprint.prototype._fileMapTokens = function (options) {
+ var standardTokens = {
+ __name__: function (options) {
+ if (options.pod && options.hasPathToken) {
+ return options.blueprintName;
+ }
+ return options.dasherizedModuleName;
+ },
+ __path__: function (options) {
+ var blueprintName = options.blueprintName;
+
+ if (blueprintName.match(/-test/)) {
+ blueprintName = options.blueprintName.slice(0, options.blueprintName.indexOf('-test'));
+ }
+ if (options.pod && options.hasPathToken) {
+ return path.join(options.podPath, options.dasherizedModuleName);
+ }
+ return inflector.pluralize(blueprintName);
+ },
+ __root__: function (options) {
+ if (options.inRepoAddon) {
+ return path.join('lib', options.inRepoAddon, 'addon');
+ }
+ if (options.inDummy) {
+ return path.join('tests', 'dummy', 'app');
+ }
+ if (options.inAddon) {
+ return 'addon';
+ }
+ return 'app';
+ },
+ __test__: function (options) {
+ if (options.pod && options.hasPathToken) {
+ return options.blueprintName;
+ }
+ return options.dasherizedModuleName + '-test';
+ }
+ };
+
+ var customTokens = this.fileMapTokens(options) || options.fileMapTokens || {};
+ return merge(standardTokens, customTokens);
+};
+
+/**
+ Used to generate fileMap tokens for mapFile.
+
+ @method generateFileMap
+ @param {Object} fileMapVariables
+ @return {Object}
+ */
+Blueprint.prototype.generateFileMap = function (fileMapVariables) {
+ var tokens = this._fileMapTokens(fileMapVariables);
+ var fileMapValues = values(tokens);
+ var tokenValues = fileMapValues.map(function (token) {
+ return token(fileMapVariables);
+ });
+ var tokenKeys = keys(tokens);
+ return zipObject(tokenKeys, tokenValues);
+};
+
+/**
+ @method buildFileInfo
+ @param {Function} destPath
+ @param {Object} templateVariables
+ @param {String} file
+ @return {FileInfo}
+ */
+Blueprint.prototype.buildFileInfo = function (destPath, templateVariables, file) {
+ var mappedPath = this.mapFile(file, templateVariables);
+
+ return new FileInfo({
+ action: 'write',
+ outputPath: destPath(mappedPath),
+ displayPath: path.normalize(mappedPath),
+ inputPath: this.srcPath(file),
+ templateVariables: templateVariables,
+ ui: this.ui
+ });
+};
+
+/**
+ @method isUpdate
+ @return {Boolean}
+ */
+Blueprint.prototype.isUpdate = function () {
+ if (this.project && this.project.isEmberCLIProject) {
+ return this.project.isEmberCLIProject();
+ }
+};
+
+/**
+ @private
+ @method _getFileInfos
+ @param {Array} files
+ @param {String} intoDir
+ @param {Object} templateVariables
+ @return {Array} file infos
+ */
+Blueprint.prototype._getFileInfos = function (files, intoDir, templateVariables) {
+ return files.map(this.buildFileInfo.bind(this, destPath.bind(null, intoDir), templateVariables));
+};
+
+/**
+ Add update files to ignored files
+ @private
+ @method _ignoreUpdateFiles
+ */
+Blueprint.prototype._ignoreUpdateFiles = function () {
+ if (this.isUpdate()) {
+ Blueprint.ignoredFiles = Blueprint.ignoredFiles.concat(Blueprint.ignoredUpdateFiles);
+ }
+};
+
+/**
+ @private
+ @method _getFilesForInstall
+ @param {Array} targetFiles
+ @return {Array} files
+ */
+Blueprint.prototype._getFilesForInstall = function (targetFiles) {
+ var files = this.files();
+
+ // if we've defined targetFiles, get file info on ones that match
+ return targetFiles && targetFiles.length > 0 && intersect(files, targetFiles) || files;
+};
+
+/**
+ @private
+ @method _checkForNoMatch
+ @param {Array} fileInfos
+ @param {String} rawArgs
+ */
+Blueprint.prototype._checkForNoMatch = function (fileInfos, rawArgs) {
+ if (fileInfos.filter(isFilePath).length < 1 && rawArgs) {
+ this.ui.writeLine(chalk.yellow('The globPattern \"' + rawArgs +
+ '\" did not match any files, so no file updates will be made.'));
+ }
+};
+
+function finishProcessingForInstall(infos) {
+ infos.forEach(markIdenticalToBeSkipped);
+
+ var infosNeedingConfirmation = infos.reduce(gatherConfirmationMessages, []);
+
+ return sequence(infosNeedingConfirmation).returns(infos);
+}
+
+function finishProcessingForUninstall(infos) {
+ infos.forEach(markToBeRemoved);
+ return infos;
+}
+
+/**
+ @method processFiles
+ @param {String} intoDir
+ @param {Object} templateVariables
+ */
+Blueprint.prototype.processFiles = function (intoDir, templateVariables) {
+ var files = this._getFilesForInstall(templateVariables.targetFiles);
+ var fileInfos = this._getFileInfos(files, intoDir, templateVariables);
+ this._checkForNoMatch(fileInfos, templateVariables.rawArgs);
+
+ this._ignoreUpdateFiles();
+
+ return Promise.filter(fileInfos, isValidFile).map(prepareConfirm).then(finishProcessingForInstall);
+};
+
+/**
+ @method processFilesForUninstall
+ @param {String} intoDir
+ @param {Object} templateVariables
+ */
+Blueprint.prototype.processFilesForUninstall = function (intoDir, templateVariables) {
+ var fileInfos = this._getFileInfos(this.files(), intoDir, templateVariables);
+
+ this._ignoreUpdateFiles();
+
+ return Promise.filter(fileInfos, isValidFile).then(finishProcessingForUninstall);
+};
+
+
+/**
+ @method mapFile
+ @param {String} file
+ @return {String}
+ */
+Blueprint.prototype.mapFile = function (file, locals) {
+ var pattern, i;
+ var fileMap = locals.fileMap || {__name__: locals.dasherizedModuleName};
+ file = Blueprint.renamedFiles[file] || file;
+ for (i in fileMap) {
+ pattern = new RegExp(i, 'g');
+ file = file.replace(pattern, fileMap[i]);
+ }
+ return file;
+};
+
+/**
+ Looks for a __root__ token in the files folder. Must be present for
+ the blueprint to support addon tokens. The `server`, `blueprints`, and `test`
+
+ @private
+ @method supportsAddon
+ @return {Boolean}
+ */
+Blueprint.prototype.supportsAddon = function () {
+ return this.files().join().match(/__root__/);
+};
+
+/**
+ @private
+ @method _generateFileMapVariables
+ @param {Object} options
+ @return {Object}
+ */
+Blueprint.prototype._generateFileMapVariables = function (moduleName, locals, options) {
+ var originBlueprintName = options.originBlueprintName || this.name;
+ var podModulePrefix = this.project.config().podModulePrefix || '';
+ var podPath = podModulePrefix.substr(podModulePrefix.lastIndexOf('/') + 1);
+ var inAddon = this.project.isEmberCLIAddon() || !!options.inRepoAddon;
+ var inDummy = this.project.isEmberCLIAddon() ? options.dummy : false;
+
+ return {
+ pod: this.pod,
+ podPath: podPath,
+ hasPathToken: this.hasPathToken,
+ inAddon: inAddon,
+ inRepoAddon: options.inRepoAddon,
+ inDummy: inDummy,
+ blueprintName: this.name,
+ originBlueprintName: originBlueprintName,
+ dasherizedModuleName: stringUtils.dasherize(moduleName),
+ locals: locals
+ };
+};
+
+/**
+ @private
+ @method _locals
+ @param {Object} options
+ @return {Object}
+ */
+Blueprint.prototype._locals = function (options) {
+ var packageName = options.project.name();
+ var moduleName = options.entity && options.entity.name || packageName;
+ var sanitizedModuleName = moduleName.replace(/\//g, '-');
+
+ return new Promise(function (resolve) {
+ resolve(this.locals(options));
+ }.bind(this)).then(function (customLocals) {
+ var fileMapVariables = this._generateFileMapVariables(moduleName, customLocals, options);
+ var fileMap = this.generateFileMap(fileMapVariables);
+ var standardLocals = {
+ dasherizedPackageName: stringUtils.dasherize(packageName),
+ classifiedPackageName: stringUtils.classify(packageName),
+ dasherizedModuleName: stringUtils.dasherize(moduleName),
+ classifiedModuleName: stringUtils.classify(sanitizedModuleName),
+ camelizedModuleName: stringUtils.camelize(sanitizedModuleName),
+ decamelizedModuleName: stringUtils.decamelize(sanitizedModuleName),
+ fileMap: fileMap,
+ hasPathToken: this.hasPathToken,
+ targetFiles: options.targetFiles,
+ rawArgs: options.rawArgs
+ };
+
+ return merge({}, standardLocals, customLocals);
+ }.bind(this));
+};
+
+/**
+ Used to add a package to the project's `package.json`.
+
+ Generally, this would be done from the `afterInstall` hook, to
+ ensure that a package that is required by a given blueprint is
+ available.
+
+ @method addPackageToProject
+ @param {String} packageName
+ @param {String} target
+ @return {Promise}
+ */
+Blueprint.prototype.addPackageToProject = function (packageName, target) {
+ var packageObject = {name: packageName};
+
+ if (target) {
+ packageObject.target = target;
+ }
+
+ return this.addPackagesToProject([packageObject]);
+};
+
+/**
+ Used to add multiple packages to the project's `package.json`.
+
+ Generally, this would be done from the `afterInstall` hook, to
+ ensure that a package that is required by a given blueprint is
+ available.
+
+ Expects each array item to be an object with a `name`. Each object
+ may optionally have a `target` to specify a specific version.
+
+ @method addPackagesToProject
+ @param {Array} packages
+ @return {Promise}
+ */
+Blueprint.prototype.addPackagesToProject = function (packages) {
+ var task = this.taskFor('npm-install');
+ var installText = (packages.length > 1) ? 'install packages' : 'install package';
+ var packageNames = [];
+ var packageArray = [];
+
+ for (var i = 0; i < packages.length; i++) {
+ packageNames.push(packages[i].name);
+
+ var packageNameAndVersion = packages[i].name;
+
+ if (packages[i].target) {
+ packageNameAndVersion += '@' + packages[i].target;
+ }
+
+ packageArray.push(packageNameAndVersion);
+ }
+
+ this._writeStatusToUI(chalk.green, installText, packageNames.join(', '));
+
+ return task.run({
+ 'save-dev': true,
+ verbose: false,
+ packages: packageArray
+ });
+};
+
+/**
+ Used to remove a package from the project's `package.json`.
+
+ Generally, this would be done from the `afterInstall` hook, to
+ ensure that any package conflicts can be resolved before the
+ addon is used.
+
+ @method removePackageFromProject
+ @param {String} packageName
+ @return {Promise}
+ */
+Blueprint.prototype.removePackageFromProject = function (packageName) {
+ var packageObject = {name: packageName};
+
+ return this.removePackagesFromProject([packageObject]);
+};
+
+/**
+ Used to remove multiple packages from the project's `package.json`.
+
+ Generally, this would be done from the `afterInstall` hook, to
+ ensure that any package conflicts can be resolved before the
+ addon is used.
+
+ Expects each array item to be an object with a `name` property.
+
+ @method removePackagesFromProject
+ @param {Array} packages
+ @return {Promise}
+ */
+Blueprint.prototype.removePackagesFromProject = function (packages) {
+ var task = this.taskFor('npm-uninstall');
+ var installText = (packages.length > 1) ? 'uninstall packages' : 'uninstall package';
+ var packageNames = [];
+ var packageArray = [];
+
+ for (var i = 0; i < packages.length; i++) {
+ packageNames.push(packages[i].name);
+
+ var packageNameAndVersion = packages[i].name;
+
+ packageArray.push(packageNameAndVersion);
+ }
+
+ this._writeStatusToUI(chalk.green, installText, packageNames.join(', '));
+
+ return task.run({
+ 'save-dev': true,
+ verbose: false,
+ packages: packageArray
+ });
+};
+
+/**
+ Used to add a package to the projects `bower.json`.
+
+ Generally, this would be done from the `afterInstall` hook, to
+ ensure that a package that is required by a given blueprint is
+ available.
+
+ `localPackageName` and `target` may be thought of as equivalent
+ to the key-value pairs in the `dependency` or `devDepencency`
+ objects contained within a bower.json file.
+
+ Examples:
+
+ addBowerPackageToProject('jquery', '~1.11.1');
+ addBowerPackageToProject('old_jquery', 'jquery#~1.9.1');
+ addBowerPackageToProject('bootstrap-3', 'http://twitter.github.io/bootstrap/assets/bootstrap');
+
+ @method addBowerPackageToProject
+ @param {String} localPackageName
+ @param {String} target
+ @param {Object} installOptions
+ @return {Promise}
+ */
+Blueprint.prototype.addBowerPackageToProject = function (localPackageName, target, installOptions) {
+ // var lpn = localPackageName;
+ // var tar = target;
+ // if (localPackageName.indexOf('#') >= 0) {
+ // if (arguments.length === 1) {
+ // var parts = localPackageName.split('#');
+ // lpn = parts[0];
+ // tar = parts[1];
+ // this.ui.writeDeprecateLine('passing ' + localPackageName +
+ // ' directly to `addBowerPackageToProject` will soon be unsupported. \n' +
+ // 'You may want to replace this with ' +
+ // '`addBowerPackageToProject(\'' + lpn + '\', \'' + tar + '\')`');
+ // } else {
+ // this.ui.writeDeprecateLine('passing ' + localPackageName +
+ // ' directly to `addBowerPackageToProject` will soon be unsupported');
+ // }
+ // }
+ // var packageObject = bowEpParser.json2decomposed(lpn, tar);
+ // return this.addBowerPackagesToProject([packageObject], installOptions);
+ return Promise.resolve();
+};
+
+/**
+ Used to add an array of packages to the projects `bower.json`.
+
+ Generally, this would be done from the `afterInstall` hook, to
+ ensure that a package that is required by a given blueprint is
+ available.
+
+ Expects each array item to be an object with a `name`. Each object
+ may optionally have a `target` to specify a specific version.
+
+ @method addBowerPackagesToProject
+ @param {Array} packages
+ @param {Object} installOptions
+ @return {Promise}
+ */
+Blueprint.prototype.addBowerPackagesToProject = function (packages, installOptions) {
+ var task = this.taskFor('bower-install');
+ var installText = (packages.length > 1) ? 'install bower packages' : 'install bower package';
+ var packageNames = [];
+ var packageNamesAndVersions = packages.map(function (pkg) {
+ pkg.source = pkg.source || pkg.name;
+ packageNames.push(pkg.name);
+ return pkg;
+ }).map(bowEpParser.compose);
+
+ this._writeStatusToUI(chalk.green, installText, packageNames.join(', '));
+
+ return task.run({
+ verbose: true,
+ packages: packageNamesAndVersions,
+ installOptions: installOptions
+ });
+};
+
+/**
+ Used to retrieve a task with the given name. Passes the new task
+ the standard information available (like `ui`, `analytics`, `project`, etc).
+
+ @method taskFor
+ @param dasherizedName
+ @public
+ */
+Blueprint.prototype.taskFor = function (dasherizedName) {
+ var Task = require('../tasks/' + dasherizedName);
+
+ return new Task({
+ ui: this.ui,
+ project: this.project,
+ analytics: this.analytics
+ });
+};
+
+/*
+
+ Inserts the given content into a file. If the `contentsToInsert` string is already
+ present in the current contents, the file will not be changed unless `force` option
+ is passed.
+
+ If `options.before` is specified, `contentsToInsert` will be inserted before
+ the first instance of that string. If `options.after` is specified, the
+ contents will be inserted after the first instance of that string.
+ If the string specified by options.before or options.after is not in the file,
+ no change will be made.
+
+ If neither `options.before` nor `options.after` are present, `contentsToInsert`
+ will be inserted at the end of the file.
+
+ Example:
+ ```
+ // app/router.js
+ Router.map(function() {
+ });
+
+ insertIntoFile('app/router.js',
+ ' this.route("admin");',
+ {after:'Router.map(function() {'+EOL});
+
+ // new app/router.js
+ Router.map(function() {
+ this.route("admin");
+ });
+ ```
+
+ @method insertIntoFile
+ @param {String} pathRelativeToProjectRoot
+ @param {String} contentsToInsert
+ @param {Object} options
+ @return {Promise}
+ */
+Blueprint.prototype.insertIntoFile = function (pathRelativeToProjectRoot, contentsToInsert, providedOptions) {
+ var fullPath = path.join(this.project.root, pathRelativeToProjectRoot);
+ var originalContents = '';
+
+ if (existsSync(fullPath)) {
+ originalContents = fs.readFileSync(fullPath, {encoding: 'utf8'});
+ }
+
+ var contentsToWrite = originalContents;
+
+ var options = providedOptions || {};
+ var alreadyPresent = originalContents.indexOf(contentsToInsert) > -1;
+ var insert = !alreadyPresent;
+ var insertBehavior = 'end';
+
+ if (options.before) {
+ insertBehavior = 'before';
+ }
+ if (options.after) {
+ insertBehavior = 'after';
+ }
+
+ if (options.force) {
+ insert = true;
+ }
+
+ if (insert) {
+ if (insertBehavior === 'end') {
+ contentsToWrite += contentsToInsert;
+ } else {
+ var contentMarker = options[insertBehavior];
+ var contentMarkerIndex = contentsToWrite.indexOf(contentMarker);
+
+ if (contentMarkerIndex !== -1) {
+ var insertIndex = contentMarkerIndex;
+ if (insertBehavior === 'after') {
+ insertIndex += contentMarker.length;
+ }
+
+ contentsToWrite = contentsToWrite.slice(0, insertIndex) +
+ contentsToInsert + EOL +
+ contentsToWrite.slice(insertIndex);
+ }
+ }
+ }
+
+ var returnValue = {
+ path: fullPath,
+ originalContents: originalContents,
+ contents: contentsToWrite,
+ inserted: false
+ };
+
+ if (contentsToWrite !== originalContents) {
+ returnValue.inserted = true;
+
+ return writeFile(fullPath, contentsToWrite)
+ .then(function () {
+ return returnValue;
+ });
+ } else {
+ return Promise.resolve(returnValue);
+ }
+};
+
+Blueprint.prototype._printCommand = printCommand;
+
+Blueprint.prototype.printBasicHelp = function (verbose) {
+ var initialMargin = ' ';
+ var output = initialMargin;
+ if (this.overridden) {
+ output += chalk.grey('(overridden) ' + this.name);
+ } else {
+ output += this.name;
+
+ output += this._printCommand(initialMargin, true);
+
+ if (verbose) {
+ output += EOL + this.printDetailedHelp(this.availableOptions);
+ }
+ }
+
+ return output;
+};
+
+Blueprint.prototype.printDetailedHelp = function () {
+ var markdownColor = new MarkdownColor();
+ var filePath = getDetailedHelpPath(this.path);
+
+ if (existsSync(filePath)) {
+ return markdownColor.renderFile(filePath, {indent: ' '});
+ }
+ return '';
+};
+
+Blueprint.prototype.getJson = function (verbose) {
+ var json = {};
+
+ printableProperties.forEachWithProperty(function (key) {
+ var value = this[key];
+ if (key === 'availableOptions') {
+ value = cloneDeep(value);
+ value.forEach(function (option) {
+ if (typeof option.type === 'function') {
+ option.type = option.type.name;
+ }
+ });
+ }
+ json[key] = value;
+ }, this);
+
+ if (verbose) {
+ var detailedHelp = this.printDetailedHelp(this.availableOptions);
+ if (detailedHelp) {
+ json.detailedHelp = detailedHelp;
+ }
+ }
+
+ return json;
+};
+
+/**
+ Used to retrieve a blueprint with the given name.
+
+ @method lookupBlueprint
+ @param dasherizedName
+ @public
+ */
+Blueprint.prototype.lookupBlueprint = function (dasherizedName) {
+ var projectPaths = this.project ? this.project.blueprintLookupPaths() : [];
+
+ return Blueprint.lookup(dasherizedName, {
+ paths: projectPaths
+ });
+};
+
+/**
+ @static
+ @method lookup
+ @namespace Blueprint
+ @param {String} [name]
+ @param {Object} [options]
+ @param {Array} [options.paths] Extra paths to search for blueprints
+ @param {Object} [options.properties] Properties
+ @return {Blueprint}
+ */
+Blueprint.lookup = function (name, options) {
+ options = options || {};
+
+ var lookupPaths = generateLookupPaths(options.paths);
+
+ var lookupPath;
+ var blueprintPath;
+
+ for (var i = 0; (lookupPath = lookupPaths[i]); i++) {
+ blueprintPath = path.resolve(lookupPath, name);
+
+ if (existsSync(blueprintPath)) {
+ return Blueprint.load(blueprintPath);
+ }
+ }
+
+ if (!options.ignoreMissing) {
+ throw new SilentError('Unknown blueprint: ' + name);
+ }
+};
+
+/**
+ Loads a blueprint from given path.
+ @static
+ @method load
+ @namespace Blueprint
+ @param {String} blueprintPath
+ @return {Blueprint} blueprint instance
+ */
+Blueprint.load = function (blueprintPath) {
+ var constructorPath = path.resolve(blueprintPath, 'index.js');
+ var blueprintModule;
+ var Constructor = Blueprint;
+
+ if (fs.lstatSync(blueprintPath).isDirectory()) {
+
+ if (existsSync(constructorPath)) {
+ blueprintModule = require(constructorPath);
+
+ if (typeof blueprintModule === 'function') {
+ Constructor = blueprintModule;
+ } else {
+ Constructor = Blueprint.extend(blueprintModule);
+ }
+ }
+
+ return new Constructor(blueprintPath);
+ }
+
+ return;
+};
+
+/**
+ @static
+ @method list
+ @namespace Blueprint
+ @param {Object} [options]
+ @param {Array} [options.paths] Extra paths to search for blueprints
+ @return {Blueprint}
+ */
+Blueprint.list = function (options) {
+ options = options || {};
+
+ var lookupPaths = generateLookupPaths(options.paths);
+ var seen = [];
+
+ return lookupPaths.map(function (lookupPath) {
+ var blueprints = dir(lookupPath);
+ var packagePath = path.join(lookupPath, '../package.json');
+ var source;
+
+ if (existsSync(packagePath)) {
+ source = require(packagePath).name;
+ } else {
+ source = path.basename(path.join(lookupPath, '..'));
+ }
+
+ blueprints = blueprints.map(function (blueprintPath) {
+ var blueprint = Blueprint.load(blueprintPath);
+ var name;
+
+ if (blueprint) {
+ name = blueprint.name;
+ blueprint.overridden = includes(seen, name);
+ seen.push(name);
+
+ return blueprint;
+ }
+
+ return;
+ });
+
+ return {
+ source: source,
+ blueprints: compact(blueprints)
+ };
+ });
+};
+
+/**
+ @static
+ @property renameFiles
+ */
+Blueprint.renamedFiles = {
+ 'gitignore': '.gitignore'
+};
+
+/**
+ @static
+ @property ignoredFiles
+ */
+Blueprint.ignoredFiles = [
+ '.DS_Store'
+];
+
+/**
+ @static
+ @property ignoredUpdateFiles
+ */
+Blueprint.ignoredUpdateFiles = [
+ '.gitkeep',
+ 'app.css'
+];
+
+/**
+ @static
+ @property defaultLookupPaths
+ */
+Blueprint.defaultLookupPaths = function () {
+ return [
+ path.resolve(__dirname, '..', '..', 'blueprints')
+ ];
+};
+
+/**
+ @private
+ @method prepareConfirm
+ @param {FileInfo} info
+ @return {Promise}
+ */
+function prepareConfirm(info) {
+ return info.checkForConflict().then(function (resolution) {
+ info.resolution = resolution;
+ return info;
+ });
+}
+
+/**
+ @private
+ @method markIdenticalToBeSkipped
+ @param {FileInfo} info
+ */
+function markIdenticalToBeSkipped(info) {
+ if (info.resolution === 'identical') {
+ info.action = 'skip';
+ }
+}
+
+/**
+ @private
+ @method markToBeRemoved
+ @param {FileInfo} info
+ */
+function markToBeRemoved(info) {
+ info.action = 'remove';
+}
+
+/**
+ @private
+ @method gatherConfirmationMessages
+ @param {Array} collection
+ @param {FileInfo} info
+ @return {Array}
+ */
+function gatherConfirmationMessages(collection, info) {
+ if (info.resolution === 'confirm') {
+ collection.push(info.confirmOverwriteTask());
+ }
+ return collection;
+}
+
+/**
+ @private
+ @method isFile
+ @param {FileInfo} info
+ @return {Boolean}
+ */
+function isFile(info) {
+ return stat(info.inputPath).invoke('isFile');
+}
+
+/**
+ @private
+ @method isIgnored
+ @param {FileInfo} info
+ @return {Boolean}
+ */
+function isIgnored(info) {
+ var fn = info.inputPath;
+
+ return any(Blueprint.ignoredFiles, function (ignoredFile) {
+ return minimatch(fn, ignoredFile, {matchBase: true});
+ });
+}
+
+/**
+ Combines provided lookup paths with defaults and removes
+ duplicates.
+
+ @private
+ @method generateLookupPaths
+ @param {Array} lookupPaths
+ @return {Array}
+ */
+function generateLookupPaths(lookupPaths) {
+ lookupPaths = lookupPaths || [];
+ lookupPaths = lookupPaths.concat(Blueprint.defaultLookupPaths());
+ return uniq(lookupPaths);
+}
+
+/**
+ Looks for a __path__ token in the files folder. Must be present for
+ the blueprint to support pod tokens.
+
+ @private
+ @method hasPathToken
+ @param {files} files
+ @return {Boolean}
+ */
+function hasPathToken(files) {
+ return files.join().match(/__path__/);
+}
+
+function inRepoAddonExists(name, root) {
+ var addonPath = path.join(root, 'lib', name);
+ return existsSync(addonPath);
+}
+
+function podDeprecations(config, ui) {
+ /*
+ var podModulePrefix = config.podModulePrefix || '';
+ var podPath = podModulePrefix.substr(podModulePrefix.lastIndexOf('/') + 1);
+ // Disabled until we are ready to deprecate podModulePrefix
+ deprecateUI(ui)('`podModulePrefix` is deprecated and will be removed from future versions of ember-cli.'+
+ ' Please move existing pods from \'app/' + podPath + '/\' to \'app/\'.', config.podModulePrefix);
+ */
+ if (config.usePodsByDefault) {
+ ui.writeDeprecateLine('`usePodsByDefault` is no longer supported in \'config/environment.js\',' +
+ ' use `usePods` in \'.ember-cli\' instead.');
+ }
+}
+
+/**
+ @private
+ @method destPath
+ @param {String} intoDir
+ @param {String} file
+ @return {String} new path
+ */
+function destPath(intoDir, file) {
+ return path.join(intoDir, file);
+}
+
+/**
+ @private
+ @method isValidFile
+ @param {Object} fileInfo
+ @return {Promise}
+ */
+function isValidFile(fileInfo) {
+ if (isIgnored(fileInfo)) {
+ return Promise.resolve(false);
+ } else {
+ return isFile(fileInfo);
+ }
+}
+
+/**
+ @private
+ @method isFilePath
+ @param {Object} fileInfo
+ @return {Promise}
+ */
+function isFilePath(fileInfo) {
+ return fs.statSync(fileInfo.inputPath).isFile();
+}
+
+/**
+ @private
+ @method dir
+ @returns {Array} list of files in the given directory or and empty array if no directory exists
+ */
+function dir(fullPath) {
+ if (existsSync(fullPath)) {
+ return fs.readdirSync(fullPath).map(function (fileName) {
+ return path.join(fullPath, fileName);
+ });
+ } else {
+ return [];
+ }
+}
+
+/**
+ @private
+ @method getDetailedHelpPath
+ @param {String} thisPath
+ @return {String} help path
+ */
+function getDetailedHelpPath(thisPath) {
+ return path.join(thisPath, './HELP.md');
+}
diff --git a/packages/angular-cli/ember-cli/lib/models/command.js b/packages/universal-cli/ember-cli/lib/models/command.js
similarity index 99%
rename from packages/angular-cli/ember-cli/lib/models/command.js
rename to packages/universal-cli/ember-cli/lib/models/command.js
index ea960753c3d9..af2d8478dc7f 100644
--- a/packages/angular-cli/ember-cli/lib/models/command.js
+++ b/packages/universal-cli/ember-cli/lib/models/command.js
@@ -293,7 +293,7 @@ Command.prototype.parseAlias = function(option, alias) {
try {
aliasValue = JSON.parse(alias);
} catch (e) {
- var debug = require('debug')('angular-cli/ember-cli/models/command');
+ var debug = require('debug')('universal-cli/ember-cli/models/command');
debug(e);
}
}
diff --git a/packages/angular-cli/ember-cli/lib/models/edit-file-diff.js b/packages/universal-cli/ember-cli/lib/models/edit-file-diff.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/edit-file-diff.js
rename to packages/universal-cli/ember-cli/lib/models/edit-file-diff.js
diff --git a/packages/angular-cli/ember-cli/lib/models/file-info.js b/packages/universal-cli/ember-cli/lib/models/file-info.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/file-info.js
rename to packages/universal-cli/ember-cli/lib/models/file-info.js
diff --git a/packages/angular-cli/ember-cli/lib/models/installation-checker.js b/packages/universal-cli/ember-cli/lib/models/installation-checker.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/installation-checker.js
rename to packages/universal-cli/ember-cli/lib/models/installation-checker.js
diff --git a/packages/angular-cli/ember-cli/lib/models/project.js b/packages/universal-cli/ember-cli/lib/models/project.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/project.js
rename to packages/universal-cli/ember-cli/lib/models/project.js
diff --git a/packages/angular-cli/ember-cli/lib/models/task.js b/packages/universal-cli/ember-cli/lib/models/task.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/task.js
rename to packages/universal-cli/ember-cli/lib/models/task.js
diff --git a/packages/angular-cli/ember-cli/lib/models/watcher.js b/packages/universal-cli/ember-cli/lib/models/watcher.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/models/watcher.js
rename to packages/universal-cli/ember-cli/lib/models/watcher.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks.js b/packages/universal-cli/ember-cli/lib/tasks.js
similarity index 99%
rename from packages/angular-cli/ember-cli/lib/tasks.js
rename to packages/universal-cli/ember-cli/lib/tasks.js
index efb5b22acbaf..47389c5a6388 100644
--- a/packages/angular-cli/ember-cli/lib/tasks.js
+++ b/packages/universal-cli/ember-cli/lib/tasks.js
@@ -8,4 +8,4 @@ module.exports = {
NpmInstall: require('./tasks/npm-install'),
NpmTask: require('./tasks/npm-task'),
NpmUninstall: require('./tasks/npm-uninstall'),
-};
+};
\ No newline at end of file
diff --git a/packages/angular-cli/ember-cli/lib/tasks/create-and-step-into-directory.js b/packages/universal-cli/ember-cli/lib/tasks/create-and-step-into-directory.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/create-and-step-into-directory.js
rename to packages/universal-cli/ember-cli/lib/tasks/create-and-step-into-directory.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/destroy-from-blueprint.js b/packages/universal-cli/ember-cli/lib/tasks/destroy-from-blueprint.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/destroy-from-blueprint.js
rename to packages/universal-cli/ember-cli/lib/tasks/destroy-from-blueprint.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/generate-from-blueprint.js b/packages/universal-cli/ember-cli/lib/tasks/generate-from-blueprint.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/generate-from-blueprint.js
rename to packages/universal-cli/ember-cli/lib/tasks/generate-from-blueprint.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/git-init.js b/packages/universal-cli/ember-cli/lib/tasks/git-init.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/git-init.js
rename to packages/universal-cli/ember-cli/lib/tasks/git-init.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/install-blueprint.js b/packages/universal-cli/ember-cli/lib/tasks/install-blueprint.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/install-blueprint.js
rename to packages/universal-cli/ember-cli/lib/tasks/install-blueprint.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/npm-install.js b/packages/universal-cli/ember-cli/lib/tasks/npm-install.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/npm-install.js
rename to packages/universal-cli/ember-cli/lib/tasks/npm-install.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/npm-task.js b/packages/universal-cli/ember-cli/lib/tasks/npm-task.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/npm-task.js
rename to packages/universal-cli/ember-cli/lib/tasks/npm-task.js
diff --git a/packages/angular-cli/ember-cli/lib/tasks/npm-uninstall.js b/packages/universal-cli/ember-cli/lib/tasks/npm-uninstall.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/tasks/npm-uninstall.js
rename to packages/universal-cli/ember-cli/lib/tasks/npm-uninstall.js
diff --git a/packages/angular-cli/ember-cli/lib/ui/index.js b/packages/universal-cli/ember-cli/lib/ui/index.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/ui/index.js
rename to packages/universal-cli/ember-cli/lib/ui/index.js
diff --git a/packages/angular-cli/ember-cli/lib/ui/write-error.js b/packages/universal-cli/ember-cli/lib/ui/write-error.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/ui/write-error.js
rename to packages/universal-cli/ember-cli/lib/ui/write-error.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/COMMIT_MESSAGE.txt b/packages/universal-cli/ember-cli/lib/utilities/COMMIT_MESSAGE.txt
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/COMMIT_MESSAGE.txt
rename to packages/universal-cli/ember-cli/lib/utilities/COMMIT_MESSAGE.txt
diff --git a/packages/angular-cli/ember-cli/lib/utilities/DAG.js b/packages/universal-cli/ember-cli/lib/utilities/DAG.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/DAG.js
rename to packages/universal-cli/ember-cli/lib/utilities/DAG.js
diff --git a/packages/universal-cli/ember-cli/lib/utilities/attempt-never-index.js b/packages/universal-cli/ember-cli/lib/utilities/attempt-never-index.js
new file mode 100644
index 000000000000..d2ec53254958
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/utilities/attempt-never-index.js
@@ -0,0 +1,20 @@
+'use strict';
+
+var isDarwin = /darwin/i.test(require('os').type());
+var debug = require('debug')('ember-cli:utilities/attempt-metadata-index-file');
+
+module.exports = function(dir) {
+ var path = dir + '/.metadata_never_index';
+
+ if (!isDarwin) {
+ debug('not darwin, skipping %s (which hints to spotlight to prevent indexing)', path);
+ return;
+ }
+
+ debug('creating: %s (to prevent spotlight indexing)', path);
+
+ var fs = require('fs-extra');
+
+ fs.mkdirsSync(dir);
+ fs.writeFileSync(path);
+};
diff --git a/packages/universal-cli/ember-cli/lib/utilities/deprecate.js b/packages/universal-cli/ember-cli/lib/utilities/deprecate.js
new file mode 100644
index 000000000000..35be01d66568
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/utilities/deprecate.js
@@ -0,0 +1,19 @@
+'use strict';
+
+var chalk = require('chalk');
+
+module.exports = function(message, test) {
+ if (test) {
+ console.log(chalk.yellow('DEPRECATION: ' + message));
+ }
+};
+
+module.exports.deprecateUI = function(ui) {
+ return function(message, test) {
+ ui.writeDeprecateLine('The deprecateUI utility has been deprecated in favor of ui.writeDeprecateLine');
+
+ test = !test;
+
+ ui.writeDeprecateLine(message, test);
+ };
+};
diff --git a/packages/universal-cli/ember-cli/lib/utilities/doc-generator.js b/packages/universal-cli/ember-cli/lib/utilities/doc-generator.js
new file mode 100644
index 000000000000..b9cb89f56666
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/utilities/doc-generator.js
@@ -0,0 +1,24 @@
+'use strict';
+
+var versionUtils = require('./version-utils');
+var emberCLIVersion = versionUtils.emberCLIVersion;
+var fs = require('fs');
+
+function DocGenerator(options) {
+ options = options || {};
+ this.exec = options.exec || require('child_process').exec;
+}
+
+DocGenerator.prototype.generate = function() {
+ var command = 'cd docs && ' + fs.realpathSync('./node_modules/.bin/yuidoc') +
+ ' -q --project-version ' + emberCLIVersion(); // add '-p' flag to produce only JSON and not HTML
+
+ console.log('Executing command: ' + command);
+ this.exec(command, function(error) { // stdout, stderr
+ if (error !== null) {
+ console.log('Error: ' + error);
+ }
+ });
+};
+
+module.exports = DocGenerator;
diff --git a/packages/universal-cli/ember-cli/lib/utilities/find-build-file.js b/packages/universal-cli/ember-cli/lib/utilities/find-build-file.js
new file mode 100644
index 000000000000..4ebbc0655654
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/utilities/find-build-file.js
@@ -0,0 +1,28 @@
+'use strict';
+
+var findUp = require('findup').sync;
+var path = require('path');
+
+module.exports = function(file) {
+ var buildFilePath = findUp(file);
+
+ // Note
+ // In the future this should throw
+ if (buildFilePath === null) {
+ return null;
+ }
+
+ var baseDir = path.dirname(buildFilePath);
+
+ process.chdir(baseDir);
+
+ var buildFile = null;
+ try {
+ buildFile = require(buildFilePath);
+ } catch (err) {
+ err.message = 'Could not require \'' + file + '\': ' + err.message;
+ throw err;
+ }
+
+ return buildFile;
+};
diff --git a/packages/angular-cli/ember-cli/lib/utilities/get-option-args.js b/packages/universal-cli/ember-cli/lib/utilities/get-option-args.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/get-option-args.js
rename to packages/universal-cli/ember-cli/lib/utilities/get-option-args.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/get-package-base-name.js b/packages/universal-cli/ember-cli/lib/utilities/get-package-base-name.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/get-package-base-name.js
rename to packages/universal-cli/ember-cli/lib/utilities/get-package-base-name.js
diff --git a/packages/universal-cli/ember-cli/lib/utilities/json-generator.js b/packages/universal-cli/ember-cli/lib/utilities/json-generator.js
new file mode 100644
index 000000000000..0307d3aaa442
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/utilities/json-generator.js
@@ -0,0 +1,100 @@
+'use strict';
+
+var lookupCommand = require('../cli/lookup-command');
+var stringUtils = require('ember-cli-string-utils');
+var assign = require('lodash/assign');
+var GenerateCommand = require('../commands/generate');
+var RootCommand = require('./root-command');
+var versionUtils = require('./version-utils');
+var emberCLIVersion = versionUtils.emberCLIVersion;
+
+function JsonGenerator(options) {
+ options = options || {};
+
+ this.ui = options.ui;
+ this.project = options.project;
+ this.commands = options.commands;
+ this.tasks = options.tasks;
+}
+
+JsonGenerator.prototype.generate = function(commandOptions, rawArgs) {
+ var rootCommand = new RootCommand({
+ ui: this.ui,
+ project: this.project,
+ commands: this.commands,
+ tasks: this.tasks
+ });
+
+ var json = rootCommand.getJson(commandOptions);
+ json.version = emberCLIVersion();
+ json.commands = [];
+ json.addons = [];
+
+ if (rawArgs.length === 0) {
+ Object.keys(this.commands).forEach(function(commandName) {
+ this._addCommandHelpToJson(commandName, false, commandOptions, json);
+ }, this);
+
+ if (this.project.eachAddonCommand) {
+ this.project.eachAddonCommand(function(addonName, commands) {
+ this.commands = commands;
+
+ var addonJson = { name: addonName };
+ addonJson.commands = [];
+ json.addons.push(addonJson);
+
+ Object.keys(this.commands).forEach(function(commandName) {
+ this._addCommandHelpToJson(commandName, false, commandOptions, addonJson);
+ }, this);
+ }.bind(this));
+ }
+ } else {
+ // If args were passed to the help command,
+ // attempt to look up the command for each of them.
+
+ if (this.project.eachAddonCommand) {
+ this.project.eachAddonCommand(function(addonName, commands) {
+ assign(this.commands, commands);
+ }.bind(this));
+ }
+
+ var multipleCommands = [GenerateCommand.prototype.name].concat(GenerateCommand.prototype.aliases);
+ if (multipleCommands.indexOf(rawArgs[0]) > -1) {
+ var command = rawArgs.shift();
+ if (rawArgs.length > 0) {
+ commandOptions.rawArgs = rawArgs;
+ }
+ rawArgs = [command];
+ }
+
+ // Iterate through each arg beyond the initial 'help' command,
+ // and try to display usage instructions.
+ rawArgs.forEach(function(commandName) {
+ this._addCommandHelpToJson(commandName, true, commandOptions, json);
+ }, this);
+ }
+
+ return json;
+};
+
+
+JsonGenerator.prototype._addCommandHelpToJson = function(commandName, single, options, json) {
+ var command = this._lookupCommand(commandName);
+ if ((!command.skipHelp || single) && !command.unknown) {
+ json.commands.push(command.getJson(options));
+ }
+};
+
+JsonGenerator.prototype._lookupCommand = function(commandName) {
+ var Command = this.commands[stringUtils.classify(commandName)] ||
+ lookupCommand(this.commands, commandName);
+
+ return new Command({
+ ui: this.ui,
+ project: this.project,
+ commands: this.commands,
+ tasks: this.tasks
+ });
+};
+
+module.exports = JsonGenerator;
diff --git a/packages/angular-cli/ember-cli/lib/utilities/markdown-color.js b/packages/universal-cli/ember-cli/lib/utilities/markdown-color.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/markdown-color.js
rename to packages/universal-cli/ember-cli/lib/utilities/markdown-color.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/merge-blueprint-options.js b/packages/universal-cli/ember-cli/lib/utilities/merge-blueprint-options.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/merge-blueprint-options.js
rename to packages/universal-cli/ember-cli/lib/utilities/merge-blueprint-options.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/mk-tmp-dir-in.js b/packages/universal-cli/ember-cli/lib/utilities/mk-tmp-dir-in.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/mk-tmp-dir-in.js
rename to packages/universal-cli/ember-cli/lib/utilities/mk-tmp-dir-in.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/normalize-blueprint-option.js b/packages/universal-cli/ember-cli/lib/utilities/normalize-blueprint-option.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/normalize-blueprint-option.js
rename to packages/universal-cli/ember-cli/lib/utilities/normalize-blueprint-option.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/open-editor.js b/packages/universal-cli/ember-cli/lib/utilities/open-editor.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/open-editor.js
rename to packages/universal-cli/ember-cli/lib/utilities/open-editor.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/parse-options.js b/packages/universal-cli/ember-cli/lib/utilities/parse-options.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/parse-options.js
rename to packages/universal-cli/ember-cli/lib/utilities/parse-options.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/path.js b/packages/universal-cli/ember-cli/lib/utilities/path.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/path.js
rename to packages/universal-cli/ember-cli/lib/utilities/path.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/platform-checker.js b/packages/universal-cli/ember-cli/lib/utilities/platform-checker.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/platform-checker.js
rename to packages/universal-cli/ember-cli/lib/utilities/platform-checker.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/print-command.js b/packages/universal-cli/ember-cli/lib/utilities/print-command.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/print-command.js
rename to packages/universal-cli/ember-cli/lib/utilities/print-command.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/printable-properties.js b/packages/universal-cli/ember-cli/lib/utilities/printable-properties.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/printable-properties.js
rename to packages/universal-cli/ember-cli/lib/utilities/printable-properties.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/require-as-hash.js b/packages/universal-cli/ember-cli/lib/utilities/require-as-hash.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/require-as-hash.js
rename to packages/universal-cli/ember-cli/lib/utilities/require-as-hash.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/require-local.js b/packages/universal-cli/ember-cli/lib/utilities/require-local.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/require-local.js
rename to packages/universal-cli/ember-cli/lib/utilities/require-local.js
diff --git a/packages/universal-cli/ember-cli/lib/utilities/root-command.js b/packages/universal-cli/ember-cli/lib/utilities/root-command.js
new file mode 100644
index 000000000000..785048094c6e
--- /dev/null
+++ b/packages/universal-cli/ember-cli/lib/utilities/root-command.js
@@ -0,0 +1,12 @@
+'use strict';
+
+var Command = require('../models/command');
+
+module.exports = Command.extend({
+ isRoot: true,
+ name: 'ember',
+
+ anonymousOptions: [
+ ''
+ ]
+});
diff --git a/packages/angular-cli/ember-cli/lib/utilities/sequence.js b/packages/universal-cli/ember-cli/lib/utilities/sequence.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/sequence.js
rename to packages/universal-cli/ember-cli/lib/utilities/sequence.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/valid-project-name.js b/packages/universal-cli/ember-cli/lib/utilities/valid-project-name.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/valid-project-name.js
rename to packages/universal-cli/ember-cli/lib/utilities/valid-project-name.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/version-utils.js b/packages/universal-cli/ember-cli/lib/utilities/version-utils.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/version-utils.js
rename to packages/universal-cli/ember-cli/lib/utilities/version-utils.js
diff --git a/packages/angular-cli/ember-cli/lib/utilities/windows-admin.js b/packages/universal-cli/ember-cli/lib/utilities/windows-admin.js
similarity index 100%
rename from packages/angular-cli/ember-cli/lib/utilities/windows-admin.js
rename to packages/universal-cli/ember-cli/lib/utilities/windows-admin.js
diff --git a/packages/angular-cli/lib/cli/index.js b/packages/universal-cli/lib/cli/index.js
similarity index 54%
rename from packages/angular-cli/lib/cli/index.js
rename to packages/universal-cli/lib/cli/index.js
index 9c0eebed47ab..cc93732f6a3f 100644
--- a/packages/angular-cli/lib/cli/index.js
+++ b/packages/universal-cli/lib/cli/index.js
@@ -10,7 +10,7 @@ Error.stackTraceLimit = Infinity;
module.exports = function(options) {
- // patch UI to not print Ember-CLI warnings (which don't apply to Angular-CLI)
+ // patch UI to not print Ember-CLI warnings (which don't apply to Universal-CLI)
UI.prototype.writeWarnLine = function () { }
// patch Watcher to always default to node, not checking for Watchman
@@ -20,10 +20,30 @@ module.exports = function(options) {
return Promise.resolve(options);
}
+ const oldStdoutWrite = process.stdout.write;
+ process.stdout.write = function (line) {
+ line = line.toString();
+ if (line.match(/ember-cli-(inject-)?live-reload/)) {
+ // don't replace 'ember-cli-live-reload' on ung init diffs
+ return oldStdoutWrite.apply(process.stdout, arguments);
+ }
+ line = line.replace(/ember-cli(?!.com)/g, 'universal-cli')
+ .replace(/\bember\b(?!-cli.com)/g, 'ung');
+ return oldStdoutWrite.apply(process.stdout, arguments);
+ };
+
+ const oldStderrWrite = process.stderr.write;
+ process.stderr.write = function (line) {
+ line = line.toString()
+ .replace(/ember-cli(?!.com)/g, 'universal-cli')
+ .replace(/\bember\b(?!-cli.com)/g, 'ung');
+ return oldStderrWrite.apply(process.stdout, arguments);
+ };
+
options.cli = {
- name: 'ng',
+ name: 'ung',
root: path.join(__dirname, '..', '..'),
- npmPackage: 'angular-cli'
+ npmPackage: 'universal-cli'
};
// ensure the environemnt variable for dynamic paths
diff --git a/packages/angular-cli/lib/config/schema.d.ts b/packages/universal-cli/lib/config/schema.d.ts
similarity index 86%
rename from packages/angular-cli/lib/config/schema.d.ts
rename to packages/universal-cli/lib/config/schema.d.ts
index 1f5ea0d0d526..370a8ddeba5c 100644
--- a/packages/angular-cli/lib/config/schema.d.ts
+++ b/packages/universal-cli/lib/config/schema.d.ts
@@ -12,13 +12,15 @@ export interface CliConfig {
apps?: {
root?: string;
outDir?: string;
- assets?: string;
+ assets?: string[];
index?: string;
main?: string;
+ nodeMain?: string;
test?: string;
tsconfig?: string;
prefix?: string;
mobile?: boolean;
+ universal?: boolean;
/**
* Global styles to be included in the build.
*/
@@ -33,6 +35,13 @@ export interface CliConfig {
environments?: {
[name: string]: any;
};
+ /**
+ * Name and corresponding file for custom webpack config.
+ */
+ webpackCustom?: {
+ client?: string;
+ server?: string;
+ };
}[];
/**
* Configuration reserved for installed third party addons.
diff --git a/packages/angular-cli/lib/config/schema.json b/packages/universal-cli/lib/config/schema.json
similarity index 91%
rename from packages/angular-cli/lib/config/schema.json
rename to packages/universal-cli/lib/config/schema.json
index 2334acd76427..df715f2e1245 100644
--- a/packages/angular-cli/lib/config/schema.json
+++ b/packages/universal-cli/lib/config/schema.json
@@ -52,6 +52,9 @@
"main": {
"type": "string"
},
+ "nodeMain": {
+ "type": "string"
+ },
"test": {
"type": "string"
},
@@ -64,6 +67,9 @@
"mobile": {
"type": "boolean"
},
+ "universal": {
+ "type": "boolean"
+ },
"styles": {
"description": "Global styles to be included in the build.",
"type": "array",
@@ -110,6 +116,19 @@
"description": "Name and corresponding file for environment config.",
"type": "object",
"additionalProperties": true
+ },
+ "webpackCustom": {
+ "description": "Name and corresponding file for custom webpack config.",
+ "type": "object",
+ "properties": {
+ "client": {
+ "type": "string"
+ },
+ "server": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
}
},
"additionalProperties": false
diff --git a/packages/angular-cli/lib/webpack/compression-plugin.ts b/packages/universal-cli/lib/webpack/compression-plugin.ts
similarity index 97%
rename from packages/angular-cli/lib/webpack/compression-plugin.ts
rename to packages/universal-cli/lib/webpack/compression-plugin.ts
index 32c627f17f58..6bae1ea0f697 100644
--- a/packages/angular-cli/lib/webpack/compression-plugin.ts
+++ b/packages/universal-cli/lib/webpack/compression-plugin.ts
@@ -26,8 +26,8 @@ export class CompressionPlugin {
private algorithm: Function;
private compressionOptions: any = {};
private test: RegExp[];
- private threshold: number = 0;
- private minRatio: number = 0.8;
+ private threshold = 0;
+ private minRatio = 0.8;
constructor(options: CompressionPluginOptions = {}) {
if (options.hasOwnProperty('asset')) {
diff --git a/packages/angular-cli/models/config.ts b/packages/universal-cli/models/config.ts
similarity index 95%
rename from packages/angular-cli/models/config.ts
rename to packages/universal-cli/models/config.ts
index f98e113f070a..dc5a8a6b602c 100644
--- a/packages/angular-cli/models/config.ts
+++ b/packages/universal-cli/models/config.ts
@@ -30,7 +30,7 @@ function getUserHome() {
export class CliConfig extends CliConfigBase {
static configFilePath(projectPath?: string): string {
- // Find the configuration, either where specified, in the angular-cli project
+ // Find the configuration, either where specified, in the universal-cli project
// (if it's in node_modules) or from the current process.
return (projectPath && _findUp(CLI_CONFIG_FILE_NAME, projectPath))
|| _findUp(CLI_CONFIG_FILE_NAME, process.cwd())
@@ -59,7 +59,7 @@ export class CliConfig extends CliConfigBase {
console.error(chalk.yellow(oneLine`
The "defaults.prefix" and "defaults.sourceDir" properties of angular-cli.json
are deprecated in favor of "apps[0].root" and "apps[0].prefix".\n
- Please update in order to avoid errors in future versions of angular-cli.
+ Please update in order to avoid errors in future versions of universal-cli.
`));
}
diff --git a/packages/angular-cli/models/config/config.ts b/packages/universal-cli/models/config/config.ts
similarity index 100%
rename from packages/angular-cli/models/config/config.ts
rename to packages/universal-cli/models/config/config.ts
diff --git a/packages/angular-cli/models/error.ts b/packages/universal-cli/models/error.ts
similarity index 100%
rename from packages/angular-cli/models/error.ts
rename to packages/universal-cli/models/error.ts
diff --git a/packages/universal-cli/models/find-lazy-modules.ts b/packages/universal-cli/models/find-lazy-modules.ts
new file mode 100644
index 000000000000..37c04c2f637f
--- /dev/null
+++ b/packages/universal-cli/models/find-lazy-modules.ts
@@ -0,0 +1,77 @@
+import * as fs from 'fs';
+import * as glob from 'glob';
+import * as path from 'path';
+import * as ts from 'typescript';
+const resolve = require('resolve');
+
+import {getSource, findNodes, getContentOfKeyLiteral} from '../utilities/ast-utils';
+
+
+export function findLoadChildren(tsFilePath: string): string[] {
+ const source = getSource(tsFilePath);
+ const unique: { [path: string]: boolean } = {};
+
+ return (
+ // Find all object literals.
+ findNodes(source, ts.SyntaxKind.ObjectLiteralExpression)
+ // Get all their property assignments.
+ .map(node => findNodes(node, ts.SyntaxKind.PropertyAssignment))
+ // Flatten into a single array (from an array of array).
+ .reduce((prev, curr) => curr ? prev.concat(curr) : prev, [])
+ // Remove every property assignment that aren't 'loadChildren'.
+ .filter((node: ts.PropertyAssignment) => {
+ const key = getContentOfKeyLiteral(source, node.name);
+ if (!key) {
+ // key is an expression, can't do anything.
+ return false;
+ }
+ return key == 'loadChildren';
+ })
+ // Remove initializers that are not files.
+ .filter((node: ts.PropertyAssignment) => {
+ return node.initializer.kind === ts.SyntaxKind.StringLiteral;
+ })
+ // Get the full text of the initializer.
+ .map((node: ts.PropertyAssignment) => {
+ const literal = node.initializer as ts.StringLiteral;
+ return literal.text;
+ })
+ // Map to the module name itself.
+ .map((moduleName: string) => moduleName.split('#')[0])
+ // Only get unique values (there might be multiple modules from a single URL, or a module used
+ // multiple times).
+ .filter((value: string) => {
+ if (unique[value]) {
+ return false;
+ } else {
+ unique[value] = true;
+ return true;
+ }
+ }));
+}
+
+export function findLazyModules(projectRoot: any): {[key: string]: string} {
+ const result: {[key: string]: string} = {};
+ glob.sync(path.join(projectRoot, '/**/*.ts'))
+ .forEach(tsPath => {
+ findLoadChildren(tsPath).forEach(moduleName => {
+ let fileName = moduleName.startsWith('.')
+ ? path.resolve(path.dirname(tsPath), moduleName) + '.ts'
+ : path.resolve(projectRoot, moduleName) + '.ts';
+
+ if (fs.existsSync(fileName)) {
+ // Put the moduleName as relative to the main.ts.
+ result[moduleName] = fileName;
+ } else {
+ try {
+ let res = resolve.sync(moduleName, { basedir: projectRoot });
+ if (res) {
+ result[moduleName] = res;
+ }
+ } catch (e) {
+ }
+ }
+ });
+ });
+ return result;
+}
diff --git a/packages/angular-cli/models/index.ts b/packages/universal-cli/models/index.ts
similarity index 84%
rename from packages/angular-cli/models/index.ts
rename to packages/universal-cli/models/index.ts
index b4205cf32e91..b42f1ec12afb 100644
--- a/packages/angular-cli/models/index.ts
+++ b/packages/universal-cli/models/index.ts
@@ -3,3 +3,4 @@ export * from './webpack-build-production';
export * from './webpack-build-development';
export * from './webpack-build-mobile';
export * from './webpack-build-utils';
+export * from './webpack-build-node';
diff --git a/packages/angular-cli/models/json-schema/schema-class-factory.ts b/packages/universal-cli/models/json-schema/schema-class-factory.ts
similarity index 100%
rename from packages/angular-cli/models/json-schema/schema-class-factory.ts
rename to packages/universal-cli/models/json-schema/schema-class-factory.ts
diff --git a/packages/angular-cli/models/json-schema/schema-tree.ts b/packages/universal-cli/models/json-schema/schema-tree.ts
similarity index 99%
rename from packages/angular-cli/models/json-schema/schema-tree.ts
rename to packages/universal-cli/models/json-schema/schema-tree.ts
index 2dd120a22788..86a5d66fa4fc 100644
--- a/packages/angular-cli/models/json-schema/schema-tree.ts
+++ b/packages/universal-cli/models/json-schema/schema-tree.ts
@@ -30,8 +30,8 @@ export abstract class SchemaTreeNode {
// Hierarchy objects
protected _parent: SchemaTreeNode;
- protected _defined: boolean = false;
- protected _dirty: boolean = false;
+ protected _defined = false;
+ protected _dirty = false;
protected _schema: Schema;
protected _name: string;
diff --git a/packages/angular-cli/models/json-schema/serializer.ts b/packages/universal-cli/models/json-schema/serializer.ts
similarity index 100%
rename from packages/angular-cli/models/json-schema/serializer.ts
rename to packages/universal-cli/models/json-schema/serializer.ts
diff --git a/packages/angular-cli/models/webpack-build-common.ts b/packages/universal-cli/models/webpack-build-common.ts
similarity index 93%
rename from packages/angular-cli/models/webpack-build-common.ts
rename to packages/universal-cli/models/webpack-build-common.ts
index d44226a798bf..471f600b44f6 100644
--- a/packages/angular-cli/models/webpack-build-common.ts
+++ b/packages/universal-cli/models/webpack-build-common.ts
@@ -2,7 +2,7 @@ import * as webpack from 'webpack';
import * as path from 'path';
import { GlobCopyWebpackPlugin } from '../plugins/glob-copy-webpack-plugin';
import { SuppressEntryChunksWebpackPlugin } from '../plugins/suppress-entry-chunks-webpack-plugin';
-import { packageChunkSort } from '../utilities/package-chunk-sort';
+import { packageChunkSort } from '../plugins/package-chunk-sort';
import { BaseHrefWebpackPlugin } from '@angular-cli/base-href-webpack';
import { extraEntryParser, makeCssLoaders } from './webpack-build-utils';
@@ -37,14 +37,14 @@ export function getWebpackCommonConfig(
const appRoot = path.resolve(projectRoot, appConfig.root);
const appMain = path.resolve(appRoot, appConfig.main);
const nodeModules = path.resolve(projectRoot, 'node_modules');
+ const entryName: string = path.basename(appMain).replace('.ts', '');
let extraPlugins: any[] = [];
let extraRules: any[] = [];
let lazyChunks: string[] = [];
- let entryPoints: { [key: string]: string[] } = {
- main: [appMain]
- };
+ let entryPoints: { [key: string]: string[] } = {};
+ entryPoints[entryName] = [appMain];
if (!(environment in appConfig.environments)) {
throw new SilentError(`Environment "${environment}" does not exist.`);
@@ -99,7 +99,7 @@ export function getWebpackCommonConfig(
if (vendorChunk) {
extraPlugins.push(new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
- chunks: ['main'],
+ chunks: [appConfig.universal === true ? 'client' : 'main'],
minChunks: (module: any) => module.userRequest && module.userRequest.startsWith(nodeModules)
}));
}
@@ -136,7 +136,8 @@ export function getWebpackCommonConfig(
new HtmlWebpackPlugin({
template: path.resolve(appRoot, appConfig.index),
filename: path.resolve(appConfig.outDir, appConfig.index),
- chunksSortMode: packageChunkSort(['inline', 'styles', 'scripts', 'vendor', 'main']),
+ chunksSortMode: packageChunkSort([
+ 'inline', 'styles', 'scripts', 'vendor', 'main']),
excludeChunks: lazyChunks
}),
new BaseHrefWebpackPlugin({
diff --git a/packages/angular-cli/models/webpack-build-development.ts b/packages/universal-cli/models/webpack-build-development.ts
similarity index 100%
rename from packages/angular-cli/models/webpack-build-development.ts
rename to packages/universal-cli/models/webpack-build-development.ts
diff --git a/packages/angular-cli/models/webpack-build-mobile.ts b/packages/universal-cli/models/webpack-build-mobile.ts
similarity index 100%
rename from packages/angular-cli/models/webpack-build-mobile.ts
rename to packages/universal-cli/models/webpack-build-mobile.ts
diff --git a/packages/universal-cli/models/webpack-build-node.ts b/packages/universal-cli/models/webpack-build-node.ts
new file mode 100644
index 000000000000..92300c7de309
--- /dev/null
+++ b/packages/universal-cli/models/webpack-build-node.ts
@@ -0,0 +1,202 @@
+import * as path from 'path';
+import * as webpack from 'webpack';
+import { CompressionPlugin } from '../lib/webpack/compression-plugin';
+import { SuppressEntryChunksWebpackPlugin } from '../plugins/suppress-entry-chunks-webpack-plugin';
+import { extraEntryParser, makeCssLoaders } from './webpack-build-utils';
+
+const webpackMerge = require('webpack-merge');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const ProgressPlugin = require('webpack/lib/ProgressPlugin');
+const autoprefixer = require('autoprefixer');
+const postcssDiscardComments = require('postcss-discard-comments');
+
+export function getWebpackNodeConfig(
+ projectRoot: string,
+ environment: string,
+ appConfig: any,
+ baseHref: string,
+ sourcemap: boolean,
+ verbose: boolean,
+ progress: boolean
+) {
+ const checkNodeImport = function (context: any, request: any, cb: any) {
+ if (!path.isAbsolute(request) && request.charAt(0) !== '.') {
+ cb(null, 'commonjs ' + request);
+ return;
+ }
+ cb();
+ };
+ const appRoot = path.resolve(projectRoot, appConfig.root);
+ const nodeMain = path.resolve(appRoot, appConfig.nodeMain);
+ const nodeModules = path.resolve(projectRoot, 'node_modules');
+ const entryName: string = path.basename(nodeMain).replace('.ts', '');
+
+ let extraPlugins: any[] = [];
+ let extraRules: any[] = [];
+ let lazyChunks: string[] = [];
+
+ let entryPoints: { [key: string]: string[] } = {};
+ entryPoints[entryName] = [nodeMain];
+
+ // process global scripts
+ if (appConfig.scripts.length > 0) {
+ const globalScripts = extraEntryParser(appConfig.scripts, appRoot, 'scripts');
+
+ // add entry points and lazy chunks
+ globalScripts.forEach(script => {
+ if (script.lazy) { lazyChunks.push(script.entry); }
+ entryPoints[script.entry] = (entryPoints[script.entry] || []).concat(script.path);
+ });
+
+ // load global scripts using script-loader
+ extraRules.push({
+ include: globalScripts.map((script) => script.path), test: /\.js$/, loader: 'script-loader'
+ });
+ }
+
+ // process global styles
+ if (appConfig.styles.length === 0) {
+ // create css loaders for component css
+ extraRules.push(...makeCssLoaders());
+ } else {
+ const globalStyles = extraEntryParser(appConfig.styles, appRoot, 'styles');
+ let extractedCssEntryPoints: string[] = [];
+ // add entry points and lazy chunks
+ globalStyles.forEach(style => {
+ if (style.lazy) { lazyChunks.push(style.entry); }
+ if (!entryPoints[style.entry]) {
+ // since this entry point doesn't exist yet, it's going to only have
+ // extracted css and we can supress the entry point
+ extractedCssEntryPoints.push(style.entry);
+ entryPoints[style.entry] = (entryPoints[style.entry] || []).concat(style.path);
+ } else {
+ // existing entry point, just push the css in
+ entryPoints[style.entry].push(style.path);
+ }
+ });
+
+ // create css loaders for component css and for global css
+ extraRules.push(...makeCssLoaders(globalStyles.map((style) => style.path)));
+
+ if (extractedCssEntryPoints.length > 0) {
+ // don't emit the .js entry point for extracted styles
+ extraPlugins.push(new SuppressEntryChunksWebpackPlugin({ chunks: extractedCssEntryPoints }));
+ }
+ }
+
+ if (progress) { extraPlugins.push(new ProgressPlugin({ profile: verbose, colors: true })); }
+
+ const commonConfig: any = {
+ resolve: {
+ extensions: ['.ts', '.js'],
+ modules: [nodeModules]
+ },
+ resolveLoader: {
+ modules: [nodeModules]
+ },
+ context: projectRoot,
+ entry: entryPoints,
+ output: {
+ path: path.resolve(projectRoot, appConfig.outDir, '../server'),
+ filename: '[name].bundle.js',
+ libraryTarget: 'commonjs2'
+ },
+ module: {
+ rules: [
+ { enforce: 'pre', test: /\.js$/, loader: 'source-map-loader', exclude: [nodeModules] },
+
+ { test: /\.json$/, loader: 'json-loader' },
+ { test: /\.(jpg|png|gif)$/, loader: 'url-loader?limit=10000' },
+ { test: /\.html$/, loader: 'raw-loader' },
+
+ { test: /\.(otf|ttf|woff|woff2)$/, loader: 'url-loader?limit=10000' },
+ { test: /\.(eot|svg)$/, loader: 'file-loader' }
+ ].concat(extraRules)
+ },
+ plugins: [
+ new webpack.ContextReplacementPlugin(
+ // The (\\|\/) piece accounts for path separators in *nix and Windows
+ /angular(\\|\/)core(\\|\/)src(\\|\/)linker/,
+ path.resolve(__dirname, './src'),
+ {}
+ ),
+ new webpack.NormalModuleReplacementPlugin(
+ // This plugin is responsible for swapping the environment files.
+ // Since it takes a RegExp as first parameter, we need to escape the path.
+ // See https://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin
+ new RegExp(path.resolve(appRoot, appConfig.environments['source'])
+ .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')),
+ path.resolve(appRoot, appConfig.environments[environment])
+ ),
+ ].concat(extraPlugins),
+ target: 'node',
+ externals: checkNodeImport,
+ node: {
+ global: true,
+ crypto: true,
+ __dirname: false,
+ __filename: true,
+ process: true,
+ Buffer: true
+ }
+ };
+ const devConfig: any = {
+ devtool: 'inline-source-map',
+ plugins: [
+ new ExtractTextPlugin({filename: '[name].bundle.css'}),
+ new webpack.LoaderOptionsPlugin({
+ test: /\.(css|scss|sass|less|styl)$/,
+ options: {
+ postcss: [autoprefixer()],
+ cssLoader: { sourceMap: sourcemap },
+ sassLoader: { sourceMap: sourcemap },
+ lessLoader: { sourceMap: sourcemap },
+ stylusLoader: { sourceMap: sourcemap },
+ // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285
+ context: projectRoot,
+ },
+ })
+ ]
+ };
+ const prodConfig: any = {
+ devtool: 'source-map',
+ plugins: [
+ new ExtractTextPlugin('[name].[chunkhash].bundle.css'),
+ new webpack.LoaderOptionsPlugin({ minimize: true }),
+ new webpack.optimize.UglifyJsPlugin({
+ mangle: {screw_ie8: true},
+ compress: {screw_ie8: true},
+ sourceMap: true
+ }),
+ new CompressionPlugin({
+ asset: '[path].gz[query]',
+ algorithm: 'gzip',
+ test: /\.js$|\.html$/,
+ threshold: 10240,
+ minRatio: 0.8
+ }),
+ // LoaderOptionsPlugin needs to be fully duplicated because webpackMerge will replace it.
+ new webpack.LoaderOptionsPlugin({
+ test: /\.(css|scss|sass|less|styl)$/,
+ options: {
+ postcss: [
+ autoprefixer(),
+ postcssDiscardComments
+ ],
+ cssLoader: { sourceMap: sourcemap },
+ sassLoader: { sourceMap: sourcemap },
+ lessLoader: { sourceMap: sourcemap },
+ stylusLoader: { sourceMap: sourcemap },
+ // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285
+ context: projectRoot,
+ }
+ })
+ ]
+ };
+
+ if (environment === 'prod') {
+ return webpackMerge(commonConfig, prodConfig);
+ } else {
+ return webpackMerge(commonConfig, devConfig);
+ }
+}
diff --git a/packages/angular-cli/models/webpack-build-production.ts b/packages/universal-cli/models/webpack-build-production.ts
similarity index 75%
rename from packages/angular-cli/models/webpack-build-production.ts
rename to packages/universal-cli/models/webpack-build-production.ts
index 12bc762e4130..5c63803a8fb6 100644
--- a/packages/angular-cli/models/webpack-build-production.ts
+++ b/packages/universal-cli/models/webpack-build-production.ts
@@ -5,6 +5,8 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin');
import {CompressionPlugin} from '../lib/webpack/compression-plugin';
const autoprefixer = require('autoprefixer');
const postcssDiscardComments = require('postcss-discard-comments');
+const webpackMerge = require('webpack-merge');
+const StringReplacePlugin = require('string-replace-webpack-plugin');
declare module 'webpack' {
export interface LoaderOptionsPlugin {}
@@ -22,7 +24,33 @@ export const getWebpackProdConfigPartial = function(projectRoot: string,
verbose: any) {
const appRoot = path.resolve(projectRoot, appConfig.root);
- return {
+ let universalPartial: any = {};
+
+ if (appConfig.universal === true) {
+ universalPartial = {
+ module: {
+ rules: [
+ {
+ test: /index.html$/,
+ loader: StringReplacePlugin.replace({
+ replacements: [
+ {
+ pattern:
+ /'
+ );
+ });
+ });
}
diff --git a/tests/e2e/tests/build/scripts-array.ts b/tests/e2e/tests/build/scripts-array.ts
index 995a75381720..9c77b3687847 100644
--- a/tests/e2e/tests/build/scripts-array.ts
+++ b/tests/e2e/tests/build/scripts-array.ts
@@ -5,6 +5,7 @@ import {
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { oneLineTrim } from 'common-tags';
+import { getClientDist, getAppMain } from '../../utils/utils';
export default function () {
return writeMultipleFiles({
@@ -30,23 +31,27 @@ export default function () {
}))
.then(() => ng('build'))
// files were created successfully
- .then(() => expectFileToMatch('dist/scripts.bundle.js', 'string-script'))
- .then(() => expectFileToMatch('dist/scripts.bundle.js', 'input-script'))
- .then(() => expectFileToMatch('dist/lazy-script.bundle.js', 'lazy-script'))
- .then(() => expectFileToMatch('dist/renamed-script.bundle.js', 'pre-rename-script'))
- .then(() => expectFileToMatch('dist/renamed-lazy-script.bundle.js', 'pre-rename-lazy-script'))
- .then(() => expectFileToMatch('dist/common-entry.bundle.js', 'common-entry-script'))
- .then(() => expectFileToMatch('dist/common-entry.bundle.css', '.common-entry-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}scripts.bundle.js`, 'string-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}scripts.bundle.js`, 'input-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}lazy-script.bundle.js`, 'lazy-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}renamed-script.bundle.js`,
+ 'pre-rename-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}renamed-lazy-script.bundle.js`,
+ 'pre-rename-lazy-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}common-entry.bundle.js`,
+ 'common-entry-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}common-entry.bundle.css`,
+ '.common-entry-style'))
// index.html lists the right bundles
- .then(() => expectFileToMatch('dist/index.html', oneLineTrim`
+ .then(() => expectFileToMatch(`${getClientDist()}index.html`, oneLineTrim`
`))
- .then(() => expectFileToMatch('dist/index.html', oneLineTrim`
+ .then(() => expectFileToMatch(`${getClientDist()}index.html`, oneLineTrim`
-
+
`));
}
diff --git a/tests/e2e/tests/build/sourcemap.ts b/tests/e2e/tests/build/sourcemap.ts
index 7029ff872f24..de3265b56523 100644
--- a/tests/e2e/tests/build/sourcemap.ts
+++ b/tests/e2e/tests/build/sourcemap.ts
@@ -1,11 +1,14 @@
-import {ng} from '../../utils/process';
-import {expectFileToExist} from '../../utils/fs';
-import {expectToFail} from '../../utils/utils';
+import { ng } from '../../utils/process';
+import { expectFileToExist } from '../../utils/fs';
+import { expectToFail, getAppMain, getClientDist } from '../../utils/utils';
-export default function() {
+export default function () {
return ng('build')
- .then(() => expectFileToExist('dist/main.bundle.map'))
+ .then(() => expectFileToExist(`${getClientDist()}${getAppMain()}.bundle.map`))
.then(() => ng('build', '--no-sourcemap'))
- .then(() => expectToFail(() => expectFileToExist('dist/main.bundle.map')));
+ .then(() => expectToFail(() => expectFileToExist(
+ `${getClientDist()}${getAppMain()}.bundle.map`
+ ))
+ );
}
diff --git a/tests/e2e/tests/build/styles/css.ts b/tests/e2e/tests/build/styles/css.ts
index f1abac5b37f0..d9d3b7d9427e 100644
--- a/tests/e2e/tests/build/styles/css.ts
+++ b/tests/e2e/tests/build/styles/css.ts
@@ -4,6 +4,7 @@ import {
} from '../../../utils/fs';
import { ng } from '../../../utils/process';
import { stripIndents } from 'common-tags';
+import { getClientDist, getAppMain } from '../../../utils/utils';
export default function () {
return writeMultipleFiles({
@@ -22,9 +23,10 @@ export default function () {
}
`})
.then(() => ng('build'))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/body\s*{\s*background-color: blue;\s*}/))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/p\s*{\s*background-color: red;\s*}/))
- .then(() => expectFileToMatch('dist/main.bundle.js', /.outer.*.inner.*background:\s*#[fF]+/));
+ .then(() => expectFileToMatch(`${getClientDist()}${getAppMain()}.bundle.js`,
+ /.outer.*.inner.*background:\s*#[fF]+/));
}
diff --git a/tests/e2e/tests/build/styles/less.ts b/tests/e2e/tests/build/styles/less.ts
index edb197b9997a..88e11c229798 100644
--- a/tests/e2e/tests/build/styles/less.ts
+++ b/tests/e2e/tests/build/styles/less.ts
@@ -6,9 +6,14 @@ import {
} from '../../../utils/fs';
import { ng } from '../../../utils/process';
import { stripIndents } from 'common-tags';
+import { isMobileTest, getAppMain, getClientDist } from '../../../utils/utils';
import { updateJsonFile } from '../../../utils/project';
export default function () {
+ if (isMobileTest()) {
+ return;
+ }
+
return writeMultipleFiles({
'src/styles.less': stripIndents`
@import './imported-styles.less';
@@ -23,7 +28,8 @@ export default function () {
background: #fff;
}
}
- `})
+ `
+ })
.then(() => deleteFile('src/app/app.component.css'))
.then(() => updateJsonFile('angular-cli.json', configJson => {
const app = configJson['apps'][0];
@@ -32,9 +38,10 @@ export default function () {
.then(() => replaceInFile('src/app/app.component.ts',
'./app.component.css', './app.component.less'))
.then(() => ng('build'))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/body\s*{\s*background-color: blue;\s*}/))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/p\s*{\s*background-color: red;\s*}/))
- .then(() => expectFileToMatch('dist/main.bundle.js', /.outer.*.inner.*background:\s*#[fF]+/));
+ .then(() => expectFileToMatch(`${getClientDist()}${getAppMain()}.bundle.js`,
+ /.outer.*.inner.*background:\s*#[fF]+/));
}
diff --git a/tests/e2e/tests/build/styles/loaders.ts b/tests/e2e/tests/build/styles/loaders.ts
index 9a2121c8f7dd..29ed1f82b408 100644
--- a/tests/e2e/tests/build/styles/loaders.ts
+++ b/tests/e2e/tests/build/styles/loaders.ts
@@ -8,6 +8,7 @@ import { ng } from '../../../utils/process';
import { stripIndents } from 'common-tags';
import { updateJsonFile } from '../../../utils/project';
import { expectToFail } from '../../../utils/utils';
+import { getClientDist, getAppMain } from '../../../utils/utils';
export default function () {
return writeMultipleFiles({
@@ -33,7 +34,8 @@ export default function () {
.then(() => replaceInFile('src/app/app.component.ts',
'./app.component.css', './app.component.scss'))
.then(() => ng('build'))
- .then(() => expectToFail(() => expectFileToMatch('dist/styles.bundle.css', /exports/)))
- .then(() => expectToFail(() => expectFileToMatch('dist/main.bundle.js',
+ .then(() => expectToFail(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
+ /exports/)))
+ .then(() => expectToFail(() => expectFileToMatch(`${getClientDist()}${getAppMain()}.bundle.js`,
/".*module\.exports.*\.outer.*background:/)));
}
diff --git a/tests/e2e/tests/build/styles/postcss.ts b/tests/e2e/tests/build/styles/postcss.ts
index 809ce7919f71..a6aa03bea34b 100644
--- a/tests/e2e/tests/build/styles/postcss.ts
+++ b/tests/e2e/tests/build/styles/postcss.ts
@@ -2,6 +2,7 @@ import * as glob from 'glob';
import { writeFile, expectFileToMatch } from '../../../utils/fs';
import { ng } from '../../../utils/process';
import { stripIndents } from 'common-tags';
+import { getClientDist } from '../../../utils/utils';
export default function () {
return writeFile('src/styles.css', stripIndents`
@@ -11,14 +12,14 @@ export default function () {
`)
// uses autoprefixer plugin for all builds
.then(() => ng('build'))
- .then(() => expectFileToMatch('dist/styles.bundle.css', stripIndents`
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`, stripIndents`
/* normal-comment */
/*! important-comment */
div { -webkit-box-flex: 1; -ms-flex: 1; flex: 1 }
`))
// uses postcss-discard-comments plugin for prod
.then(() => ng('build', '--prod'))
- .then(() => glob.sync('dist/styles.*.bundle.css').find(file => !!file))
+ .then(() => glob.sync(`${getClientDist()}styles.*.bundle.css`).find(file => !!file))
.then((stylesBundle) => expectFileToMatch(stylesBundle, stripIndents`
/*! important-comment */div{-webkit-box-flex:1;-ms-flex:1;flex:1}
`));
diff --git a/tests/e2e/tests/build/styles/scss.ts b/tests/e2e/tests/build/styles/scss.ts
index 9ba76e715617..9860058a75c0 100644
--- a/tests/e2e/tests/build/styles/scss.ts
+++ b/tests/e2e/tests/build/styles/scss.ts
@@ -6,9 +6,14 @@ import {
} from '../../../utils/fs';
import { ng } from '../../../utils/process';
import { stripIndents } from 'common-tags';
+import { isMobileTest, getAppMain, getClientDist } from '../../../utils/utils';
import { updateJsonFile } from '../../../utils/project';
export default function () {
+ if (isMobileTest()) {
+ return;
+ }
+
return writeMultipleFiles({
'src/styles.scss': stripIndents`
@import './imported-styles.scss';
@@ -32,9 +37,10 @@ export default function () {
.then(() => replaceInFile('src/app/app.component.ts',
'./app.component.css', './app.component.scss'))
.then(() => ng('build'))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/body\s*{\s*background-color: blue;\s*}/))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/p\s*{\s*background-color: red;\s*}/))
- .then(() => expectFileToMatch('dist/main.bundle.js', /.outer.*.inner.*background:\s*#[fF]+/));
+ .then(() => expectFileToMatch(`${getClientDist()}${getAppMain()}.bundle.js`,
+ /.outer.*.inner.*background:\s*#[fF]+/));
}
diff --git a/tests/e2e/tests/build/styles/styles-array.ts b/tests/e2e/tests/build/styles/styles-array.ts
index ff913bd63afd..f7df35af8fbd 100644
--- a/tests/e2e/tests/build/styles/styles-array.ts
+++ b/tests/e2e/tests/build/styles/styles-array.ts
@@ -7,6 +7,8 @@ import { ng } from '../../../utils/process';
import { updateJsonFile } from '../../../utils/project';
import { expectToFail } from '../../../utils/utils';
import { oneLineTrim } from 'common-tags';
+import { getClientDist, getAppMain } from '../../../utils/utils';
+
export default function () {
return writeMultipleFiles({
@@ -32,28 +34,33 @@ export default function () {
}))
.then(() => ng('build'))
// files were created successfully
- .then(() => expectFileToMatch('dist/styles.bundle.css', '.string-style'))
- .then(() => expectFileToMatch('dist/styles.bundle.css', '.input-style'))
- .then(() => expectFileToMatch('dist/lazy-style.bundle.css', '.lazy-style'))
- .then(() => expectFileToMatch('dist/renamed-style.bundle.css', '.pre-rename-style'))
- .then(() => expectFileToMatch('dist/renamed-lazy-style.bundle.css', '.pre-rename-lazy-style'))
- .then(() => expectFileToMatch('dist/common-entry.bundle.css', '.common-entry-style'))
- .then(() => expectFileToMatch('dist/common-entry.bundle.js', 'common-entry-script'))
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`, '.string-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`, '.input-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}lazy-style.bundle.css`, '.lazy-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}renamed-style.bundle.css`,
+ '.pre-rename-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}renamed-lazy-style.bundle.css`,
+ '.pre-rename-lazy-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}common-entry.bundle.css`,
+ '.common-entry-style'))
+ .then(() => expectFileToMatch(`${getClientDist()}common-entry.bundle.js`,
+ 'common-entry-script'))
// there are no js entry points for css only bundles
- .then(() => expectToFail(() => expectFileToExist('dist/styles.bundle.js')))
- .then(() => expectToFail(() => expectFileToExist('dist/lazy-styles.bundle.js')))
- .then(() => expectToFail(() => expectFileToExist('dist/renamed-styles.bundle.js')))
- .then(() => expectToFail(() => expectFileToExist('dist/renamed-lazy-styles.bundle.js')))
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}styles.bundle.js`)))
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}lazy-styles.bundle.js`)))
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}renamed-styles.bundle.js`)))
+ .then(() => expectToFail(() =>
+ expectFileToExist(`${getClientDist()}renamed-lazy-styles.bundle.js`)))
// index.html lists the right bundles
- .then(() => expectFileToMatch('dist/index.html', oneLineTrim`
+ .then(() => expectFileToMatch(`${getClientDist()}index.html`, oneLineTrim`
`))
- .then(() => expectFileToMatch('dist/index.html', oneLineTrim`
+ .then(() => expectFileToMatch(`${getClientDist()}index.html`, oneLineTrim`
-
+
`));
}
diff --git a/tests/e2e/tests/build/styles/stylus.ts b/tests/e2e/tests/build/styles/stylus.ts
index b318dfa73d24..89eedd77b929 100644
--- a/tests/e2e/tests/build/styles/stylus.ts
+++ b/tests/e2e/tests/build/styles/stylus.ts
@@ -7,6 +7,7 @@ import {
import { ng } from '../../../utils/process';
import { stripIndents } from 'common-tags';
import { updateJsonFile } from '../../../utils/project';
+import { getClientDist, getAppMain } from '../../../utils/utils';
export default function () {
return writeMultipleFiles({
@@ -32,9 +33,10 @@ export default function () {
.then(() => replaceInFile('src/app/app.component.ts',
'./app.component.css', './app.component.styl'))
.then(() => ng('build'))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/body\s*{\s*background-color: #00f;\s*}/))
- .then(() => expectFileToMatch('dist/styles.bundle.css',
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`,
/p\s*{\s*background-color: #f00;\s*}/))
- .then(() => expectFileToMatch('dist/main.bundle.js', /.outer.*.inner.*background:\s*#[fF]+/));
+ .then(() => expectFileToMatch(`${getClientDist()}${getAppMain()}.bundle.js`,
+ /.outer.*.inner.*background:\s*#[fF]+/));
}
diff --git a/tests/e2e/tests/build/vendor-chunk.ts b/tests/e2e/tests/build/vendor-chunk.ts
index cafc19e3371b..532306b08a50 100644
--- a/tests/e2e/tests/build/vendor-chunk.ts
+++ b/tests/e2e/tests/build/vendor-chunk.ts
@@ -1,11 +1,11 @@
import {ng} from '../../utils/process';
import {expectFileToExist} from '../../utils/fs';
-import {expectToFail} from '../../utils/utils';
+import {expectToFail, getClientDist} from '../../utils/utils';
export default function() {
return ng('build')
- .then(() => expectFileToExist('dist/vendor.bundle.js'))
+ .then(() => expectFileToExist(`${getClientDist()}vendor.bundle.js`))
.then(() => ng('build', '--no-vendor-chunk'))
- .then(() => expectToFail(() => expectFileToExist('dist/vendor.bundle.js')));
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}vendor.bundle.js`)));
}
diff --git a/tests/e2e/tests/misc/assets.ts b/tests/e2e/tests/misc/assets.ts
index 9dd9504cfac2..5ed88444c893 100644
--- a/tests/e2e/tests/misc/assets.ts
+++ b/tests/e2e/tests/misc/assets.ts
@@ -1,22 +1,22 @@
import {writeFile, expectFileToExist, expectFileToMatch} from '../../utils/fs';
import {ng} from '../../utils/process';
import {updateJsonFile} from '../../utils/project';
-import {expectToFail} from '../../utils/utils';
+import { expectToFail, getClientDist } from '../../utils/utils';
export default function() {
return writeFile('src/assets/.file', '')
.then(() => writeFile('src/assets/test.abc', 'hello world'))
.then(() => ng('build'))
- .then(() => expectFileToExist('dist/favicon.ico'))
- .then(() => expectFileToExist('dist/assets/.file'))
- .then(() => expectFileToMatch('dist/assets/test.abc', 'hello world'))
- .then(() => expectToFail(() => expectFileToExist('dist/assets/.gitkeep')))
+ .then(() => expectFileToExist(`${getClientDist()}favicon.ico`))
+ .then(() => expectFileToExist(`${getClientDist()}assets/.file`))
+ .then(() => expectFileToMatch(`${getClientDist()}assets/test.abc`, 'hello world'))
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}assets/.gitkeep`)))
// doesn't break beta.16 projects
.then(() => updateJsonFile('angular-cli.json', configJson => {
const app = configJson['apps'][0];
app['assets'] = 'assets';
}))
- .then(() => expectFileToExist('dist/assets/.file'))
- .then(() => expectFileToMatch('dist/assets/test.abc', 'hello world'));
+ .then(() => expectFileToExist(`${getClientDist()}assets/.file`))
+ .then(() => expectFileToMatch(`${getClientDist()}assets/test.abc`, 'hello world'));
}
diff --git a/tests/e2e/tests/misc/lazy-module.ts b/tests/e2e/tests/misc/lazy-module.ts
index d3d33482d877..45aa0a673f8a 100644
--- a/tests/e2e/tests/misc/lazy-module.ts
+++ b/tests/e2e/tests/misc/lazy-module.ts
@@ -1,33 +1,52 @@
-import {readdirSync} from 'fs';
-import {oneLine} from 'common-tags';
+import { readdirSync } from 'fs';
+import { oneLine } from 'common-tags';
-import {ng} from '../../utils/process';
-import {addImportToModule} from '../../utils/ast';
+import { ng } from '../../utils/process';
+import { addImportToModule } from '../../utils/ast';
+import { isUniversalTest } from '../../utils/utils';
export default function() {
let oldNumberOfFiles = 0;
- return Promise.resolve()
- .then(() => ng('build'))
- .then(() => oldNumberOfFiles = readdirSync('dist').length)
- .then(() => ng('generate', 'module', 'lazy', '--routing'))
- .then(() => addImportToModule('src/app/app.module.ts', oneLine`
+ if (isUniversalTest()) {
+ return Promise.resolve()
+ .then(() => ng('build'))
+ .then(() => oldNumberOfFiles = readdirSync('dist/client').length)
+ .then(() => ng('generate', 'module', 'lazy', '--routing'))
+ .then(() => addImportToModule('src/app/app.browser.module.ts', oneLine`
RouterModule.forRoot([{ path: "lazy", loadChildren: "app/lazy/lazy.module#LazyModule" }]),
RouterModule.forRoot([{ path: "lazy1", loadChildren: "./lazy/lazy.module#LazyModule" }])
`, '@angular/router'))
- .then(() => ng('build'))
- .then(() => readdirSync('dist').length)
- .then(currentNumberOfDistFiles => {
- if (oldNumberOfFiles >= currentNumberOfDistFiles) {
- throw new Error('A bundle for the lazy module was not created.');
- }
- })
- // Check for AoT and lazy routes.
- .then(() => ng('build', '--aot'))
- .then(() => readdirSync('dist').length)
- .then(currentNumberOfDistFiles => {
- if (oldNumberOfFiles >= currentNumberOfDistFiles) {
- throw new Error('A bundle for the lazy module was not created.');
- }
- });
+ .then(() => ng('build'))
+ .then(() => readdirSync('dist/client').length)
+ .then(currentNumberOfDistFiles => {
+ if (oldNumberOfFiles >= currentNumberOfDistFiles) {
+ throw new Error('A bundle for the lazy module was not created.');
+ }
+ });
+ } else {
+ return Promise.resolve()
+ .then(() => ng('build'))
+ .then(() => oldNumberOfFiles = readdirSync('dist').length)
+ .then(() => ng('generate', 'module', 'lazy', '--routing'))
+ .then(() => addImportToModule('src/app/app.module.ts', oneLine`
+ RouterModule.forRoot([{ path: "lazy", loadChildren: "app/lazy/lazy.module#LazyModule" }]),
+ RouterModule.forRoot([{ path: "lazy1", loadChildren: "./lazy/lazy.module#LazyModule" }])
+ `, '@angular/router'))
+ .then(() => ng('build'))
+ .then(() => readdirSync('dist').length)
+ .then(currentNumberOfDistFiles => {
+ if (oldNumberOfFiles >= currentNumberOfDistFiles) {
+ throw new Error('A bundle for the lazy module was not created.');
+ }
+ })
+ // Check for AoT and lazy routes.
+ .then(() => ng('build', '--aot'))
+ .then(() => readdirSync('dist').length)
+ .then(currentNumberOfDistFiles => {
+ if (oldNumberOfFiles >= currentNumberOfDistFiles) {
+ throw new Error('A bundle for the lazy module was not created.');
+ }
+ });
+ }
}
diff --git a/tests/e2e/tests/misc/proxy.ts b/tests/e2e/tests/misc/proxy.ts
index 26e058c863b3..63546f234786 100644
--- a/tests/e2e/tests/misc/proxy.ts
+++ b/tests/e2e/tests/misc/proxy.ts
@@ -5,10 +5,15 @@ import {writeFile} from '../../utils/fs';
import {request} from '../../utils/http';
import {killAllProcesses, ng} from '../../utils/process';
import {ngServe} from '../../utils/project';
-import {expectToFail} from '../../utils/utils';
+import {expectToFail, isUniversalTest} from '../../utils/utils';
export default function() {
+ /** This test is disabled for universal */
+ if (isUniversalTest()) {
+ return Promise.resolve();
+ }
+
// Create an express app that serves as a proxy.
const app = express();
const server = http.createServer(app);
diff --git a/tests/e2e/tests/misc/ssl-default.ts b/tests/e2e/tests/misc/ssl-default.ts
index e16ec54291c9..bd5efadacafe 100644
--- a/tests/e2e/tests/misc/ssl-default.ts
+++ b/tests/e2e/tests/misc/ssl-default.ts
@@ -1,9 +1,15 @@
import { request } from '../../utils/http';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
+import { isUniversalTest } from '../../utils/utils';
export default function() {
+ /** This test is disabled for universal */
+ if (isUniversalTest()) {
+ return Promise.resolve();
+ }
+
return Promise.resolve()
.then(() => ngServe('--ssl', 'true'))
.then(() => request('https://localhost:4200/'))
diff --git a/tests/e2e/tests/misc/ssl-with-cert.ts b/tests/e2e/tests/misc/ssl-with-cert.ts
index 3930c91625fb..b4114efbf123 100644
--- a/tests/e2e/tests/misc/ssl-with-cert.ts
+++ b/tests/e2e/tests/misc/ssl-with-cert.ts
@@ -2,9 +2,15 @@ import { request } from '../../utils/http';
import { assetDir } from '../../utils/assets';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
+import { isUniversalTest } from '../../utils/utils';
export default function() {
+ /** This test is disabled for universal */
+ if (isUniversalTest()) {
+ return Promise.resolve();
+ }
+
return Promise.resolve()
.then(() => ngServe(
'--ssl', 'true',
diff --git a/tests/e2e/tests/misc/universal-serve.ts b/tests/e2e/tests/misc/universal-serve.ts
new file mode 100644
index 000000000000..6e3e42eea3b6
--- /dev/null
+++ b/tests/e2e/tests/misc/universal-serve.ts
@@ -0,0 +1,23 @@
+import { request } from '../../utils/http';
+import { killAllProcesses } from '../../utils/process';
+import { ngUniversalServe } from '../../utils/project';
+import { isUniversalTest } from '../../utils/utils';
+
+
+export default function () {
+ if (!isUniversalTest()) {
+ return Promise.resolve();
+ }
+ return Promise.resolve()
+ .then(() => ngUniversalServe())
+ .then(() => request('http://localhost:4200'))
+ .then(body => {
+ if (!body.match(/app works!/)) {
+ throw new Error('Response does not match expected value.');
+ }
+ })
+ .then(() => killAllProcesses(), (err) => {
+ killAllProcesses();
+ throw err;
+ });
+}
diff --git a/tests/e2e/tests/mobile/prod-features.ts b/tests/e2e/tests/mobile/prod-features.ts
index e649c9a53f69..1b53a4b90b36 100644
--- a/tests/e2e/tests/mobile/prod-features.ts
+++ b/tests/e2e/tests/mobile/prod-features.ts
@@ -1,4 +1,4 @@
-import {isMobileTest, expectToFail} from '../../utils/utils';
+import { isMobileTest, expectToFail, getClientDist } from '../../utils/utils';
import {expectFileToMatch, expectFileToExist} from '../../utils/fs';
@@ -9,12 +9,12 @@ export default function() {
return Promise.resolve()
// Service Worker
- .then(() => expectToFail(() => expectFileToMatch('dist/index.html',
+ .then(() => expectToFail(() => expectFileToMatch(`${getClientDist()}index.html`,
'if (\'serviceWorker\' in navigator) {')))
- .then(() => expectToFail(() => expectFileToExist('dist/worker.js')))
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}worker.js`)))
// Asynchronous bundle
- .then(() => expectToFail(() => expectFileToMatch('dist/index.html',
+ .then(() => expectToFail(() => expectFileToMatch(`${getClientDist()}index.html`,
'')))
- .then(() => expectToFail(() => expectFileToExist('dist/app-concat.js')));
+ .then(() => expectToFail(() => expectFileToExist(`${getClientDist()}app-concat.js`)));
}
diff --git a/tests/e2e/tests/test/e2e.ts b/tests/e2e/tests/test/e2e.ts
index ca66091906c7..6ca7bfc3df8e 100644
--- a/tests/e2e/tests/test/e2e.ts
+++ b/tests/e2e/tests/test/e2e.ts
@@ -1,6 +1,6 @@
-import {ng, killAllProcesses} from '../../utils/process';
-import {expectToFail} from '../../utils/utils';
-import {ngServe} from '../../utils/project';
+import { ng, killAllProcesses } from '../../utils/process';
+import { expectToFail, isUniversalTest } from '../../utils/utils';
+import { ngServe, ngUniversalServe } from '../../utils/project';
function _runServeAndE2e(...args: string[]) {
@@ -12,10 +12,24 @@ function _runServeAndE2e(...args: string[]) {
});
}
-export default function() {
+function _runUniversalServeAndE2e(...args: string[]) {
+ return ngUniversalServe(...args)
+ .then(() => ng('e2e'))
+ .then(() => killAllProcesses(), (err: any) => {
+ killAllProcesses();
+ throw err;
+ });
+}
+
+export default function () {
+ /** AOT test disabled for universal */
+ if (isUniversalTest()) {
+ return expectToFail(() => ng('e2e'))
+ .then(() => _runUniversalServeAndE2e('--prod'));
+ }
// This is supposed to fail without serving first...
return expectToFail(() => ng('e2e'))
- // These should work.
+ // These should work.
.then(() => _runServeAndE2e())
.then(() => _runServeAndE2e('--prod'))
.then(() => _runServeAndE2e('--aot'))
diff --git a/tests/e2e/tests/third-party/bootstrap.ts b/tests/e2e/tests/third-party/bootstrap.ts
index 23f922440970..85de0a1610d2 100644
--- a/tests/e2e/tests/third-party/bootstrap.ts
+++ b/tests/e2e/tests/third-party/bootstrap.ts
@@ -1,10 +1,11 @@
-import {npm, ng} from '../../utils/process';
-import {updateJsonFile} from '../../utils/project';
-import {expectFileToMatch} from '../../utils/fs';
-import {oneLineTrim} from 'common-tags';
+import { npm, ng } from '../../utils/process';
+import { updateJsonFile } from '../../utils/project';
+import { expectFileToMatch } from '../../utils/fs';
+import { oneLineTrim } from 'common-tags';
+import { getAppMain, getClientDist } from '../../utils/utils';
-export default function() {
+export default function () {
return Promise.resolve()
.then(() => npm('install', 'bootstrap@next'))
.then(() => updateJsonFile('angular-cli.json', configJson => {
@@ -17,14 +18,14 @@ export default function() {
);
}))
.then(() => ng('build'))
- .then(() => expectFileToMatch('dist/scripts.bundle.js', '* jQuery JavaScript'))
- .then(() => expectFileToMatch('dist/scripts.bundle.js', '/*! tether '))
- .then(() => expectFileToMatch('dist/scripts.bundle.js', '* Bootstrap'))
- .then(() => expectFileToMatch('dist/styles.bundle.css', '* Bootstrap'))
- .then(() => expectFileToMatch('dist/index.html', oneLineTrim`
+ .then(() => expectFileToMatch(`${getClientDist()}scripts.bundle.js`, '* jQuery JavaScript'))
+ .then(() => expectFileToMatch(`${getClientDist()}scripts.bundle.js`, '/*! tether '))
+ .then(() => expectFileToMatch(`${getClientDist()}scripts.bundle.js`, '* Bootstrap'))
+ .then(() => expectFileToMatch(`${getClientDist()}styles.bundle.css`, '* Bootstrap'))
+ .then(() => expectFileToMatch(`${getClientDist()}index.html`, oneLineTrim`
-
+
`));
}
diff --git a/tests/e2e/utils/fs.ts b/tests/e2e/utils/fs.ts
index 9e0f05b02e87..acd7294332d6 100644
--- a/tests/e2e/utils/fs.ts
+++ b/tests/e2e/utils/fs.ts
@@ -138,6 +138,21 @@ export function expectFileToMatch(fileName: string, regEx: RegExp | string) {
});
}
+export function expectFileToNotMatch(fileName: string, regEx: RegExp | string) {
+ return readFile(fileName)
+ .then(content => {
+ if (typeof regEx == 'string') {
+ if (content.indexOf(regEx) > -1) {
+ throw new Error(`File "${fileName}" did contain "${regEx}"...`);
+ }
+ } else {
+ if (content.match(regEx)) {
+ throw new Error(`File "${fileName}" did match regex ${regEx}...`);
+ }
+ }
+ });
+}
+
export function expectFileSizeToBeUnder(fileName: string, sizeInBytes: number) {
return readFile(fileName)
.then(content => {
diff --git a/tests/e2e/utils/process.ts b/tests/e2e/utils/process.ts
index ab643865dc4d..2fb22f6923d5 100644
--- a/tests/e2e/utils/process.ts
+++ b/tests/e2e/utils/process.ts
@@ -1,5 +1,5 @@
import * as child_process from 'child_process';
-import {blue, white, yellow} from 'chalk';
+import { blue, white, yellow } from 'chalk';
const treeKill = require('tree-kill');
@@ -74,6 +74,10 @@ function _exec(options: ExecOptions, cmd: string, args: string[]): Promise {
+ reject({message: 'timed out after 60 seconds.'});
+ }, 60000);
+
childProcess.stdout.on('data', (data: Buffer) => {
if (data.toString().match(options.waitForMatch)) {
resolve(stdout);
@@ -104,12 +108,12 @@ export function ng(...args: string[]) {
if (args[0] == 'build' || args[0] == 'serve' || args[0] == 'test') {
return silentNg(...args, '--no-progress');
} else {
- return _exec({}, 'ng', args);
+ return _exec({}, 'ung', args);
}
}
export function silentNg(...args: string[]) {
- return _exec({silent: true}, 'ng', args);
+ return _exec({silent: true}, 'ung', args);
}
export function silentNpm(...args: string[]) {
diff --git a/tests/e2e/utils/project.ts b/tests/e2e/utils/project.ts
index 5adb061ba38c..acdfdcfc2120 100644
--- a/tests/e2e/utils/project.ts
+++ b/tests/e2e/utils/project.ts
@@ -4,10 +4,8 @@ import {getGlobalVariable} from './env';
const packages = require('../../../lib/packages');
-
const tsConfigPath = 'src/tsconfig.json';
-
export function updateJsonFile(filePath: string, fn: (json: any) => any | void) {
return readFile(filePath)
.then(tsConfigJson => {
@@ -18,15 +16,13 @@ export function updateJsonFile(filePath: string, fn: (json: any) => any | void)
});
}
-
export function updateTsConfig(fn: (json: any) => any | void) {
return updateJsonFile(tsConfigPath, fn);
}
-
export function ngServe(...args: string[]) {
- return silentExecAndWaitForOutputToMatch('ng',
- ['serve', '--no-progress', ...args], /webpack: bundle is now VALID/);
+ return silentExecAndWaitForOutputToMatch('ung',
+ ['serve', '--no-progress', ...args], /(VALID|successfully)/);
}
@@ -67,3 +63,8 @@ export function createProject(name: string, ...args: string[]) {
.then(() => console.log(`Project ${name} created... Installing npm.`))
.then(() => silentNpm('install'));
}
+
+export function ngUniversalServe(...args: string[]) {
+ return silentExecAndWaitForOutputToMatch('ung',
+ ['serve', ...args], /Listening on port 4200/);
+}
diff --git a/tests/e2e/utils/utils.ts b/tests/e2e/utils/utils.ts
index f1c92420181b..1ae4fc15bb45 100644
--- a/tests/e2e/utils/utils.ts
+++ b/tests/e2e/utils/utils.ts
@@ -10,6 +10,24 @@ export function isMobileTest() {
return !!process.env['MOBILE_TEST'];
}
+export function isUniversalTest() {
+ return !!process.env['UNIVERSAL'];
+}
+
+export function getAppMain() {
+ return isUniversalTest() ? 'client' : 'main';
+}
+
+export function getClientDist() {
+ return isUniversalTest() ? 'dist/client/' : 'dist/';
+}
+
+export function getMainAppModuleRegex() {
+ return isUniversalTest() ?
+ /bootstrapModuleFactory.*\/\* BrowserAppModuleNgFactory \*\// :
+ /bootstrapModuleFactory.*\/\* AppModuleNgFactory \*\//;
+}
+
export function wait(msecs: number) {
return new Promise((resolve) => {
setTimeout(resolve, msecs);
diff --git a/tests/e2e_runner.js b/tests/e2e_runner.js
index 5b869dd03517..804e95c0d5b4 100644
--- a/tests/e2e_runner.js
+++ b/tests/e2e_runner.js
@@ -25,7 +25,7 @@ const setGlobalVariable = require('./e2e/utils/env').setGlobalVariable;
* Here's a short description of those flags:
* --debug If a test fails, block the thread so the temporary directory isn't deleted.
* --noproject Skip creating a project or using one.
- * --nolink Skip linking your local angular-cli directory. Can save a few seconds.
+ * --nolink Skip linking your local universal-cli directory. Can save a few seconds.
* --ng-sha=SHA Use a specific ng-sha. Similar to nightly but point to a master SHA instead
* of using the latest.
* --nightly Install angular nightly builds over the test project.
diff --git a/tests/helpers/mock-ui.js b/tests/helpers/mock-ui.js
index 07f322998037..6838f5b890ad 100644
--- a/tests/helpers/mock-ui.js
+++ b/tests/helpers/mock-ui.js
@@ -1,8 +1,8 @@
'use strict';
-var UI = require('angular-cli/ember-cli/lib/ui');
+var UI = require('universal-cli/ember-cli/lib/ui');
var through = require('through');
-var Promise = require('angular-cli/ember-cli/lib/ext/promise');
+var Promise = require('universal-cli/ember-cli/lib/ext/promise');
module.exports = MockUI;
function MockUI() {
diff --git a/tests/helpers/ng.js b/tests/helpers/ng.js
index 2e67ce2a9159..ef5e4278801e 100644
--- a/tests/helpers/ng.js
+++ b/tests/helpers/ng.js
@@ -2,7 +2,7 @@
var MockUI = require('./mock-ui');
var MockAnalytics = require('./mock-analytics');
-var Cli = require('angular-cli/lib/cli');
+var Cli = require('universal-cli/lib/cli');
module.exports = function ng(args) {
var cli;
diff --git a/tests/helpers/tmp.js b/tests/helpers/tmp.js
index 733e7a3a8ef4..13aee38c5b67 100644
--- a/tests/helpers/tmp.js
+++ b/tests/helpers/tmp.js
@@ -2,7 +2,7 @@
var fs = require('fs-extra');
var existsSync = require('exists-sync');
-var Promise = require('angular-cli/ember-cli/lib/ext/promise');
+var Promise = require('universal-cli/ember-cli/lib/ext/promise');
var remove = Promise.denodeify(fs.remove);
var root = process.cwd();
diff --git a/tests/models/config.spec.ts b/tests/models/config.spec.ts
index ece9ee4f5969..1d738af87ee9 100644
--- a/tests/models/config.spec.ts
+++ b/tests/models/config.spec.ts
@@ -1,4 +1,4 @@
-import {CliConfig} from 'angular-cli/models/config/config';
+import {CliConfig} from 'universal-cli/models/config/config';
import * as fs from 'fs';
import * as path from 'path';
import {CliConfig as ConfigInterface} from './spec-schema';
diff --git a/tests/models/find-lazy-modules.spec.ts b/tests/models/find-lazy-modules.spec.ts
new file mode 100644
index 000000000000..eb3e606de3d4
--- /dev/null
+++ b/tests/models/find-lazy-modules.spec.ts
@@ -0,0 +1,60 @@
+const mockFs = require('mock-fs');
+const expect = require('chai').expect;
+import * as path from 'path';
+import {findLoadChildren, findLazyModules} from 'universal-cli/models/find-lazy-modules';
+
+describe('find-lazy-modules', () => {
+ beforeEach(() => {
+ let mockDrive = {
+ 'node_modules/feature-module': {
+ 'package.json': '{ "main": "index.js" }',
+ 'index.js': ''
+ },
+ 'src/app': {
+ 'app.module.ts': `RouterModule.forRoot([
+ { path: 'relative', loadChildren: './feature-a/feature-a.module' },
+ { path: 'absolute', loadChildren: 'src/app/feature-b/feature-b.module' },
+ { path: 'module', loadChildren: 'feature-module' },
+ { path: 'module2', loadChildren: 'feature-module/index.js' },
+ { path: 'invalid', loadChildren: 'invalid' }
+ ]);`,
+ 'feature-a': {
+ 'feature-a.module.ts': ''
+ },
+ 'feature-b': {
+ 'feature-b.module.ts': ''
+ }
+ }
+ };
+ mockFs(mockDrive);
+ });
+ afterEach(() => {
+ mockFs.restore();
+ });
+
+ it('should find children', () => {
+ let children = findLoadChildren('src/app/app.module.ts');
+ expect(children.length).to.equal(5);
+ expect(children.sort()).to.deep.equal([
+ './feature-a/feature-a.module',
+ 'feature-module',
+ 'feature-module/index.js',
+ 'invalid',
+ 'src/app/feature-b/feature-b.module'
+ ]);
+ });
+
+ it('should find lazy modules', () => {
+ let modules = findLazyModules('.');
+ expect(modules).to.deep.equal({
+ './feature-a/feature-a.module':
+ path.join(__dirname, '../../src/app/feature-a/feature-a.module.ts'),
+ 'src/app/feature-b/feature-b.module':
+ path.join(__dirname, '../../src/app/feature-b/feature-b.module.ts'),
+ 'feature-module':
+ path.join(__dirname, '../../node_modules/feature-module/index.js'),
+ 'feature-module/index.js':
+ path.join(__dirname, '../../node_modules/feature-module/index.js')
+ });
+ });
+});
diff --git a/tsconfig.json b/tsconfig.json
index 1055b93bdb0f..8c45a865e1ee 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,6 +6,8 @@
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
+ "noUnusedParameters": true,
+ "noUnusedLocals": true,
"outDir": "./dist",
"rootDir": ".",
"sourceMap": true,
@@ -22,14 +24,14 @@
"node"
],
"paths": {
- "angular-cli/*": [ "./packages/angular-cli/*" ],
+ "universal-cli/*": [ "./packages/universal-cli/*" ],
"@angular-cli/ast-tools": [ "./packages/ast-tools/src" ],
"@angular-cli/base-href-webpack": [ "./packages/base-href-webpack/src" ],
"@ngtools/webpack": [ "./packages/webpack/src" ]
}
},
"exclude": [
- "packages/angular-cli/blueprints/*/files/**/*",
+ "packages/universal-cli/blueprints/*/files/**/*",
"dist/**/*",
"node_modules/**/*",
"tmp/**/*"
diff --git a/tslint.json b/tslint.json
index 6cb5eba50936..76d10b577016 100644
--- a/tslint.json
+++ b/tslint.json
@@ -19,7 +19,6 @@
"no-trailing-whitespace": true,
"no-bitwise": true,
"no-unused-expression": true,
- "no-unused-variable": true,
"no-var-keyword": true,
"one-line": [
true,