diff --git a/.appveyor.yml b/.appveyor.yml
index eb3e089fd20b..20d541241449 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -7,13 +7,16 @@ matrix:
install:
- ps: Install-Product node $env:nodejs_version
- - npm install -g npm@~5.3.0
+ - npm install -g npm@~5.6.0
- npm install
+ - choco install googlechrome
test_script:
- node --version
- npm --version
- - node tests\run_e2e.js --appveyor
+ - npm run test:packages
+ - npm run test:cli
+ - node tests\run_e2e.js --appveyor "--glob=tests/{basic,commands,generate,build/styles}/**"
build: off
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 85d7be1c8ca1..c460fbb14fec 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -4,7 +4,7 @@ version: 2
anchor_1: &defaults
working_directory: ~/angular-cli
docker:
- - image: angular/ngcontainer
+ - image: angular/ngcontainer:0.0.5
# Restore cache based on package-lock.json checksum for branch.
anchor_2: &restore_cache_defaults
@@ -25,7 +25,7 @@ jobs:
<<: *restore_cache_defaults
- run: node --version
- run: npm --version
- - run: npm install --quiet
+ - run: npm install --no-save
- run: npm run build
- save_cache:
key: angular-cli-{{ checksum "package-lock.json" }}
@@ -48,7 +48,7 @@ jobs:
<<: *restore_cache_defaults
- run: npm run test
-# E2E test for current Angular.
+ # E2E test for current Angular.
e2e-setup:
<<: *defaults
steps:
@@ -110,67 +110,30 @@ jobs:
- run: cp -r /workspace/dist/ ./
- run: xvfb-run -a node tests/run_e2e.js --nobuild --reuse=/workspace/angular-cli-e2e-default/test-project --nb-shards=4 --shard=3 --nosilent
-# E2E test for Angular nightly.
- e2e-setup-nightly:
+ # Master only E2E.
+ ng2-e2e:
<<: *defaults
steps:
- checkout
- restore_cache:
<<: *restore_cache_defaults
- - run: mkdir /workspace
- - run: mkdir /workspace/angular-cli-e2e-nightly
- # Ignore all tests, we just want the setup step to persist it to the workspace.
- - run: node tests/run_e2e.js --tmpdir=/workspace/angular-cli-e2e-nightly --ignore=**/* --nightly
- - run: mv dist /workspace/
- - persist_to_workspace:
- root: /workspace
- paths:
- - dist/
- - angular-cli-e2e-nightly/
-
- e2e-0-nightly:
- <<: *defaults
- steps:
- - checkout
- - restore_cache:
- <<: *restore_cache_defaults
- - attach_workspace:
- <<: *attach_workspace_defaults
- - run: cp -r /workspace/dist/ ./
- - run: xvfb-run -a node tests/run_e2e.js --nobuild --reuse=/workspace/angular-cli-e2e-nightly/test-project --nb-shards=4 --shard=0 --nosilent --nightly
+ - run: xvfb-run -a node tests/run_e2e.js --ng2 "--glob=tests/build/**"
- e2e-1-nightly:
+ ng4-e2e:
<<: *defaults
steps:
- checkout
- restore_cache:
<<: *restore_cache_defaults
- - attach_workspace:
- <<: *attach_workspace_defaults
- - run: cp -r /workspace/dist/ ./
- - run: xvfb-run -a node tests/run_e2e.js --nobuild --reuse=/workspace/angular-cli-e2e-nightly/test-project --nb-shards=4 --shard=1 --nosilent --nightly
+ - run: xvfb-run -a node tests/run_e2e.js --ng4 "--glob=tests/build/**"
- e2e-2-nightly:
+ nightly-e2e:
<<: *defaults
steps:
- checkout
- restore_cache:
<<: *restore_cache_defaults
- - attach_workspace:
- <<: *attach_workspace_defaults
- - run: cp -r /workspace/dist/ ./
- - run: xvfb-run -a node tests/run_e2e.js --nobuild --reuse=/workspace/angular-cli-e2e-nightly/test-project --nb-shards=4 --shard=2 --nosilent --nightly
-
- e2e-3-nightly:
- <<: *defaults
- steps:
- - checkout
- - restore_cache:
- <<: *restore_cache_defaults
- - attach_workspace:
- <<: *attach_workspace_defaults
- - run: cp -r /workspace/dist/ ./
- - run: xvfb-run -a node tests/run_e2e.js --nobuild --reuse=/workspace/angular-cli-e2e-nightly/test-project --nb-shards=4 --shard=3 --nosilent --nightly
+ - run: xvfb-run -a node tests/run_e2e.js --nightly "--glob=tests/build/**"
workflows:
version: 2
@@ -199,23 +162,25 @@ workflows:
- e2e-3:
requires:
- e2e-setup
- # E2E test for Angular nightly.
- - e2e-setup-nightly:
+ # Master only E2E.
+ - ng2-e2e:
requires:
- build
filters:
branches:
only:
- master
- - e2e-0-nightly:
- requires:
- - e2e-setup-nightly
- - e2e-1-nightly:
- requires:
- - e2e-setup-nightly
- - e2e-2-nightly:
+ - ng4-e2e:
requires:
- - e2e-setup-nightly
- - e2e-3-nightly:
+ - build
+ filters:
+ branches:
+ only:
+ - master
+ - nightly-e2e:
requires:
- - e2e-setup-nightly
+ - build
+ filters:
+ branches:
+ only:
+ - master
diff --git a/.travis.yml b/.travis.yml
index 9b50b6185d4c..2d1b4286561a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,13 @@ cache:
directories:
- ./node_modules
+stages:
+ - build
+ - test
+ - name: optional
+ if: (NOT type IN (pull_request)) AND (branch = master)
+ - deploy
+
matrix:
fast_finish: true
allow_failures:
@@ -18,12 +25,14 @@ matrix:
- node_js: "7"
- node_js: "8"
include:
+ # Build stage
- stage: build
script: npm run lint
env: lint
- script: npm run build
env: build
+ # Test stage
- stage: test
script: npm run test
env: test
@@ -43,46 +52,35 @@ matrix:
os: linux
script: node tests/run_e2e.js --nb-shards=4 --shard=3 --nosilent
env: e2e-3
-
- - node_js: "6"
- os: linux
- script: node tests/run_e2e.js --nb-shards=4 --shard=0 --nosilent --nightly
- env: nightly-0
- - node_js: "6"
- os: linux
- script: node tests/run_e2e.js --nb-shards=4 --shard=1 --nosilent --nightly
- env: nightly-1
- - node_js: "6"
- os: linux
- script: node tests/run_e2e.js --nb-shards=4 --shard=2 --nosilent --nightly
- env: nightly-2
- - node_js: "6"
- os: linux
- script: node tests/run_e2e.js --nb-shards=4 --shard=3 --nosilent --nightly
- env: nightly-3
-
- node_js: "6"
os: linux
script: node tests/run_e2e.js --eject "--glob=tests/build/**"
env: eject
- # Optional builds.
- - node_js: "6"
+ # Optional stage.
+ - stage: optional
+ node_js: "6"
os: linux
- before_script: if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit 0; fi
- script: node tests/run_e2e.js --ng2 "--glob=tests/{build,test,misc}/**"
+ script: node tests/run_e2e.js --ng2 "--glob=tests/build/**"
env: ng2
+ - node_js: "6"
+ os: linux
+ script: node tests/run_e2e.js --ng4 "--glob=tests/build/**"
+ env: ng4
+ - node_js: "6"
+ os: linux
+ script: node tests/run_e2e.js --nightly "--glob=tests/build/**"
+ env: nightly
- node_js: "7"
os: linux
- before_script: if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit 0; fi
- script: node tests/run_e2e.js "--glob=tests/{build,test,misc}/**"
+ script: node tests/run_e2e.js "--glob=tests/build/**"
env: node7
- node_js: "8"
os: linux
- before_script: if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit 0; fi
script: node tests/run_e2e.js "--glob=tests/build/**"
env: node8
+ # Deploy stage
- stage: deploy
script: skip
env: builds
@@ -92,8 +90,7 @@ matrix:
skip_cleanup: true
on:
all_branches: true
- - stage: deploy
- script: skip
+ - script: skip
env: publish
deploy:
- provider: script
diff --git a/docs/documentation/build.md b/docs/documentation/build.md
index 2aa151aff024..19fe3371f891 100644
--- a/docs/documentation/build.md
+++ b/docs/documentation/build.md
@@ -83,13 +83,20 @@ Flag | `--dev` | `--prod`
`--named-chunks` | `true` | `false`
`--build-optimizer` | `false` | `true` with AOT and Angular 5
-`--extract-licenses` Extract all licenses in a separate file, in the case of production builds only.
-`--i18n-file` Localization file to use for i18n.
`--prod` also sets the following non-flaggable settings:
- Adds service worker if configured in `.angular-cli.json`.
- Replaces `process.env.NODE_ENV` in modules with the `production` value (this is needed for some libraries, like react).
- Runs UglifyJS on the code.
+### `--build-optimizer` and `--vendor-chunk`
+
+When using Build Optimizer the vendor chunk will be disabled by default.
+You can override this with `--vendor-chunk=true`.
+
+Total bundle sizes with Build Optimizer are smaller if there is no separate vendor chunk because
+having vendor code in the same chunk as app code makes it possible for Uglify to remove more unused
+code.
+
### CSS resources
Resources in CSS, such as images and fonts, will be copied over automatically as part of a build.
@@ -111,6 +118,16 @@ Remember to disable the service worker while developing to avoid stale code.
Note: service worker support is experimental and subject to change.
+### ES2015 support
+
+To build in ES2015 mode, edit `./tsconfig.json` to use `"target": "es2015"` (instead of `es5`).
+
+This will cause application TypeScript and Uglify be output as ES2015, and third party libraries
+to be loaded through the `es2015` entry in `package.json` if available.
+
+Be aware that JIT does not support ES2015 and so you should build/serve your app with `--aot`.
+See https://github.com/angular/angular-cli/issues/7797 for details.
+
## Options
aot
@@ -377,3 +394,14 @@ Note: service worker support is experimental and subject to change.
In a server build, state whether `all` or `none` dependencies should be bundles in the output.
+
+
+
+ extract-licenses
+
+ --extract-licenses default value: true
+
+
+ Extract all licenses in a separate file, in the case of production builds only.
+
+
diff --git a/docs/documentation/e2e.md b/docs/documentation/e2e.md
index c78606d3ae8c..ebfaf64e8d96 100644
--- a/docs/documentation/e2e.md
+++ b/docs/documentation/e2e.md
@@ -23,7 +23,7 @@ Please note that options that are supported by `ng serve` are also supported by
--config (aliases: -c)
- Use a specific config file. Defaults to the protractor config file in `.angular-cli.json`.
+ Use a specific config file. Defaults to the protractor config file in .angular-cli.json.
@@ -33,7 +33,7 @@ Please note that options that are supported by `ng serve` are also supported by
--element-explorer (aliases: -ee) default value: false
- Start Protractor's [Element Explorer](https://github.com/angular/protractor/blob/master/docs/debugging.md#testing-out-protractor-interactively) for debugging.
+ Start Protractor's Element Explorer for debugging.
@@ -56,7 +56,17 @@ Please note that options that are supported by `ng serve` are also supported by
--specs (aliases: -sp) default value: []
- Override specs in the protractor config. Can send in multiple specs by repeating flag (ng e2e --specs=spec1.ts --specs=spec2.ts).
+ Override specs in the protractor config. Can send in multiple specs by repeating flag (ng e2e --specs=spec1.ts --specs=spec2.ts).
+
+
+
+
+ suite
+
+ --suite (aliases: -su)
+
+
+ Override suite in the protractor config. Can send in multiple suite by comma separated values (ng e2e --suite=suiteA,suiteB).
diff --git a/docs/documentation/stories.md b/docs/documentation/stories.md
index babf2802e116..7b5d3f6703d0 100644
--- a/docs/documentation/stories.md
+++ b/docs/documentation/stories.md
@@ -14,6 +14,7 @@
- [Angular Material](stories/include-angular-material)
- [AngularFire](stories/include-angularfire)
- [Bootstrap](stories/include-bootstrap)
+ - [Budgets](stories/budgets)
- [Font Awesome](stories/include-font-awesome)
- [Moving Into the CLI](stories/moving-into-the-cli)
- [Moving Out of the CLI](stories/moving-out-of-the-cli)
diff --git a/docs/documentation/stories/budgets.md b/docs/documentation/stories/budgets.md
new file mode 100644
index 000000000000..33c863465078
--- /dev/null
+++ b/docs/documentation/stories/budgets.md
@@ -0,0 +1,61 @@
+# Budgets
+
+As applications grow in functionality, they also grow in size. Budgets is a feature in the
+Angular CLI which allows you to set budget thresholds in your configuration to ensure parts
+of your application stay within boundries which you set.
+
+**.angular-cli.json**
+```
+{
+ ...
+ apps: [
+ {
+ ...
+ budgets: []
+ }
+ ]
+}
+```
+
+## Budget Definition
+
+- type
+ - The type of budget.
+ - Possible values:
+ - bundle - The size of a specific bundle.
+ - initial - The initial size of the app.
+ - allScript - The size of all scripts.
+ - all - The size of the entire app.
+ - anyScript - The size of any one script.
+ - any - The size of any file.
+- name
+ - The name of the bundle.
+ - Required only for type of "bundle"
+- baseline
+ - The baseline size for comparison.
+- maximumWarning
+ - The maximum threshold for warning relative to the baseline.
+- maximumError
+ - The maximum threshold for error relative to the baseline.
+- minimumWarning
+ - The minimum threshold for warning relative to the baseline.
+- minimumError
+ - The minimum threshold for error relative to the baseline.
+- warning
+ - The threshold for warning relative to the baseline (min & max).
+- error
+ - The threshold for error relative to the baseline (min & max).
+
+## Specifying sizes
+
+Available formats:
+123 - size in bytes
+123b - size in bytes
+123kb - size in kilobytes
+123mb - size in megabytes
+12% - percentage
+
+## NOTES
+
+All sizes are relative to baseline.
+Percentages are not valid for baseline values.
diff --git a/docs/documentation/stories/configure-hmr.md b/docs/documentation/stories/configure-hmr.md
index 85d21d6dfb77..daa0c3ca56e6 100644
--- a/docs/documentation/stories/configure-hmr.md
+++ b/docs/documentation/stories/configure-hmr.md
@@ -3,7 +3,7 @@
Hot Module Replacement (HMR) is a WebPack feature to update code in a running app without rebuilding it.
This results in faster updates and less full page-reloads.
-You can read more about HMR by visiting [this page](https://webpack.github.io/docs/hot-module-replacement.html).
+You can read more about HMR by visiting [this page](https://webpack.js.org/guides/hot-module-replacement).
In order to get HMR working with Angular CLI we first need to add a new environment and enable it.
diff --git a/docs/documentation/stories/continuous-integration.md b/docs/documentation/stories/continuous-integration.md
index 1745f8cf4240..ba24aba1a07c 100644
--- a/docs/documentation/stories/continuous-integration.md
+++ b/docs/documentation/stories/continuous-integration.md
@@ -119,6 +119,13 @@ sudo: false
language: node_js
node_js:
- "6"
+
+addons:
+ apt:
+ sources:
+ - google-chrome
+ packages:
+ - google-chrome-stable
cache:
directories:
diff --git a/docs/documentation/stories/css-preprocessors.md b/docs/documentation/stories/css-preprocessors.md
index b897b0893af0..58bd0071deab 100644
--- a/docs/documentation/stories/css-preprocessors.md
+++ b/docs/documentation/stories/css-preprocessors.md
@@ -30,3 +30,5 @@ Or set the default style on an existing project:
```bash
ng set defaults.styleExt scss
```
+
+Style strings added to the `@Component.styles` array _must be written in CSS_ because the CLI cannot apply a pre-processor to inline styles.
\ No newline at end of file
diff --git a/docs/documentation/stories/include-bootstrap.md b/docs/documentation/stories/include-bootstrap.md
index 3debf5d279f1..b5d244342113 100644
--- a/docs/documentation/stories/include-bootstrap.md
+++ b/docs/documentation/stories/include-bootstrap.md
@@ -117,7 +117,11 @@ Verify the bootstrap styled button appears.
To ensure your variables are used open `_variables.scss` and add the following:
```sass
+// version 3
$brand-primary: red;
+
+// version 4
+$primary: red;
```
Return the browser to see the font color changed.
diff --git a/docs/documentation/stories/proxy.md b/docs/documentation/stories/proxy.md
index 3298b5f97c79..12e35c9bda14 100644
--- a/docs/documentation/stories/proxy.md
+++ b/docs/documentation/stories/proxy.md
@@ -1,6 +1,6 @@
# Proxy To Backend
-Using the [proxying support](https://webpack.github.io/docs/webpack-dev-server.html#proxy) in webpack's dev server we can highjack certain URLs and send them to a backend server.
+Using the [proxying support](https://webpack.js.org/configuration/dev-server/#devserver-proxy) in webpack's dev server we can highjack certain URLs and send them to a backend server.
We do this by passing a file to `--proxy-config`
Say we have a server running on `http://localhost:3000/api` and we want all calls to `http://localhost:4200/api` to go to that server.
@@ -16,7 +16,7 @@ We create a file next to our project's `package.json` called `proxy.conf.json` w
}
```
-You can read more about what options are available [here](https://webpack.github.io/docs/webpack-dev-server.html#proxy).
+You can read more about what options are available [here](https://webpack.js.org/configuration/dev-server/#devserver-proxy).
We can then edit the `package.json` file's start script to be
@@ -26,6 +26,8 @@ We can then edit the `package.json` file's start script to be
Now in order to run our dev server with our proxy config, we can simply call `npm start`.
+**After each edit to the proxy.conf.json file remember to relaunch the `npm start` process to make your changes effective.**
+
### Rewriting the URL path
One option that comes up a lot is rewriting the URL path for the proxy. This is supported by the `pathRewrite` option.
diff --git a/package-lock.json b/package-lock.json
index 28e68ef39edb..a5c1e1c01d45 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,37 +1,58 @@
{
"name": "@angular/cli",
- "version": "1.6.0-beta.2",
+ "version": "1.7.0-beta.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@angular-devkit/build-optimizer": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.0.28.tgz",
- "integrity": "sha512-rG5sGV5a2F3R5E+8WRnvq/UPDY2uN5iQjMBDsId1oILjBSAUSwOZM10zQ3De+sd89CmT/R6aSkr6YtbkYn8G0Q==",
+ "version": "0.0.41",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.0.41.tgz",
+ "integrity": "sha512-TYolYpR3cb3rZGMqHBc1Q4r6SwhvuTF9sDt3gARy9Tli5R3BwY8bRA3evHQhhM0cb4AbBaJVgQYdJm5FURNn6g==",
"requires": {
"loader-utils": "1.1.0",
"source-map": "0.5.7",
- "typescript": "2.4.2",
+ "typescript": "2.6.2",
"webpack-sources": "1.0.1"
+ },
+ "dependencies": {
+ "typescript": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
+ "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q="
+ }
}
},
"@angular-devkit/core": {
- "version": "0.0.20",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.0.20.tgz",
- "integrity": "sha512-lg5BvMxOfbVD//SOQvpq6TPIKTXYNMj0I9N/kfXbXkUGgiBGFLyFMf2fc+qNvDoa7lulKMPT8OJWS1YlGt93eg==",
+ "version": "0.0.28",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.0.28.tgz",
+ "integrity": "sha512-rfGRVdpx080zZq9NGZ3RNG+cmoq/ZPaCzpM4dAbosEM46ficUkwr/JKjhjZUUoSyb9ItrT1lp9C33GfE/YpSVQ==",
"requires": {
+ "ajv": "5.5.2",
+ "chokidar": "1.7.0",
+ "rxjs": "5.5.6",
"source-map": "0.5.7"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ }
}
},
"@angular-devkit/schematics": {
- "version": "0.0.35",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.0.35.tgz",
- "integrity": "sha512-+qGUWhmMpHqHkYKMk1yKQDjXb/vqXGkzbMiRs/u5rSnlrH+/TzkCO0UsM7/p9WPcModuDxkf5FItpw/AgdcPeQ==",
+ "version": "0.0.51",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.0.51.tgz",
+ "integrity": "sha512-KGYiJpPgLqPvXeJzaHw/9JHAt8dL3EzyeYOAZ/gMKnPDA+7WypAta2n9ZuPVchY3G9p1XcqB5STJLvk7HQw3Cw==",
"requires": {
- "@angular-devkit/core": "0.0.20",
"@ngtools/json-schema": "1.1.0",
- "minimist": "1.2.0",
- "rxjs": "5.5.2"
+ "rxjs": "5.5.6"
}
},
"@angular/compiler": {
@@ -79,11 +100,18 @@
"integrity": "sha1-w6DFRNYjkqzCgTpCyKDcb1j4aSI="
},
"@schematics/angular": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.1.0.tgz",
- "integrity": "sha512-+Yy72J55uImsROxwyyEMso+HJIvx7+ffT8o8HzdNOZyLg4jj7G/ZDiCsCmhRtTYOmOof4OqvF2VecJyXVi0oHA==",
+ "version": "0.1.16",
+ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.1.16.tgz",
+ "integrity": "sha512-SLzs5TmDLEO2/oU83uDw/x9jgBQTktNlO202kbawcqDKLekqgcZXnsl7UhoNdeCFOU9BE9dw07wWwuIzAhj9gQ==",
"requires": {
- "@angular-devkit/core": "0.0.20"
+ "typescript": "2.6.2"
+ },
+ "dependencies": {
+ "typescript": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
+ "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q="
+ }
}
},
"@types/common-tags": {
@@ -161,6 +189,16 @@
"integrity": "sha1-WJKKYh0BTOarWcWpxBBx9zKLDKk=",
"dev": true
},
+ "@types/loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@types/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha512-VR4oHG6TzhpemxtBDf0BD8xlOiPo2B6zcFEA2Jjmgf1RqSrHLAiteIksV3YvpVn0Pd4HxV1B3LQ6Mf2pGTyZ7g==",
+ "dev": true,
+ "requires": {
+ "@types/node": "6.0.88",
+ "@types/webpack": "3.0.11"
+ }
+ },
"@types/lodash": {
"version": "4.14.74",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.74.tgz",
@@ -226,6 +264,12 @@
"@types/mime": "2.0.0"
}
},
+ "@types/source-list-map": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
+ "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
+ "dev": true
+ },
"@types/source-map": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.5.1.tgz",
@@ -258,6 +302,17 @@
"@types/uglify-js": "2.6.29"
}
},
+ "@types/webpack-sources": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.3.tgz",
+ "integrity": "sha512-yS052yVjjyIjwcUqIEe2+JxbWsw27OM8UFb1fLUGacGYtqMRwgAx2qk41VTE/nPMjw/xfD0JiHPD0Q99dlrInA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "6.0.88",
+ "@types/source-list-map": "0.1.2",
+ "@types/source-map": "0.5.1"
+ }
+ },
"JSONStream": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
@@ -420,6 +475,11 @@
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
},
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+ },
"array-filter": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
@@ -520,6 +580,11 @@
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
+ },
"async": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
@@ -544,17 +609,84 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
+ "atob": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
+ "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10="
+ },
"autoprefixer": {
- "version": "6.7.7",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
- "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.3.tgz",
+ "integrity": "sha512-dqzVGiz3v934+s3YZA6nk7tAs9xuTz5wMJbX1M+L4cY/MTNkOUqP61c1GWkEVlUL/PEy1pKRSCFuoRZrXYx9qA==",
"requires": {
- "browserslist": "1.7.7",
- "caniuse-db": "1.0.30000733",
+ "browserslist": "2.10.0",
+ "caniuse-lite": "1.0.30000784",
"normalize-range": "0.1.2",
"num2fraction": "1.2.2",
- "postcss": "5.2.17",
+ "postcss": "6.0.14",
"postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "browserslist": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz",
+ "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==",
+ "requires": {
+ "caniuse-lite": "1.0.30000784",
+ "electron-to-chromium": "1.3.28"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "electron-to-chromium": {
+ "version": "1.3.28",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz",
+ "integrity": "sha1-jdTmRYCGZE6fnwoc8y4qH53/2e4="
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ },
+ "postcss": {
+ "version": "6.0.14",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
+ "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
+ "requires": {
+ "chalk": "2.3.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.5.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
}
},
"aws-sign2": {
@@ -684,6 +816,20 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "requires": {
+ "cache-base": "1.0.1",
+ "class-utils": "0.3.6",
+ "component-emitter": "1.2.1",
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "mixin-deep": "1.3.0",
+ "pascalcase": "0.1.1"
+ }
+ },
"base64-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
@@ -732,6 +878,38 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.7.tgz",
"integrity": "sha512-LxFiV5mefv0ley0SzqkOPR1bC4EbpPx8LkOz5vMe/Yi15t5hzwgO/G+tc7wOtL4PZTYjwHu8JnEiSLumuSjSfA=="
},
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.1",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "1.6.15"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
"bonjour": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
@@ -890,9 +1068,9 @@
"integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo="
},
"cacache": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.0.tgz",
- "integrity": "sha512-s9h6I9NY3KcBjfuS28K6XNmrv/HNFSzlpVD6eYMXugZg3Y8jjI1lUzTeUMa0oKByCDtHfsIy5Ec7KgWRnC5gtg==",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.1.tgz",
+ "integrity": "sha512-dRHYcs9LvG9cHgdPzjiI+/eS7e1xRhULrcyOx04RZQsszNJXU2SL9CyG60yLnge282Qq5nwTv+ieK2fH+WPZmA==",
"requires": {
"bluebird": "3.5.1",
"chownr": "1.0.1",
@@ -909,6 +1087,22 @@
"y18n": "3.2.1"
}
},
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "requires": {
+ "collection-visit": "1.0.0",
+ "component-emitter": "1.2.1",
+ "get-value": "2.0.6",
+ "has-value": "1.0.0",
+ "isobject": "3.0.1",
+ "set-value": "2.0.0",
+ "to-object-path": "0.3.0",
+ "union-value": "1.0.0",
+ "unset-value": "1.0.0"
+ }
+ },
"caller-path": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
@@ -963,6 +1157,11 @@
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000733.tgz",
"integrity": "sha1-OmJbxBx6n5nVnWRVKFfdGvDt2dQ="
},
+ "caniuse-lite": {
+ "version": "1.0.30000784",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz",
+ "integrity": "sha1-EpztdOmhKApEGIC2zSvOMO9Z5sA="
+ },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -1017,11 +1216,6 @@
}
}
},
- "charenc": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
- "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
- },
"chokidar": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -1029,7 +1223,7 @@
"requires": {
"anymatch": "1.3.2",
"async-each": "1.0.1",
- "fsevents": "1.1.2",
+ "fsevents": "1.1.3",
"glob-parent": "2.0.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@@ -1068,9 +1262,9 @@
}
},
"circular-dependency-plugin": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-3.0.0.tgz",
- "integrity": "sha1-m2hpLjWw41EJmNAWS2rlARvqV2A="
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-4.2.1.tgz",
+ "integrity": "sha512-Ggm3s8lvFVr2aYqDK6v09D1sJN17n3E7FE3R2khWFHchNop0QLRQvJi4JYsgwX0DNf7gZvXuOQsjTcj2qIVBqg=="
},
"circular-json": {
"version": "0.3.3",
@@ -1105,6 +1299,78 @@
}
}
},
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "requires": {
+ "arr-union": "3.1.0",
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "static-extend": "0.1.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
"clean-css": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz",
@@ -1172,6 +1438,15 @@
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "requires": {
+ "map-visit": "1.0.0",
+ "object-visit": "1.0.1"
+ }
+ },
"color": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
@@ -1254,6 +1529,11 @@
"dot-prop": "3.0.0"
}
},
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+ },
"compressible": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz",
@@ -1597,9 +1877,9 @@
}
},
"convert-source-map": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz",
- "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU="
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU="
},
"cookie": {
"version": "0.3.1",
@@ -1624,6 +1904,11 @@
"run-queue": "1.0.3"
}
},
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
+ },
"copy-webpack-plugin": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.1.1.tgz",
@@ -1740,11 +2025,6 @@
"which": "1.3.0"
}
},
- "crypt": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
- "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
- },
"cryptiles": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
@@ -1879,6 +2159,21 @@
"postcss-unique-selectors": "2.0.2",
"postcss-value-parser": "3.3.0",
"postcss-zindex": "2.2.0"
+ },
+ "dependencies": {
+ "autoprefixer": {
+ "version": "6.7.7",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-db": "1.0.30000733",
+ "normalize-range": "0.1.2",
+ "num2fraction": "1.2.2",
+ "postcss": "5.2.17",
+ "postcss-value-parser": "3.3.0"
+ }
+ }
}
},
"csso": {
@@ -1967,6 +2262,11 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ },
"deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
@@ -1987,6 +2287,14 @@
"object-keys": "1.0.11"
}
},
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
"defined": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
@@ -2305,12 +2613,6 @@
"tapable": "0.2.8"
}
},
- "ensure-posix-path": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.0.2.tgz",
- "integrity": "sha1-pls+QtC3HPxYXrd0+ZQ8jZuRsMI=",
- "dev": true
- },
"entities": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
@@ -2685,6 +2987,7 @@
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz",
"integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=",
+ "dev": true,
"requires": {
"accepts": "1.3.4",
"array-flatten": "1.1.1",
@@ -2719,12 +3022,14 @@
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
},
"qs": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
- "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg=="
+ "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==",
+ "dev": true
}
}
},
@@ -2733,6 +3038,14 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
"extglob": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
@@ -2749,9 +3062,9 @@
}
},
"extract-text-webpack-plugin": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.0.tgz",
- "integrity": "sha1-kMqnkHvESfM1AF46x1MrQbAN5hI=",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz",
+ "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==",
"requires": {
"async": "2.5.0",
"loader-utils": "1.1.0",
@@ -2769,6 +3082,11 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
"integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
},
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
@@ -2848,6 +3166,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.5.tgz",
"integrity": "sha1-pwEwPSV6G8gv6lR6M+WuiVMXI98=",
+ "dev": true,
"requires": {
"debug": "2.6.8",
"encodeurl": "1.0.1",
@@ -2864,7 +3183,7 @@
"integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
"requires": {
"commondir": "1.0.1",
- "make-dir": "1.0.0",
+ "make-dir": "1.1.0",
"pkg-dir": "2.0.0"
}
},
@@ -2978,10 +3297,19 @@
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "requires": {
+ "map-cache": "0.2.2"
+ }
+ },
"fresh": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz",
- "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44="
+ "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=",
+ "dev": true
},
"from": {
"version": "0.1.7",
@@ -3018,6 +3346,15 @@
}
}
},
+ "fs-minipass": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.3.tgz",
+ "integrity": "sha512-u1pHCXDx+CElfM6CuIeHDTKvb1Ya9ZhsMk7xTHTh6zHSRLK6O0DTVBN+E3wg8fruxAFp4oE07owrrzQfDA0b5Q==",
+ "dev": true,
+ "requires": {
+ "minipass": "2.2.1"
+ }
+ },
"fs-write-stream-atomic": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -3035,13 +3372,13 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz",
- "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
+ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
"optional": true,
"requires": {
"nan": "2.7.0",
- "node-pre-gyp": "0.6.36"
+ "node-pre-gyp": "0.6.39"
},
"dependencies": {
"abbrev": {
@@ -3175,7 +3512,6 @@
"cryptiles": {
"version": "2.0.5",
"bundled": true,
- "optional": true,
"requires": {
"boom": "2.10.1"
}
@@ -3217,6 +3553,11 @@
"bundled": true,
"optional": true
},
+ "detect-libc": {
+ "version": "1.0.2",
+ "bundled": true,
+ "optional": true
+ },
"ecc-jsbn": {
"version": "0.1.1",
"bundled": true,
@@ -3341,7 +3682,6 @@
"hawk": {
"version": "3.1.3",
"bundled": true,
- "optional": true,
"requires": {
"boom": "2.10.1",
"cryptiles": "2.0.5",
@@ -3490,10 +3830,12 @@
"optional": true
},
"node-pre-gyp": {
- "version": "0.6.36",
+ "version": "0.6.39",
"bundled": true,
"optional": true,
"requires": {
+ "detect-libc": "1.0.2",
+ "hawk": "3.1.3",
"mkdirp": "0.5.1",
"nopt": "4.0.1",
"npmlog": "4.1.0",
@@ -3677,7 +4019,6 @@
"sntp": {
"version": "1.0.9",
"bundled": true,
- "optional": true,
"requires": {
"hoek": "2.16.3"
}
@@ -3862,14 +4203,12 @@
"generate-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
- "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
- "dev": true
+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ="
},
"generate-object-property": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
- "dev": true,
"requires": {
"is-property": "1.0.2"
}
@@ -3902,6 +4241,11 @@
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+ },
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -4090,32 +4434,79 @@
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
- "hash-base": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
- "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
- "requires": {
- "inherits": "2.0.3"
- }
- },
- "hash.js": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
- "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
"requires": {
- "inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "get-value": "2.0.6",
+ "has-values": "1.0.0",
+ "isobject": "3.0.1"
}
},
- "hawk": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
- "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
"requires": {
- "boom": "4.3.1",
- "cryptiles": "3.1.2",
- "hoek": "4.2.0",
- "sntp": "2.0.2"
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+ "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "requires": {
+ "inherits": "2.0.3",
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "requires": {
+ "boom": "4.3.1",
+ "cryptiles": "3.1.2",
+ "hoek": "4.2.0",
+ "sntp": "2.0.2"
}
},
"he": {
@@ -4303,6 +4694,11 @@
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
"integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI="
},
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
"icss-replace-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
@@ -4363,15 +4759,6 @@
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"optional": true
},
- "import-local": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-0.1.1.tgz",
- "integrity": "sha1-sReVcqrNwRxqkQCftDDbyrX2aKg=",
- "requires": {
- "pkg-dir": "2.0.0",
- "resolve-cwd": "2.0.0"
- }
- },
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -4497,13 +4884,29 @@
"ipaddr.js": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
- "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA="
+ "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=",
+ "dev": true
},
"is-absolute-url": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
"integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY="
},
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -4535,11 +4938,43 @@
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
"integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI="
},
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
},
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ }
+ }
+ },
"is-directory": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
@@ -4596,7 +5031,6 @@
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
- "dev": true,
"requires": {
"generate-function": "2.0.0",
"generate-object-property": "1.2.0",
@@ -4618,6 +5052,24 @@
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
+ "is-odd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz",
+ "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=",
+ "requires": {
+ "is-number": "3.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ }
+ }
+ },
"is-path-cwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
@@ -4665,8 +5117,7 @@
"is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
- "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
- "dev": true
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
},
"is-regex": {
"version": "1.0.4",
@@ -4754,27 +5205,14 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"istanbul-instrumenter-loader": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-2.0.0.tgz",
- "integrity": "sha1-5UkpAKsLuoNe+oAkywC+mz7qJwA=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.0.tgz",
+ "integrity": "sha512-alLSEFX06ApU75sm5oWcaVNaiss/bgMRiWTct3g0P0ZZTKjR+6QiCcuVOKDI1kWJgwHEnIXsv/dWm783kPpmtw==",
"requires": {
- "convert-source-map": "1.5.0",
- "istanbul-lib-instrument": "1.8.0",
- "loader-utils": "0.2.17",
- "object-assign": "4.1.1"
- },
- "dependencies": {
- "loader-utils": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
- "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
- "requires": {
- "big.js": "3.2.0",
- "emojis-list": "2.1.0",
- "json5": "0.5.1",
- "object-assign": "4.1.1"
- }
- }
+ "convert-source-map": "1.5.1",
+ "istanbul-lib-instrument": "1.9.1",
+ "loader-utils": "1.1.0",
+ "schema-utils": "0.3.0"
}
},
"istanbul-lib-coverage": {
@@ -4783,9 +5221,9 @@
"integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q=="
},
"istanbul-lib-instrument": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz",
- "integrity": "sha1-ZvbJQhzJ7EcE928tsIS6kHiitTI=",
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz",
+ "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==",
"requires": {
"babel-generator": "6.26.0",
"babel-template": "6.26.0",
@@ -4823,9 +5261,9 @@
}
},
"js-base64": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
- "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw=="
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz",
+ "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA=="
},
"js-tokens": {
"version": "3.0.2",
@@ -4910,8 +5348,7 @@
"jsonpointer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
- "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
- "dev": true
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
},
"jsprim": {
"version": "1.4.1",
@@ -4932,6 +5369,11 @@
"source-map-support": "0.4.18"
}
},
+ "killable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
+ "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms="
+ },
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@@ -4996,9 +5438,9 @@
}
},
"license-checker": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-14.0.0.tgz",
- "integrity": "sha512-NuPRmB/tICGaRuDwLoGp24oBW0e/dX9jnEYo5lR0hCTkIT1yx+Jm3x3hQ+qkgF+e2UJC59hDSJY1FPkjcxvQ0w==",
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/license-checker/-/license-checker-15.0.0.tgz",
+ "integrity": "sha512-HLI3BcrG1mM5Q156DAZxVlK0pE0s/I/EhSaLqWev23e+G5pBIwYXleAhgsja3qJDKcZVBezb7GJwu5pqfmK/Tg==",
"dev": true,
"requires": {
"chalk": "0.5.1",
@@ -5284,11 +5726,18 @@
}
},
"make-dir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz",
- "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
+ "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
"requires": {
- "pify": "2.3.0"
+ "pify": "3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ }
}
},
"make-error": {
@@ -5297,6 +5746,11 @@
"integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=",
"dev": true
},
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
+ },
"map-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
@@ -5308,13 +5762,12 @@
"integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
"dev": true
},
- "matcher-collection": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz",
- "integrity": "sha512-nUCmzKipcJEwYsBVAFh5P+d7JBuhJaW1xs85Hara9xuMLqtCVUrW6DSC0JVIkluxEH2W45nPBM/wjHtBXa/tYA==",
- "dev": true,
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
"requires": {
- "minimatch": "3.0.4"
+ "object-visit": "1.0.1"
}
},
"math-expression-evaluator": {
@@ -5322,16 +5775,6 @@
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
"integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw="
},
- "md5": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
- "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
- "requires": {
- "charenc": "0.0.2",
- "crypt": "0.0.2",
- "is-buffer": "1.1.5"
- }
- },
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -5523,15 +5966,6 @@
}
}
},
- "minizlib": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.0.3.tgz",
- "integrity": "sha1-1cGr93vhVGGZUuJTM27Mq5sqMvU=",
- "dev": true,
- "requires": {
- "minipass": "2.2.1"
- }
- },
"mississippi": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-1.3.0.tgz",
@@ -5543,12 +5977,31 @@
"flush-write-stream": "1.0.2",
"from2": "2.3.0",
"parallel-transform": "1.1.0",
- "pump": "1.0.2",
+ "pump": "1.0.3",
"pumpify": "1.3.5",
- "stream-each": "1.2.0",
+ "stream-each": "1.2.2",
"through2": "2.0.3"
}
},
+ "mixin-deep": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz",
+ "integrity": "sha512-dgaCvoh6i1nosAUBKb0l0pfJ78K8+S9fluyIR2YvAeUD/QuMahnFnF3xYty5eYXMjhGSsB0DsW6A0uAZyetoAg==",
+ "requires": {
+ "for-in": "1.0.2",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
"mixin-object": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
@@ -5636,6 +6089,41 @@
"integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=",
"optional": true
},
+ "nanomatch": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz",
+ "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==",
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "is-odd": "1.0.0",
+ "kind-of": "5.1.0",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -5768,9 +6256,9 @@
"integrity": "sha1-QAlrCM560OoUaAhjr0ScfHWl0cg="
},
"node-sass": {
- "version": "4.5.3",
- "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.3.tgz",
- "integrity": "sha1-0JydEXlkEjnRuX/8YjH9zsU+FWg=",
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz",
+ "integrity": "sha512-CaV+wLqZ7//Jdom5aUFCpGNoECd7BbNhjuwdsX/LkXBrHl8eb1Wjw4HvWqcFvhr5KuNgAk8i/myf/MQ1YYeroA==",
"optional": true,
"requires": {
"async-foreach": "0.1.3",
@@ -5788,16 +6276,42 @@
"nan": "2.7.0",
"node-gyp": "3.6.2",
"npmlog": "4.1.2",
- "request": "2.82.0",
+ "request": "2.79.0",
"sass-graph": "2.2.4",
- "stdout-stream": "1.4.0"
+ "stdout-stream": "1.4.0",
+ "true-case-path": "1.0.2"
},
"dependencies": {
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "optional": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "optional": true
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "optional": true
+ },
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "optional": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
@@ -5806,23 +6320,131 @@
"supports-color": "2.0.0"
}
},
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "optional": true,
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "optional": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.17"
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "optional": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "commander": "2.11.0",
+ "is-my-json-valid": "2.16.1",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "optional": true,
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "optional": true,
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
"optional": true
- }
- }
- },
- "nopt": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
- "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
- "requires": {
- "abbrev": "1.1.0",
- "osenv": "0.1.4"
- }
- },
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "optional": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.11.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "2.0.6",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.17",
+ "oauth-sign": "0.8.2",
+ "qs": "6.3.2",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.4.3",
+ "uuid": "3.1.0"
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "optional": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "optional": true
+ }
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+ "requires": {
+ "abbrev": "1.1.0",
+ "osenv": "0.1.4"
+ }
+ },
"normalize-package-data": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
@@ -6029,11 +6651,72 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "requires": {
+ "copy-descriptor": "0.1.1",
+ "define-property": "0.2.5",
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ }
+ }
+ },
"object-keys": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
"integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0="
},
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
"object.omit": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
@@ -6053,6 +6736,14 @@
}
}
},
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "requires": {
+ "isobject": "3.0.1"
+ }
+ },
"obuf": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz",
@@ -6269,11 +6960,21 @@
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
},
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
+ },
"path-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo="
},
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
+ },
"path-exists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
@@ -6402,13 +7103,18 @@
}
}
},
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
+ },
"postcss": {
"version": "5.2.17",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz",
"integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=",
"requires": {
"chalk": "1.1.3",
- "js-base64": "2.3.2",
+ "js-base64": "2.4.0",
"source-map": "0.5.7",
"supports-color": "3.2.3"
},
@@ -6463,40 +7169,6 @@
"postcss-value-parser": "3.3.0"
}
},
- "postcss-custom-properties": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.1.0.tgz",
- "integrity": "sha1-nK8RUaxBsenmTTov+ezplsoYl30=",
- "requires": {
- "balanced-match": "1.0.0",
- "postcss": "6.0.11"
- },
- "dependencies": {
- "has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
- },
- "postcss": {
- "version": "6.0.11",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.11.tgz",
- "integrity": "sha512-DsnIzznNRQprsGTALpkC0xjDygo+QcOd+qVjP9+RjyzrPiyYOXBGOwoJ4rAiiE4lu6JggQ/jW4niY24WLxuncg==",
- "requires": {
- "chalk": "2.2.0",
- "source-map": "0.5.7",
- "supports-color": "4.4.0"
- }
- },
- "supports-color": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
- "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
- "requires": {
- "has-flag": "2.0.0"
- }
- }
- }
- },
"postcss-discard-comments": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
@@ -6547,6 +7219,75 @@
"uniqid": "4.1.1"
}
},
+ "postcss-import": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.0.0.tgz",
+ "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=",
+ "requires": {
+ "postcss": "6.0.15",
+ "postcss-value-parser": "3.3.0",
+ "read-cache": "1.0.0",
+ "resolve": "1.4.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
+ },
+ "postcss": {
+ "version": "6.0.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.15.tgz",
+ "integrity": "sha512-v/SpyMzLbtkmh45zUdaqLAaqXqzPdSrw8p4cQVO0/w6YiYfpj4k+Wkzhn68qk9br+H+0qfddhdPEVnbmBPfXVQ==",
+ "requires": {
+ "chalk": "2.3.0",
+ "source-map": "0.6.1",
+ "supports-color": "5.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "supports-color": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
+ "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
"postcss-load-config": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
@@ -6577,12 +7318,12 @@
}
},
"postcss-loader": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.8.tgz",
- "integrity": "sha512-KtXBiQ/r/WYW8LxTSJK7h8wLqvCMSub/BqmRnud/Mu8RzwflW9cmXxwsMwbn15TNv287Hcufdb3ZSs7xHKnG8Q==",
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.10.tgz",
+ "integrity": "sha512-xQaDcEgJ/2JqFY18zpFkik8vyYs7oS5ZRbrjvDqkP97k2wYWfPT4+qA0m4o3pTSCsz0u26PNqs8ZO9FRUWAqrA==",
"requires": {
"loader-utils": "1.1.0",
- "postcss": "6.0.14",
+ "postcss": "6.0.15",
"postcss-load-config": "1.2.0",
"schema-utils": "0.3.0"
},
@@ -6603,6 +7344,16 @@
"ansi-styles": "3.2.0",
"escape-string-regexp": "1.0.5",
"supports-color": "4.5.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
}
},
"has-flag": {
@@ -6611,13 +7362,13 @@
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
},
"postcss": {
- "version": "6.0.14",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
- "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
+ "version": "6.0.15",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.15.tgz",
+ "integrity": "sha512-v/SpyMzLbtkmh45zUdaqLAaqXqzPdSrw8p4cQVO0/w6YiYfpj4k+Wkzhn68qk9br+H+0qfddhdPEVnbmBPfXVQ==",
"requires": {
"chalk": "2.3.0",
"source-map": "0.6.1",
- "supports-color": "4.5.0"
+ "supports-color": "5.1.0"
}
},
"source-map": {
@@ -6626,9 +7377,9 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
+ "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
"requires": {
"has-flag": "2.0.0"
}
@@ -7072,6 +7823,7 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
"integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
+ "dev": true,
"requires": {
"forwarded": "0.1.2",
"ipaddr.js": "1.4.0"
@@ -7109,9 +7861,9 @@
}
},
"pump": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz",
- "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
"requires": {
"end-of-stream": "1.4.0",
"once": "1.4.0"
@@ -7124,7 +7876,7 @@
"requires": {
"duplexify": "3.5.1",
"inherits": "2.0.3",
- "pump": "1.0.2"
+ "pump": "1.0.3"
}
},
"punycode": {
@@ -7216,11 +7968,37 @@
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ }
+ }
+ },
"raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao="
},
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
"read-installed": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz",
@@ -7390,6 +8168,14 @@
"is-equal-shallow": "0.1.3"
}
},
+ "regex-not": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz",
+ "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=",
+ "requires": {
+ "extend-shallow": "2.0.1"
+ }
+ },
"regexpu-core": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
@@ -7557,6 +8343,11 @@
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
},
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
+ },
"restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
@@ -7567,12 +8358,6 @@
"onetime": "1.1.0"
}
},
- "rewire": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/rewire/-/rewire-2.5.2.tgz",
- "integrity": "sha1-ZCfee3/u+n02QBUH62SlOFvFjcc=",
- "dev": true
- },
"right-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -7622,11 +8407,11 @@
"dev": true
},
"rxjs": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.2.tgz",
- "integrity": "sha512-oRYoIKWBU3Ic37fLA5VJu31VqQO4bWubRntcHSJ+cwaDQBwdnZ9x4zmhJfm/nFQ2E82/I4loSioHnACamrKGgA==",
+ "version": "5.5.6",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz",
+ "integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==",
"requires": {
- "symbol-observable": "1.0.4"
+ "symbol-observable": "1.0.1"
}
},
"safe-buffer": {
@@ -7684,7 +8469,7 @@
"integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
"optional": true,
"requires": {
- "js-base64": "2.3.2",
+ "js-base64": "2.4.0",
"source-map": "0.4.4"
},
"dependencies": {
@@ -7721,6 +8506,7 @@
"version": "0.15.4",
"resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz",
"integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=",
+ "dev": true,
"requires": {
"debug": "2.6.8",
"depd": "1.1.1",
@@ -7740,10 +8526,16 @@
"mime": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
- "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=",
+ "dev": true
}
}
},
+ "serialize-javascript": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz",
+ "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU="
+ },
"serializerr": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/serializerr/-/serializerr-1.0.3.tgz",
@@ -7771,6 +8563,7 @@
"version": "1.12.4",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz",
"integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=",
+ "dev": true,
"requires": {
"encodeurl": "1.0.1",
"escape-html": "1.0.3",
@@ -7783,11 +8576,30 @@
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
+ "set-getter": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
+ "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
+ "requires": {
+ "to-object-path": "0.3.0"
+ }
+ },
"set-immediate-shim": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
},
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "split-string": "3.1.0"
+ }
+ },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -7894,45 +8706,123 @@
"integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=",
"dev": true
},
- "sntp": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz",
- "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=",
- "requires": {
- "hoek": "4.2.0"
- }
- },
- "sockjs": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz",
- "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=",
- "requires": {
- "faye-websocket": "0.10.0",
- "uuid": "2.0.3"
- },
- "dependencies": {
- "uuid": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
- "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho="
- }
- }
- },
- "sockjs-client": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
- "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
+ "snapdragon": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz",
+ "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=",
"requires": {
+ "base": "0.11.2",
"debug": "2.6.8",
- "eventsource": "0.1.6",
- "faye-websocket": "0.11.1",
- "inherits": "2.0.3",
- "json3": "3.3.2",
- "url-parse": "1.1.9"
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "map-cache": "0.2.2",
+ "source-map": "0.5.7",
+ "source-map-resolve": "0.5.1",
+ "use": "2.0.2"
},
"dependencies": {
- "faye-websocket": {
- "version": "0.11.1",
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "requires": {
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "snapdragon-util": "3.0.1"
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "sntp": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz",
+ "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=",
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "sockjs-client": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
+ "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
+ "requires": {
+ "debug": "2.6.8",
+ "eventsource": "0.1.6",
+ "faye-websocket": "0.11.1",
+ "inherits": "2.0.3",
+ "json3": "3.3.2",
+ "url-parse": "1.1.9"
+ },
+ "dependencies": {
+ "faye-websocket": {
+ "version": "0.11.1",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
"integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
"requires": {
@@ -7995,6 +8885,18 @@
}
}
},
+ "source-map-resolve": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+ "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+ "requires": {
+ "atob": "2.0.3",
+ "decode-uri-component": "0.2.0",
+ "resolve-url": "0.2.1",
+ "source-map-url": "0.4.0",
+ "urix": "0.1.0"
+ }
+ },
"source-map-support": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
@@ -8003,6 +8905,11 @@
"source-map": "0.5.7"
}
},
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
+ },
"spdx": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/spdx/-/spdx-0.5.1.tgz",
@@ -8099,6 +9006,33 @@
"through": "2.3.8"
}
},
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "requires": {
+ "extend-shallow": "3.0.2"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
"split2": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/split2/-/split2-2.1.1.tgz",
@@ -8136,6 +9070,76 @@
"safe-buffer": "5.1.1"
}
},
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "requires": {
+ "define-property": "0.2.5",
+ "object-copy": "0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
"statuses": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
@@ -8169,9 +9173,9 @@
}
},
"stream-each": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.0.tgz",
- "integrity": "sha1-HpXUdXP1gNgU3A/4zQ9m8c5TyZE=",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
+ "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
"requires": {
"end-of-stream": "1.4.0",
"stream-shift": "1.0.0"
@@ -8269,11 +9273,12 @@
"dev": true
},
"style-loader": {
- "version": "0.13.2",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.13.2.tgz",
- "integrity": "sha1-dFMzhM9pjHEEx5URULSXF63C87s=",
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz",
+ "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==",
"requires": {
- "loader-utils": "1.1.0"
+ "loader-utils": "1.1.0",
+ "schema-utils": "0.3.0"
}
},
"stylus": {
@@ -8350,9 +9355,9 @@
}
},
"symbol-observable": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",
- "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
+ "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
},
"sync-exec": {
"version": "0.6.2",
@@ -8450,18 +9455,28 @@
"integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI="
},
"tar": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-3.2.1.tgz",
- "integrity": "sha512-ZSzds1E0IqutvMU8HxjMaU8eB7urw2fGwTq88ukDOVuUIh0656l7/P7LiVPxhO5kS4flcRJQk8USG+cghQbTUQ==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.1.1.tgz",
+ "integrity": "sha512-p2lLtRABOEhuC28GDpMYwxcDYRqAFfiz2AIZiQlI+fhrACPKtQ1mcF/bPY8T1h9aKlpDpd+WE33Y2PJ/hWhm8g==",
"dev": true,
"requires": {
"chownr": "1.0.1",
+ "fs-minipass": "1.2.3",
"minipass": "2.2.1",
- "minizlib": "1.0.3",
+ "minizlib": "1.0.4",
"mkdirp": "0.5.1",
"yallist": "3.0.2"
},
"dependencies": {
+ "minizlib": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.0.4.tgz",
+ "integrity": "sha512-sN4U9tIJtBRwKbwgFh9qJfrPIQ/GGTRr1MGqkgOeMTLy8/lM0FcWU//FqlnZ3Vb7gJ+Mxh3FOg1EklibdajbaQ==",
+ "dev": true,
+ "requires": {
+ "minipass": "2.2.1"
+ }
+ },
"yallist": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
@@ -8543,6 +9558,104 @@
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
},
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz",
+ "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=",
+ "requires": {
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "regex-not": "1.0.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "requires": {
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ }
+ }
+ },
"toposort": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.3.tgz",
@@ -8583,6 +9696,30 @@
"resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
},
+ "true-case-path": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
+ "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
+ "optional": true,
+ "requires": {
+ "glob": "6.0.4"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "optional": true,
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ }
+ }
+ },
"tryit": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
@@ -8733,33 +9870,61 @@
"optional": true
},
"uglifyjs-webpack-plugin": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.0.0.tgz",
- "integrity": "sha512-23qmtiLm1X7O0XVSZ54W7XGHykPss+2lo3RYC9zSzK3DDT5W27woZpDFDKguDCnG1RIX8cDnmy5j+dtXxJCA/Q==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.5.tgz",
+ "integrity": "sha512-YBGc9G7dv12Vjx8vUQs54DZgAXVf04LlG6dNNiEbTZjL3PbUqiY4uPB9Kv+fUJaqRskEGva/lS7sh08yJr7jnA==",
"requires": {
- "cacache": "10.0.0",
+ "cacache": "10.0.1",
"find-cache-dir": "1.0.0",
"schema-utils": "0.3.0",
- "source-map": "0.5.7",
- "uglify-es": "3.1.5",
+ "serialize-javascript": "1.4.0",
+ "source-map": "0.6.1",
+ "uglify-es": "3.2.2",
"webpack-sources": "1.0.1",
- "worker-farm": "1.4.1"
+ "worker-farm": "1.5.2"
},
"dependencies": {
+ "commander": {
+ "version": "2.12.2",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+ "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA=="
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
"uglify-es": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.1.5.tgz",
- "integrity": "sha512-l2PqhvUNmD5pOKiHMuE8TmlvvsghxvLcg+ffcg/obRn/qm0fXf+1Mi8N7tZZIi6zxQS+PbIvq39VCYxmK0QMYA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.2.tgz",
+ "integrity": "sha512-l+s5VLzFwGJfS+fbqaGf/Dfwo1MF13jLOF2ekL0PytzqEqQ6cVppvHf4jquqFok+35USMpKjqkYxy6pQyUcuug==",
"requires": {
- "commander": "2.11.0",
+ "commander": "2.12.2",
"source-map": "0.6.1"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- }
+ }
+ }
+ }
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "requires": {
+ "arr-union": "3.1.0",
+ "get-value": "2.0.6",
+ "is-extendable": "0.1.1",
+ "set-value": "0.4.3"
+ },
+ "dependencies": {
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
}
}
}
@@ -8808,11 +9973,52 @@
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "requires": {
+ "has-value": "0.3.1",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "0.1.4",
+ "isobject": "2.1.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
+ }
+ }
+ },
"upper-case": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
"integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
},
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
+ },
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -8862,6 +10068,85 @@
}
}
},
+ "use": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz",
+ "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=",
+ "requires": {
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "lazy-cache": "2.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ },
+ "lazy-cache": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
+ "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
+ "requires": {
+ "set-getter": "0.1.0"
+ }
+ }
+ }
+ },
"user-home": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
@@ -8905,7 +10190,8 @@
"utils-merge": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
- "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
+ "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=",
+ "dev": true
},
"uuid": {
"version": "3.1.0",
@@ -8971,16 +10257,6 @@
"indexof": "0.0.1"
}
},
- "walk-sync": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.2.tgz",
- "integrity": "sha512-FMB5VqpLqOCcqrzA9okZFc0wq0Qbmdm396qJxvQZhDpyu0W95G9JCmp74tx7iyYnyOcBtUuKJsgIKAqjozvmmQ==",
- "dev": true,
- "requires": {
- "ensure-posix-path": "1.0.2",
- "matcher-collection": "1.0.5"
- }
- },
"watchpack": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
@@ -9000,9 +10276,9 @@
}
},
"webpack": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz",
- "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==",
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz",
+ "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==",
"requires": {
"acorn": "5.1.2",
"acorn-dynamic-import": "2.0.2",
@@ -9255,58 +10531,6 @@
}
}
},
- "webpack-concat-plugin": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/webpack-concat-plugin/-/webpack-concat-plugin-1.4.0.tgz",
- "integrity": "sha512-Ym9Qm5Sw9oXJYChNJk09I/yaXDaV3UDxsa07wcCvILzIeSJTnSUZjhS4y2YkULzgE8VHOv9X04KtlJPZGwXqMg==",
- "requires": {
- "md5": "2.2.1",
- "uglify-js": "2.8.29"
- },
- "dependencies": {
- "camelcase": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
- "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
- },
- "cliui": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
- "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
- "requires": {
- "center-align": "0.1.3",
- "right-align": "0.1.3",
- "wordwrap": "0.0.2"
- }
- },
- "uglify-js": {
- "version": "2.8.29",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
- "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
- "requires": {
- "source-map": "0.5.7",
- "uglify-to-browserify": "1.0.2",
- "yargs": "3.10.0"
- }
- },
- "wordwrap": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
- "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
- },
- "yargs": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
- "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
- "requires": {
- "camelcase": "1.2.1",
- "cliui": "2.1.0",
- "decamelize": "1.2.0",
- "window-size": "0.1.0"
- }
- }
- }
- },
"webpack-core": {
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz",
@@ -9344,43 +10568,109 @@
}
},
"webpack-dev-server": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.3.tgz",
- "integrity": "sha512-bwq7sj452FRH+oVfgOA8xXKkLYPTNsYB4dQ0Jhz3ydjNJ9MvhpGJtehFW8Z0cEcwNkRRiF4aYbReiSGQ4pbS1w==",
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.0.tgz",
+ "integrity": "sha512-lXzc36DGjKUVinETNmDWhfZFRbHMhatuF+lKex+czqY+JVe0Qf2V+Ig6/svDdbt/DmXFXuLQmSqhncYCqYf3qA==",
"requires": {
"ansi-html": "0.0.7",
"array-includes": "3.0.3",
"bonjour": "3.5.0",
- "chokidar": "1.7.0",
+ "chokidar": "2.0.0",
"compression": "1.7.0",
"connect-history-api-fallback": "1.3.0",
"debug": "3.1.0",
"del": "3.0.0",
- "express": "4.15.4",
+ "express": "4.16.2",
"html-entities": "1.2.1",
"http-proxy-middleware": "0.17.4",
- "import-local": "0.1.1",
+ "import-local": "1.0.0",
"internal-ip": "1.2.0",
"ip": "1.1.5",
+ "killable": "1.0.0",
"loglevel": "1.4.1",
"opn": "5.1.0",
"portfinder": "1.0.13",
"selfsigned": "1.9.1",
"serve-index": "1.9.0",
- "sockjs": "0.3.18",
+ "sockjs": "0.3.19",
"sockjs-client": "1.1.4",
"spdy": "3.4.7",
- "strip-ansi": "3.0.1",
- "supports-color": "4.4.0",
- "webpack-dev-middleware": "1.12.0",
+ "strip-ansi": "4.0.0",
+ "supports-color": "5.1.0",
+ "webpack-dev-middleware": "1.12.2",
"yargs": "6.6.0"
},
"dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "requires": {
+ "micromatch": "3.1.5",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+ },
+ "braces": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz",
+ "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==",
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "repeat-element": "1.1.2",
+ "snapdragon": "0.8.1",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.1"
+ }
+ },
"camelcase": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
},
+ "chokidar": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.0.tgz",
+ "integrity": "sha512-OgXCNv2U6TnG04D3tth0gsvdbV4zdbxFG3sYUqcoQMoEFVd1j1pZR6TZ8iknC45o9IJ6PeQI/J6wT/+cHcniAw==",
+ "requires": {
+ "anymatch": "2.0.0",
+ "async-each": "1.0.1",
+ "braces": "2.3.0",
+ "fsevents": "1.1.3",
+ "glob-parent": "3.1.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "4.0.0",
+ "normalize-path": "2.1.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0"
+ }
+ },
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -9389,19 +10679,396 @@
"ms": "2.0.0"
}
},
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "requires": {
+ "debug": "2.6.9",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
+ "express": {
+ "version": "4.16.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
+ "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
+ "requires": {
+ "accepts": "1.3.4",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
+ "content-disposition": "0.5.2",
+ "content-type": "1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "1.1.1",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "finalhandler": "1.1.0",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "1.1.2",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "2.0.2",
+ "qs": "6.5.1",
+ "range-parser": "1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.1",
+ "serve-static": "1.13.1",
+ "setprototypeof": "1.1.0",
+ "statuses": "1.3.1",
+ "type-is": "1.6.15",
+ "utils-merge": "1.0.1",
+ "vary": "1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "requires": {
+ "is-glob": "3.1.0",
+ "path-dirname": "1.0.2"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ }
+ }
+ },
"has-flag": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE="
},
+ "import-local": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
+ "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==",
+ "requires": {
+ "pkg-dir": "2.0.0",
+ "resolve-cwd": "2.0.0"
+ }
+ },
+ "ipaddr.js": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
+ "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ },
+ "micromatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz",
+ "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==",
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.0",
+ "define-property": "1.0.0",
+ "extend-shallow": "2.0.1",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.7",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.0",
+ "snapdragon": "0.8.1",
+ "to-regex": "3.0.1"
+ }
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+ },
+ "proxy-addr": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+ "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
+ "requires": {
+ "forwarded": "0.1.2",
+ "ipaddr.js": "1.5.2"
+ }
+ },
+ "send": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+ "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "1.1.1",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+ "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
+ "requires": {
+ "encodeurl": "1.0.1",
+ "escape-html": "1.0.3",
+ "parseurl": "1.3.2",
+ "send": "0.16.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+ },
+ "sockjs": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
+ "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
+ "requires": {
+ "faye-websocket": "0.10.0",
+ "uuid": "3.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
"supports-color": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
- "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
+ "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
"requires": {
"has-flag": "2.0.0"
}
},
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "webpack-dev-middleware": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz",
+ "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==",
+ "requires": {
+ "memory-fs": "0.4.1",
+ "mime": "1.6.0",
+ "path-is-absolute": "1.0.1",
+ "range-parser": "1.2.0",
+ "time-stamp": "2.0.0"
+ },
+ "dependencies": {
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ }
+ }
+ },
"yargs": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
@@ -9513,9 +11180,9 @@
"dev": true
},
"worker-farm": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.4.1.tgz",
- "integrity": "sha512-tgFAtgOYLPutkAyzgpS6VJFL5HY+0ui1Tvua+fITgz8ByaJTMFGtazR6xxQfwfiAcbwE+2fLG/K49wc2TfwCNw==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.2.tgz",
+ "integrity": "sha512-XxiQ9kZN5n6mmnW+mFJ+wXjNNI/Nx4DIdaAKLX1Bn6LYBWlN/zaBhu34DQYPZ1AJobQuu67S2OfDdNSVULvXkQ==",
"requires": {
"errno": "0.1.4",
"xtend": "4.0.1"
@@ -9625,9 +11292,10 @@
"dev": true
},
"zone.js": {
- "version": "0.8.17",
- "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.17.tgz",
- "integrity": "sha1-TF5RhahX2o2nk9rzkZNxxaNrKgs="
+ "version": "0.8.20",
+ "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.20.tgz",
+ "integrity": "sha512-FXlA37ErSXCMy5RNBcGFgCI/Zivqzr0D19GuvDxhcYIJc7xkFp6c29DKyODJu0Zo+EMyur/WPPgcBh1EHjB9jA==",
+ "dev": true
}
}
}
diff --git a/package.json b/package.json
index adab4c28470f..000a793edd7d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@angular/cli",
- "version": "1.6.0-beta.2",
+ "version": "1.7.0-beta.1",
"description": "CLI tool for Angular",
"main": "packages/@angular/cli/lib/cli/index.js",
"trackingCode": "UA-8594346-19",
@@ -41,27 +41,28 @@
},
"homepage": "https://github.com/angular/angular-cli",
"dependencies": {
- "@angular-devkit/build-optimizer": "~0.0.28",
- "@angular-devkit/schematics": "~0.0.35",
- "@schematics/angular": "~0.1.0",
- "autoprefixer": "^6.5.3",
+ "@angular-devkit/build-optimizer": "~0.0.41",
+ "@angular-devkit/core": "~0.0.28",
+ "@angular-devkit/schematics": "~0.0.51",
+ "@schematics/angular": "~0.1.16",
+ "autoprefixer": "^7.2.3",
"chalk": "~2.2.0",
- "circular-dependency-plugin": "^3.0.0",
+ "circular-dependency-plugin": "^4.2.1",
+ "clean-css": "^4.1.9",
"common-tags": "^1.3.1",
"copy-webpack-plugin": "^4.1.1",
"core-object": "^3.1.0",
"css-loader": "^0.28.1",
- "cssnano": "^3.10.0",
"denodeify": "^1.2.1",
"ember-cli-string-utils": "^1.0.0",
"enhanced-resolve": "^3.4.1",
"exports-loader": "^0.6.3",
- "extract-text-webpack-plugin": "3.0.0",
+ "extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"fs-extra": "^4.0.0",
"glob": "^7.0.3",
"html-webpack-plugin": "^2.29.0",
- "istanbul-instrumenter-loader": "^2.0.0",
+ "istanbul-instrumenter-loader": "^3.0.0",
"karma-source-map-support": "^1.2.0",
"less": "^2.7.2",
"less-loader": "^4.0.5",
@@ -75,33 +76,31 @@
"nopt": "^4.0.1",
"opn": "~5.1.0",
"portfinder": "~1.0.12",
- "postcss-custom-properties": "^6.1.0",
- "postcss-loader": "^2.0.8",
+ "postcss-import": "^11.0.0",
+ "postcss-loader": "^2.0.10",
"postcss-url": "^7.1.2",
"raw-loader": "^0.5.1",
"resolve": "^1.1.7",
- "rxjs": "^5.5.2",
- "sass-loader": "^6.0.3",
+ "rxjs": "^5.5.6",
+ "sass-loader": "^6.0.6",
"semver": "^5.3.0",
"silent-error": "^1.0.0",
"source-map": "^0.5.6",
"source-map-loader": "^0.2.0",
"source-map-support": "^0.4.1",
- "style-loader": "^0.13.1",
+ "style-loader": "^0.19.1",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1",
"tree-kill": "^1.0.0",
"typescript": "~2.4.2",
- "uglifyjs-webpack-plugin": "1.0.0",
+ "uglifyjs-webpack-plugin": "^1.1.5",
"url-loader": "^0.6.2",
- "webpack": "~3.8.1",
- "webpack-concat-plugin": "1.4.0",
+ "webpack": "~3.10.0",
"webpack-dev-middleware": "~1.12.0",
- "webpack-dev-server": "~2.9.3",
+ "webpack-dev-server": "~2.11.0",
"webpack-merge": "^4.1.0",
"webpack-sources": "^1.0.0",
- "webpack-subresource-integrity": "^1.0.1",
- "zone.js": "^0.8.14"
+ "webpack-subresource-integrity": "^1.0.1"
},
"devDependencies": {
"@angular/compiler": "^5.0.0",
@@ -116,6 +115,7 @@
"@types/glob": "^5.0.29",
"@types/jasmine": "2.5.45",
"@types/lodash": "~4.14.50",
+ "@types/loader-utils": "^1.1.0",
"@types/minimist": "^1.2.0",
"@types/mock-fs": "^3.6.30",
"@types/node": "^6.0.84",
@@ -123,29 +123,29 @@
"@types/semver": "^5.3.30",
"@types/source-map": "^0.5.0",
"@types/webpack": "^3.0.5",
+ "@types/webpack-sources": "^0.1.3",
"conventional-changelog": "1.1.0",
"dtsgenerator": "^0.9.1",
"eslint": "^3.11.0",
"express": "^4.14.0",
"jasmine": "^2.6.0",
"jasmine-spec-reporter": "^4.1.0",
- "license-checker": "^14.0.0",
+ "license-checker": "^15.0.0",
"minimist": "^1.2.0",
"mock-fs": "^4.0.0",
"npm-run": "^4.1.0",
"npm-run-all": "^4.0.0",
"request": "^2.74.0",
"resolve-bin": "^0.4.0",
- "rewire": "^2.5.1",
"spdx-satisfies": "^0.1.3",
- "tar": "^3.1.5",
+ "tar": "^4.1.1",
"temp": "0.8.3",
"through": "^2.3.6",
"ts-node": "^3.2.0",
"tslint": "^5.1.0",
- "walk-sync": "^0.3.1"
+ "zone.js": "^0.8.20"
},
"optionalDependencies": {
- "node-sass": "^4.3.0"
+ "node-sass": "^4.7.2"
}
}
diff --git a/packages/@angular/cli/bin/ng b/packages/@angular/cli/bin/ng
index 2c265c957d4d..3f32d98ffb80 100755
--- a/packages/@angular/cli/bin/ng
+++ b/packages/@angular/cli/bin/ng
@@ -151,6 +151,7 @@ resolve('@angular/cli', { basedir: process.cwd() },
localVersion = _fromPackageJson();
shouldWarn = localVersion && globalVersion.compare(localVersion) > 0;
} catch (e) {
+ // eslint-disable-next-line no-console
console.error(e);
shouldWarn = true;
}
@@ -163,14 +164,14 @@ resolve('@angular/cli', { basedir: process.cwd() },
To disable this warning use "ng set --global warnings.versionMismatch=false".
`);
// Don't show warning colorised on `ng completion`
- if (process.argv[2] !== 'completion') {
- // eslint-disable no-console
- console.log(warning);
- } else {
- // eslint-disable no-console
- console.error(warning);
- process.exit(1);
- }
+ if (process.argv[2] !== 'completion') {
+ // eslint-disable-next-line no-console
+ console.log(warning);
+ } else {
+ // eslint-disable-next-line no-console
+ console.error(warning);
+ process.exit(1);
+ }
}
// No error implies a projectLocalCli, which will load whatever
diff --git a/packages/@angular/cli/commands/build.ts b/packages/@angular/cli/commands/build.ts
index 64bd4f823461..2611e66b0527 100644
--- a/packages/@angular/cli/commands/build.ts
+++ b/packages/@angular/cli/commands/build.ts
@@ -2,9 +2,12 @@ import { CliConfig } from '../models/config';
import { BuildOptions } from '../models/build-options';
import { Version } from '../upgrade/version';
import { oneLine } from 'common-tags';
+import { getAppFromConfig } from '../utilities/app-utils';
+import { join } from 'path';
+import { RenderUniversalTaskOptions } from '../tasks/render-universal';
const Command = require('../ember-cli/lib/models/command');
-
+const SilentError = require('silent-error');
const config = CliConfig.fromProject() || CliConfig.fromGlobal();
const buildConfigDefaults = config.getPaths('defaults.build', [
@@ -198,6 +201,12 @@ export const baseBuildCommandOptions: any = [
aliases: ['sw'],
description: 'Generates a service worker config for production builds, if the app has '
+ 'service worker enabled.'
+ },
+ {
+ name: 'skip-app-shell',
+ type: Boolean,
+ description: 'Flag to prevent building an app shell',
+ default: false
}
];
@@ -230,6 +239,11 @@ const BuildCommand = Command.extend({
commandOptions.forceTsCommonjs = true;
}
+ // Add trailing slash if missing to prevent https://github.com/angular/angular-cli/issues/7295
+ if (commandOptions.deployUrl && commandOptions.deployUrl.substr(-1) !== '/') {
+ commandOptions.deployUrl += '/';
+ }
+
const BuildTask = require('../tasks/build').default;
const buildTask = new BuildTask({
@@ -237,7 +251,51 @@ const BuildCommand = Command.extend({
ui: this.ui,
});
- return buildTask.run(commandOptions);
+ const clientApp = getAppFromConfig(commandOptions.app);
+
+ const doAppShell = commandOptions.target === 'production' &&
+ (commandOptions.aot === undefined || commandOptions.aot === true) &&
+ !commandOptions.skipAppShell;
+
+ let serverApp: any = null;
+ if (clientApp.appShell && doAppShell) {
+ serverApp = getAppFromConfig(clientApp.appShell.app);
+ if (serverApp.platform !== 'server') {
+ throw new SilentError(`Shell app's platform is not "server"`);
+ }
+ }
+
+ const buildPromise = buildTask.run(commandOptions);
+
+ if (!clientApp.appShell || !doAppShell) {
+ return buildPromise;
+ }
+
+ return buildPromise
+ .then(() => {
+
+ const serverOptions = {
+ ...commandOptions,
+ app: clientApp.appShell.app
+ };
+ return buildTask.run(serverOptions);
+ })
+ .then(() => {
+ const RenderUniversalTask = require('../tasks/render-universal').default;
+
+ const renderUniversalTask = new RenderUniversalTask({
+ project: this.project,
+ ui: this.ui,
+ });
+ const renderUniversalOptions: RenderUniversalTaskOptions = {
+ inputIndexPath: join(this.project.root, clientApp.outDir, clientApp.index),
+ route: clientApp.appShell.route,
+ serverOutDir: join(this.project.root, serverApp.outDir),
+ outputIndexPath: join(this.project.root, clientApp.outDir, clientApp.index)
+ };
+
+ return renderUniversalTask.run(renderUniversalOptions);
+ });
}
});
diff --git a/packages/@angular/cli/commands/e2e.ts b/packages/@angular/cli/commands/e2e.ts
index fc6d084816a8..3f23ee27a26d 100644
--- a/packages/@angular/cli/commands/e2e.ts
+++ b/packages/@angular/cli/commands/e2e.ts
@@ -13,6 +13,7 @@ export interface E2eTaskOptions extends ServeTaskOptions {
serve: boolean;
webdriverUpdate: boolean;
specs: string[];
+ suite: string;
elementExplorer: boolean;
}
@@ -42,6 +43,15 @@ const E2eCommand = Command.extend({
Can send in multiple specs by repeating flag (ng e2e --specs=spec1.ts --specs=spec2.ts).
`
},
+ {
+ name: 'suite',
+ type: String,
+ aliases: ['su'],
+ description: oneLine`
+ Override suite in the protractor config.
+ Can send in multiple suite by comma separated values (ng e2e --suite=suiteA,suiteB).
+ `
+ },
{
name: 'element-explorer',
type: Boolean,
diff --git a/packages/@angular/cli/commands/generate.ts b/packages/@angular/cli/commands/generate.ts
index e9a4d79b3585..b8337be48a5b 100644
--- a/packages/@angular/cli/commands/generate.ts
+++ b/packages/@angular/cli/commands/generate.ts
@@ -65,15 +65,24 @@ export default Command.extend({
''
],
- getCollectionName(rawArgs: string[]) {
+ getCollectionName(rawArgs: string[], parsedOptions?: { collection?: string }): [string, string] {
+ let schematicName = rawArgs[0];
let collectionName = CliConfig.getValue('defaults.schematics.collection');
- if (rawArgs) {
+
+ if (schematicName.match(/:/)) {
+ [collectionName, schematicName] = schematicName.split(':', 2);
+ } else if (parsedOptions) {
+ if (parsedOptions.collection) {
+ collectionName = parsedOptions.collection;
+ }
+ } else {
const parsedArgs = this.parseArgs(rawArgs, false);
if (parsedArgs.options.collection) {
collectionName = parsedArgs.options.collection;
}
}
- return collectionName;
+
+ return [collectionName, schematicName];
},
beforeRun: function(rawArgs: string[]) {
@@ -83,7 +92,7 @@ export default Command.extend({
return;
}
- const schematicName = rawArgs[0];
+ const [collectionName, schematicName] = this.getCollectionName(rawArgs);
if (!schematicName) {
return Promise.reject(new SilentError(oneLine`
The "ng generate" command requires a
@@ -103,21 +112,30 @@ export default Command.extend({
ui: this.ui,
project: this.project
});
- const collectionName = this.getCollectionName(rawArgs);
return getOptionsTask.run({
schematicName,
collectionName
})
- .then((availableOptions: SchematicAvailableOptions) => {
+ .then((availableOptions: SchematicAvailableOptions[]) => {
let anonymousOptions: string[] = [];
+
+ if (availableOptions) {
+ const nameOption = availableOptions.filter(opt => opt.name === 'name')[0];
+ if (nameOption) {
+ anonymousOptions = [...anonymousOptions, ''];
+ }
+ } else {
+ anonymousOptions = [...anonymousOptions, ''];
+ }
+
if (collectionName === '@schematics/angular' && schematicName === 'interface') {
- anonymousOptions = [''];
+ anonymousOptions = [...anonymousOptions, ''];
}
this.registerOptions({
anonymousOptions: anonymousOptions,
- availableOptions: availableOptions
+ availableOptions: availableOptions || []
});
});
},
@@ -127,8 +145,12 @@ export default Command.extend({
throw 'The `ng generate module` command requires a name to be specified.';
}
- const entityName = rawArgs[1];
- commandOptions.name = stringUtils.dasherize(entityName.split(separatorRegEx).pop());
+ let entityName = rawArgs[1];
+ if (entityName) {
+ commandOptions.name = stringUtils.dasherize(entityName.split(separatorRegEx).pop());
+ } else {
+ entityName = '';
+ }
const appConfig = getAppFromConfig(commandOptions.app);
const dynamicPathOptions: DynamicPathOptions = {
@@ -138,7 +160,7 @@ export default Command.extend({
dryRun: commandOptions.dryRun
};
const parsedPath = dynamicPathParser(dynamicPathOptions);
- commandOptions.sourceDir = parsedPath.sourceDir;
+ commandOptions.sourceDir = parsedPath.sourceDir.replace(separatorRegEx, '/');
const root = parsedPath.sourceDir + path.sep;
commandOptions.appRoot = parsedPath.appRoot === parsedPath.sourceDir ? '' :
parsedPath.appRoot.startsWith(root)
@@ -152,7 +174,7 @@ export default Command.extend({
: commandOptions.path;
const cwd = this.project.root;
- const schematicName = rawArgs[0];
+ const [collectionName, schematicName] = this.getCollectionName(rawArgs, commandOptions);
if (['component', 'c', 'directive', 'd'].indexOf(schematicName) !== -1) {
if (commandOptions.prefix === undefined) {
@@ -171,8 +193,6 @@ export default Command.extend({
ui: this.ui,
project: this.project
});
- const collectionName = commandOptions.collection ||
- CliConfig.getValue('defaults.schematics.collection');
if (collectionName === '@schematics/angular' && schematicName === 'interface' && rawArgs[2]) {
commandOptions.type = rawArgs[2];
diff --git a/packages/@angular/cli/lib/cli/index.ts b/packages/@angular/cli/lib/cli/index.ts
index e47fe33117c9..4f6a81d09294 100644
--- a/packages/@angular/cli/lib/cli/index.ts
+++ b/packages/@angular/cli/lib/cli/index.ts
@@ -1,7 +1,3 @@
-// Prevent the dependency validation from tripping because we don't import these. We need
-// it as a peer dependency of @angular/core.
-// require('zone.js')
-
import * as path from 'path';
const cli = require('../../ember-cli/lib/cli');
diff --git a/packages/@angular/cli/lib/config/schema.json b/packages/@angular/cli/lib/config/schema.json
index 6e38ae682e2f..7359d5d348d8 100644
--- a/packages/@angular/cli/lib/config/schema.json
+++ b/packages/@angular/cli/lib/config/schema.json
@@ -38,6 +38,20 @@
"description": "Directory where app files are placed.",
"default": "app"
},
+ "appShell": {
+ "type": "object",
+ "description": "AppShell configuration.",
+ "properties": {
+ "app": {
+ "type": "string",
+ "description": "Index or name of the related AppShell app."
+ },
+ "route": {
+ "type": "string",
+ "description": "Default AppShell route to render."
+ }
+ }
+ },
"root": {
"type": "string",
"description": "The root directory of the app."
@@ -85,6 +99,53 @@
},
"default": []
},
+ "budgets": {
+ "type": "array",
+ "description": "Threshold definitions for bundle sizes.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["bundle", "initial", "allScript", "all", "anyScript", "any"],
+ "description": "The type of budget"
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the bundle"
+ },
+ "baseline": {
+ "type": "string",
+ "description": "The baseline size for comparison."
+ },
+ "maximumWarning": {
+ "type": "string",
+ "description": "The maximum threshold for warning relative to the baseline."
+ },
+ "maximumError": {
+ "type": "string",
+ "description": "The maximum threshold for error relative to the baseline."
+ },
+ "minimumWarning": {
+ "type": "string",
+ "description": "The minimum threshold for warning relative to the baseline."
+ },
+ "minimumError": {
+ "type": "string",
+ "description": "The minimum threshold for error relative to the baseline."
+ },
+ "warning": {
+ "type": "string",
+ "description": "The threshold for warning relative to the baseline (min & max)."
+ },
+ "error": {
+ "type": "string",
+ "description": "The threshold for error relative to the baseline (min & max)."
+ }
+ }
+ },
+ "default": []
+ },
"deployUrl": {
"type": "string",
"description": "URL where files will be deployed."
@@ -600,6 +661,11 @@
"description": "Show a warning when the TypeScript version is incompatible",
"type": "boolean",
"default": true
+ },
+ "servePathDefault": {
+ "description": "Show a warning when deploy-url/base-href use unsupported serve path values.",
+ "type": "boolean",
+ "default": true
}
}
}
diff --git a/packages/@angular/cli/models/build-options.ts b/packages/@angular/cli/models/build-options.ts
index 13f7c23324ed..05abcfb3ee23 100644
--- a/packages/@angular/cli/models/build-options.ts
+++ b/packages/@angular/cli/models/build-options.ts
@@ -32,4 +32,5 @@ export interface BuildOptions {
subresourceIntegrity?: boolean;
forceTsCommonjs?: boolean;
serviceWorker?: boolean;
+ skipAppShell?: boolean;
}
diff --git a/packages/@angular/cli/models/webpack-configs/common.ts b/packages/@angular/cli/models/webpack-configs/common.ts
index ecb60283a19c..3e24b93a7780 100644
--- a/packages/@angular/cli/models/webpack-configs/common.ts
+++ b/packages/@angular/cli/models/webpack-configs/common.ts
@@ -2,13 +2,12 @@ import * as webpack from 'webpack';
import * as path from 'path';
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
import { NamedLazyChunksWebpackPlugin } from '../../plugins/named-lazy-chunks-webpack-plugin';
-import { InsertConcatAssetsWebpackPlugin } from '../../plugins/insert-concat-assets-webpack-plugin';
import { extraEntryParser, getOutputHashFormat, AssetPattern } from './utils';
import { isDirectory } from '../../utilities/is-directory';
import { requireProjectModule } from '../../utilities/require-project-module';
import { WebpackConfigOptions } from '../webpack-config';
+import { ScriptsWebpackPlugin } from '../../plugins/scripts-webpack-plugin';
-const ConcatPlugin = require('webpack-concat-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const SilentError = require('silent-error');
@@ -65,23 +64,16 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
// Add a new asset for each entry.
globalScriptsByEntry.forEach((script) => {
- const hash = hashFormat.chunk !== '' && !script.lazy ? '.[hash]' : '';
- extraPlugins.push(new ConcatPlugin({
- uglify: buildOptions.target === 'production' ? { sourceMapIncludeSources: true } : false,
- sourceMap: buildOptions.sourcemaps,
+ // Lazy scripts don't get a hash, otherwise they can't be loaded by name.
+ const hash = script.lazy ? '' : hashFormat.script;
+ extraPlugins.push(new ScriptsWebpackPlugin({
name: script.entry,
- // Lazy scripts don't get a hash, otherwise they can't be loaded by name.
- fileName: `[name]${script.lazy ? '' : hash}.bundle.js`,
- filesToConcat: script.paths
+ sourceMap: buildOptions.sourcemaps,
+ filename: `${script.entry}${hash}.bundle.js`,
+ scripts: script.paths,
+ basePath: projectRoot,
}));
});
-
- // Insert all the assets created by ConcatPlugin in the right place in index.html.
- extraPlugins.push(new InsertConcatAssetsWebpackPlugin(
- globalScriptsByEntry
- .filter((el) => !el.lazy)
- .map((el) => el.entry)
- ));
}
// process asset entries
@@ -91,19 +83,25 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
asset = typeof asset === 'string' ? { glob: asset } : asset;
// Add defaults.
// Input is always resolved relative to the appRoot.
- asset.input = path.resolve(appRoot, asset.input || '');
+ asset.input = path.resolve(appRoot, asset.input || '').replace(/\\/g, '/');
asset.output = asset.output || '';
asset.glob = asset.glob || '';
// Prevent asset configurations from writing outside of the output path, except if the user
// specify a configuration flag.
// Also prevent writing outside the project path. That is not overridable.
- const fullOutputPath = path.resolve(buildOptions.outputPath, asset.output);
- if (!fullOutputPath.startsWith(projectRoot)) {
- const message = 'An asset cannot be written to a location outside the project.';
- throw new SilentError(message);
- }
- if (!fullOutputPath.startsWith(path.resolve(buildOptions.outputPath))) {
+ const absoluteOutputPath = path.resolve(buildOptions.outputPath);
+ const absoluteAssetOutput = path.resolve(absoluteOutputPath, asset.output);
+ const outputRelativeOutput = path.relative(absoluteOutputPath, absoluteAssetOutput);
+
+ if (outputRelativeOutput.startsWith('..') || path.isAbsolute(outputRelativeOutput)) {
+
+ const projectRelativeOutput = path.relative(projectRoot, absoluteAssetOutput);
+ if (projectRelativeOutput.startsWith('..') || path.isAbsolute(projectRelativeOutput)) {
+ const message = 'An asset cannot be written to a location outside the project.';
+ throw new SilentError(message);
+ }
+
if (!asset.allowOutsideOutDir) {
const message = 'An asset cannot be written to a location outside of the output path. '
+ 'You can override this message by setting the `allowOutsideOutDir` '
@@ -113,7 +111,8 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
}
// Prevent asset configurations from reading files outside of the project.
- if (!asset.input.startsWith(projectRoot)) {
+ const projectRelativeInput = path.relative(projectRoot, asset.input);
+ if (projectRelativeInput.startsWith('..') || path.isAbsolute(projectRelativeInput)) {
const message = 'An asset cannot be read from a location outside the project.';
throw new SilentError(message);
}
@@ -128,11 +127,15 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
asset.glob = asset.glob + '/**/*';
}
+ // Escape the input in case it has special charaters and use to make glob absolute
+ const escapedInput = asset.input
+ .replace(/[\\|\*|\?|\!|\(|\)|\[|\]|\{|\}]/g, (substring) => `\\${substring}`);
+
return {
context: asset.input,
to: asset.output,
from: {
- glob: asset.glob,
+ glob: path.resolve(escapedInput, asset.glob),
dot: true
}
};
diff --git a/packages/@angular/cli/models/webpack-configs/production.ts b/packages/@angular/cli/models/webpack-configs/production.ts
index fddc7f373861..5b6be4dfd754 100644
--- a/packages/@angular/cli/models/webpack-configs/production.ts
+++ b/packages/@angular/cli/models/webpack-configs/production.ts
@@ -5,6 +5,7 @@ import * as semver from 'semver';
import { stripIndent } from 'common-tags';
import { LicenseWebpackPlugin } from 'license-webpack-plugin';
import { PurifyPlugin } from '@angular-devkit/build-optimizer';
+import { BundleBudgetPlugin } from '../../plugins/bundle-budget';
import { StaticAssetPlugin } from '../../plugins/static-asset';
import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin';
import { WebpackConfigOptions } from '../webpack-config';
@@ -47,7 +48,7 @@ export function getProdConfig(wco: WebpackConfigOptions) {
const swVersion = JSON.parse(swPackageJson)['version'];
const isLegacySw = semver.satisfies(swVersion, OLD_SW_VERSION);
- const isModernSw = semver.satisfies(swVersion, NEW_SW_VERSION);
+ const isModernSw = semver.gte(swVersion, NEW_SW_VERSION);
if (!isLegacySw && !isModernSw) {
throw new Error(stripIndent`
@@ -108,6 +109,10 @@ export function getProdConfig(wco: WebpackConfigOptions) {
}
}
+ extraPlugins.push(new BundleBudgetPlugin({
+ budgets: appConfig.budgets
+ }));
+
if (buildOptions.extractLicenses) {
extraPlugins.push(new LicenseWebpackPlugin({
pattern: /^(MIT|ISC|BSD.*)$/,
@@ -117,7 +122,13 @@ export function getProdConfig(wco: WebpackConfigOptions) {
}));
}
- const uglifyCompressOptions: any = {};
+ const uglifyCompressOptions: any = {
+ // Disabled because of an issue with Mapbox GL when using the Webpack node global and UglifyJS:
+ // https://github.com/mapbox/mapbox-gl-js/issues/4359#issuecomment-303880888
+ // https://github.com/angular/angular-cli/issues/5804
+ // https://github.com/angular/angular-cli/pull/7931
+ typeofs : false
+ };
if (buildOptions.buildOptimizer) {
// This plugin must be before webpack.optimize.UglifyJsPlugin.
@@ -136,21 +147,26 @@ export function getProdConfig(wco: WebpackConfigOptions) {
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
+ ...extraPlugins,
+ // Uglify should be the last plugin as PurifyPlugin needs to be before it.
new UglifyJSPlugin({
sourceMap: buildOptions.sourcemaps,
+ parallel: true,
uglifyOptions: {
ecma: wco.supportES2015 ? 6 : 5,
warnings: buildOptions.verbose,
ie8: false,
- mangle: true,
+ mangle: {
+ safari10: true,
+ },
compress: uglifyCompressOptions,
output: {
ascii_only: true,
- comments: false
+ comments: false,
+ webkit: true,
},
}
}),
- ...extraPlugins
]
};
}
diff --git a/packages/@angular/cli/models/webpack-configs/styles.ts b/packages/@angular/cli/models/webpack-configs/styles.ts
index 83392219cbdb..d85cf3df0ff1 100644
--- a/packages/@angular/cli/models/webpack-configs/styles.ts
+++ b/packages/@angular/cli/models/webpack-configs/styles.ts
@@ -6,12 +6,12 @@ import {
import { extraEntryParser, getOutputHashFormat } from './utils';
import { WebpackConfigOptions } from '../webpack-config';
import { pluginArgs, postcssArgs } from '../../tasks/eject';
+import { CleanCssWebpackPlugin } from '../../plugins/cleancss-webpack-plugin';
-const cssnano = require('cssnano');
const postcssUrl = require('postcss-url');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
-const customProperties = require('postcss-custom-properties');
+const postcssImports = require('postcss-import');
/**
* Enumerate loaders and their dependencies from this file to let the dependency validator
@@ -29,6 +29,12 @@ const customProperties = require('postcss-custom-properties');
* require('sass-loader')
*/
+interface PostcssUrlAsset {
+ url: string;
+ hash: string;
+ absolutePath: string;
+}
+
export function getStylesConfig(wco: WebpackConfigOptions) {
const { projectRoot, buildOptions, appConfig } = wco;
@@ -36,64 +42,96 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
const entryPoints: { [key: string]: string[] } = {};
const globalStylePaths: string[] = [];
const extraPlugins: any[] = [];
- // style-loader does not support sourcemaps without absolute publicPath, so it's
- // better to disable them when not extracting css
- // https://github.com/webpack-contrib/style-loader#recommended-configuration
- const cssSourceMap = buildOptions.extractCss && buildOptions.sourcemaps;
+ const cssSourceMap = buildOptions.sourcemaps;
+ // Maximum resource size to inline (KiB)
+ const maximumInlineSize = 10;
// Minify/optimize css in production.
const minimizeCss = buildOptions.target === 'production';
// Convert absolute resource URLs to account for base-href and deploy-url.
const baseHref = wco.buildOptions.baseHref || '';
const deployUrl = wco.buildOptions.deployUrl || '';
- const postcssPluginCreator = function() {
- // safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193
- const importantCommentRe = /@preserve|@license|[@#]\s*source(?:Mapping)?URL|^!/i;
- const minimizeOptions = {
- autoprefixer: false, // full pass with autoprefixer is run separately
- safe: true,
- mergeLonghand: false, // version 3+ should be safe; cssnano currently uses 2.x
- discardComments : { remove: (comment: string) => !importantCommentRe.test(comment) }
- };
-
+ const postcssPluginCreator = function(loader: webpack.loader.LoaderContext) {
return [
- postcssUrl({
- url: (URL: { url: string }) => {
- const { url } = URL;
- // Only convert root relative URLs, which CSS-Loader won't process into require().
- if (!url.startsWith('/') || url.startsWith('//')) {
- return URL.url;
- }
+ postcssImports({
+ resolve: (url: string, context: string) => {
+ return new Promise((resolve, reject) => {
+ if (url && url.startsWith('~')) {
+ url = url.substr(1);
+ }
+ loader.resolve(context, url, (err: Error, result: string) => {
+ if (err) {
+ reject(err);
+ return;
+ }
- if (deployUrl.match(/:\/\//)) {
- // If deployUrl contains a scheme, ignore baseHref use deployUrl as is.
- return `${deployUrl.replace(/\/$/, '')}${url}`;
- } else if (baseHref.match(/:\/\//)) {
- // If baseHref contains a scheme, include it as is.
- return baseHref.replace(/\/$/, '') +
- `/${deployUrl}/${url}`.replace(/\/\/+/g, '/');
- } else {
- // Join together base-href, deploy-url and the original URL.
- // Also dedupe multiple slashes into single ones.
- return `/${baseHref}/${deployUrl}/${url}`.replace(/\/\/+/g, '/');
- }
+ resolve(result);
+ });
+ });
+ },
+ load: (filename: string) => {
+ return new Promise((resolve, reject) => {
+ loader.fs.readFile(filename, (err: Error, data: Buffer) => {
+ if (err) {
+ reject(err);
+ return;
+ }
+
+ const content = data.toString();
+ resolve(content);
+ });
+ });
}
}),
+ postcssUrl({
+ filter: ({ url }: PostcssUrlAsset) => url.startsWith('~'),
+ url: ({ url }: PostcssUrlAsset) => {
+ const fullPath = path.join(projectRoot, 'node_modules', url.substr(1));
+ return path.relative(loader.context, fullPath).replace(/\\/g, '/');
+ }
+ }),
+ postcssUrl([
+ {
+ // Only convert root relative URLs, which CSS-Loader won't process into require().
+ filter: ({ url }: PostcssUrlAsset) => url.startsWith('/') && !url.startsWith('//'),
+ url: ({ url }: PostcssUrlAsset) => {
+ if (deployUrl.match(/:\/\//) || deployUrl.startsWith('/')) {
+ // If deployUrl is absolute or root relative, ignore baseHref & use deployUrl as is.
+ return `${deployUrl.replace(/\/$/, '')}${url}`;
+ } else if (baseHref.match(/:\/\//)) {
+ // If baseHref contains a scheme, include it as is.
+ return baseHref.replace(/\/$/, '') +
+ `/${deployUrl}/${url}`.replace(/\/\/+/g, '/');
+ } else {
+ // Join together base-href, deploy-url and the original URL.
+ // Also dedupe multiple slashes into single ones.
+ return `/${baseHref}/${deployUrl}/${url}`.replace(/\/\/+/g, '/');
+ }
+ }
+ },
+ {
+ // TODO: inline .cur if not supporting IE (use browserslist to check)
+ filter: (asset: PostcssUrlAsset) => {
+ return maximumInlineSize > 0 && !asset.hash && !asset.absolutePath.endsWith('.cur');
+ },
+ url: 'inline',
+ // NOTE: maxSize is in KB
+ maxSize: maximumInlineSize,
+ fallback: 'rebase',
+ },
+ { url: 'rebase' },
+ ]),
autoprefixer(),
- customProperties({ preserve: true})
- ].concat(
- minimizeCss ? [cssnano(minimizeOptions)] : []
- );
+ ];
};
(postcssPluginCreator as any)[postcssArgs] = {
variableImports: {
'autoprefixer': 'autoprefixer',
'postcss-url': 'postcssUrl',
- 'cssnano': 'cssnano',
- 'postcss-custom-properties': 'customProperties'
+ 'postcss-import': 'postcssImports',
},
- variables: { minimizeCss, baseHref, deployUrl }
+ variables: { minimizeCss, baseHref, deployUrl, projectRoot, maximumInlineSize }
};
// determine hashing format
@@ -164,7 +202,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
loader: 'css-loader',
options: {
sourceMap: cssSourceMap,
- importLoaders: 1
+ import: false,
}
},
{
@@ -172,7 +210,8 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
options: {
// A non-function property is required to workaround a webpack option handling bug
ident: 'postcss',
- plugins: postcssPluginCreator
+ plugins: postcssPluginCreator,
+ sourceMap: cssSourceMap
}
}
];
@@ -219,6 +258,10 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
extraPlugins.push(new SuppressExtractedTextChunksWebpackPlugin());
}
+ if (minimizeCss) {
+ extraPlugins.push(new CleanCssWebpackPlugin({ sourceMap: cssSourceMap }));
+ }
+
return {
entry: entryPoints,
module: { rules },
diff --git a/packages/@angular/cli/models/webpack-configs/utils.ts b/packages/@angular/cli/models/webpack-configs/utils.ts
index 8679dc5a81cf..99a6b7b07271 100644
--- a/packages/@angular/cli/models/webpack-configs/utils.ts
+++ b/packages/@angular/cli/models/webpack-configs/utils.ts
@@ -81,8 +81,8 @@ export function getOutputHashFormat(option: string, length = 20): HashFormat {
const hashFormats: { [option: string]: HashFormat } = {
none: { chunk: '', extract: '', file: '' , script: '' },
media: { chunk: '', extract: '', file: `.[hash:${length}]`, script: '' },
- bundles: { chunk: `.[chunkhash:${length}]`, extract: `.[contenthash:${length}]`, file: '' , script: '.[hash]' },
- all: { chunk: `.[chunkhash:${length}]`, extract: `.[contenthash:${length}]`, file: `.[hash:${length}]`, script: '.[hash]' },
+ bundles: { chunk: `.[chunkhash:${length}]`, extract: `.[contenthash:${length}]`, file: '' , script: `.[hash:${length}]` },
+ all: { chunk: `.[chunkhash:${length}]`, extract: `.[contenthash:${length}]`, file: `.[hash:${length}]`, script: `.[hash:${length}]` },
};
/* tslint:enable:max-line-length */
return hashFormats[option] || hashFormats['none'];
diff --git a/packages/@angular/cli/package.json b/packages/@angular/cli/package.json
index 9de573893fa1..4e4fc1d4bcd5 100644
--- a/packages/@angular/cli/package.json
+++ b/packages/@angular/cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@angular/cli",
- "version": "1.6.0-beta.2",
+ "version": "1.7.0-beta.1",
"description": "CLI tool for Angular",
"main": "lib/cli/index.js",
"trackingCode": "UA-8594346-19",
@@ -27,23 +27,24 @@
},
"homepage": "https://github.com/angular/angular-cli",
"dependencies": {
- "@angular-devkit/build-optimizer": "~0.0.31",
- "@angular-devkit/schematics": "~0.0.34",
+ "@angular-devkit/build-optimizer": "~0.0.41",
+ "@angular-devkit/core": "~0.0.28",
+ "@angular-devkit/schematics": "~0.0.51",
"@ngtools/json-schema": "1.1.0",
- "@ngtools/webpack": "1.9.0-beta.2",
- "@schematics/angular": "~0.1.5",
- "autoprefixer": "^6.5.3",
+ "@ngtools/webpack": "1.10.0-beta.1",
+ "@schematics/angular": "~0.1.16",
+ "autoprefixer": "^7.2.3",
"chalk": "~2.2.0",
- "circular-dependency-plugin": "^3.0.0",
+ "circular-dependency-plugin": "^4.2.1",
+ "clean-css": "^4.1.9",
"common-tags": "^1.3.1",
"copy-webpack-plugin": "^4.1.1",
"core-object": "^3.1.0",
"css-loader": "^0.28.1",
- "cssnano": "^3.10.0",
"denodeify": "^1.2.1",
"ember-cli-string-utils": "^1.0.0",
"exports-loader": "^0.6.3",
- "extract-text-webpack-plugin": "3.0.0",
+ "extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"fs-extra": "^4.0.0",
"glob": "^7.0.3",
@@ -53,39 +54,38 @@
"less-loader": "^4.0.5",
"license-webpack-plugin": "^1.0.0",
"lodash": "^4.11.1",
+ "loader-utils": "1.1.0",
"memory-fs": "^0.4.1",
"minimatch": "^3.0.4",
"node-modules-path": "^1.0.0",
"nopt": "^4.0.1",
"opn": "~5.1.0",
"portfinder": "~1.0.12",
- "postcss-custom-properties": "^6.1.0",
- "postcss-loader": "^2.0.8",
+ "postcss-import": "^11.0.0",
+ "postcss-loader": "^2.0.10",
"postcss-url": "^7.1.2",
"raw-loader": "^0.5.1",
"resolve": "^1.1.7",
"rxjs": "^5.5.2",
- "sass-loader": "^6.0.3",
+ "sass-loader": "^6.0.6",
"semver": "^5.1.0",
"silent-error": "^1.0.0",
"source-map-loader": "^0.2.0",
"source-map-support": "^0.4.1",
- "istanbul-instrumenter-loader": "^2.0.0",
- "style-loader": "^0.13.1",
+ "istanbul-instrumenter-loader": "^3.0.0",
+ "style-loader": "^0.19.1",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1",
- "uglifyjs-webpack-plugin": "1.0.0",
+ "uglifyjs-webpack-plugin": "^1.1.5",
"url-loader": "^0.6.2",
- "webpack": "~3.8.1",
- "webpack-concat-plugin": "1.4.0",
+ "webpack": "~3.10.0",
"webpack-dev-middleware": "~1.12.0",
- "webpack-dev-server": "~2.9.3",
+ "webpack-dev-server": "~2.11.0",
"webpack-merge": "^4.1.0",
"webpack-sources": "^1.0.0",
- "webpack-subresource-integrity": "^1.0.1",
- "zone.js": "^0.8.14"
+ "webpack-subresource-integrity": "^1.0.1"
},
"optionalDependencies": {
- "node-sass": "^4.3.0"
+ "node-sass": "^4.7.2"
}
}
diff --git a/packages/@angular/cli/plugins/bundle-budget.ts b/packages/@angular/cli/plugins/bundle-budget.ts
new file mode 100644
index 000000000000..3ce0b7f77ee0
--- /dev/null
+++ b/packages/@angular/cli/plugins/bundle-budget.ts
@@ -0,0 +1,129 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+import { Budget, calculateBytes, calculateSizes } from '../utilities/bundle-calculator';
+
+interface Thresholds {
+ maximumWarning?: number;
+ maximumError?: number;
+ minimumWarning?: number;
+ minimumError?: number;
+ warningLow?: number;
+ warningHigh?: number;
+ errorLow?: number;
+ errorHigh?: number;
+}
+
+export interface BundleBudgetPluginOptions {
+ budgets: Budget[];
+}
+
+export class BundleBudgetPlugin {
+ constructor(private options: BundleBudgetPluginOptions) {}
+
+ apply(compiler: any): void {
+ const { budgets } = this.options;
+ compiler.plugin('after-emit', (compilation: any, cb: Function) => {
+ if (!budgets || budgets.length === 0) {
+ cb();
+ return;
+ }
+
+ budgets.map(budget => {
+ const thresholds = this.calcualte(budget);
+ return {
+ budget,
+ thresholds,
+ sizes: calculateSizes(budget, compilation)
+ };
+ })
+ .forEach(budgetCheck => {
+ budgetCheck.sizes.forEach(size => {
+ if (budgetCheck.thresholds.maximumWarning) {
+ if (budgetCheck.thresholds.maximumWarning < size.size) {
+ compilation.warnings.push(`budgets, maximum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.maximumError) {
+ if (budgetCheck.thresholds.maximumError < size.size) {
+ compilation.errors.push(`budgets, maximum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.minimumWarning) {
+ if (budgetCheck.thresholds.minimumWarning > size.size) {
+ compilation.warnings.push(`budgets, minimum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.minimumError) {
+ if (budgetCheck.thresholds.minimumError > size.size) {
+ compilation.errors.push(`budgets, minimum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.warningLow) {
+ if (budgetCheck.thresholds.warningLow > size.size) {
+ compilation.warnings.push(`budgets, minimum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.warningHigh) {
+ if (budgetCheck.thresholds.warningHigh < size.size) {
+ compilation.warnings.push(`budgets, maximum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.errorLow) {
+ if (budgetCheck.thresholds.errorLow > size.size) {
+ compilation.errors.push(`budgets, minimum exceeded for ${size.label}.`);
+ }
+ }
+ if (budgetCheck.thresholds.errorHigh) {
+ if (budgetCheck.thresholds.errorHigh < size.size) {
+ compilation.errors.push(`budgets, maximum exceeded for ${size.label}.`);
+ }
+ }
+ });
+
+ });
+ cb();
+ });
+ }
+
+ private calcualte(budget: Budget): Thresholds {
+ let thresholds: Thresholds = {};
+ if (budget.maximumWarning) {
+ thresholds.maximumWarning = calculateBytes(budget.maximumWarning, budget.baseline, 'pos');
+ }
+
+ if (budget.maximumError) {
+ thresholds.maximumError = calculateBytes(budget.maximumError, budget.baseline, 'pos');
+ }
+
+ if (budget.minimumWarning) {
+ thresholds.minimumWarning = calculateBytes(budget.minimumWarning, budget.baseline, 'neg');
+ }
+
+ if (budget.minimumError) {
+ thresholds.minimumError = calculateBytes(budget.minimumError, budget.baseline, 'neg');
+ }
+
+ if (budget.warning) {
+ thresholds.warningLow = calculateBytes(budget.warning, budget.baseline, 'neg');
+ }
+
+ if (budget.warning) {
+ thresholds.warningHigh = calculateBytes(budget.warning, budget.baseline, 'pos');
+ }
+
+ if (budget.error) {
+ thresholds.errorLow = calculateBytes(budget.error, budget.baseline, 'neg');
+ }
+
+ if (budget.error) {
+ thresholds.errorHigh = calculateBytes(budget.error, budget.baseline, 'pos');
+ }
+
+ return thresholds;
+ }
+}
diff --git a/packages/@angular/cli/plugins/cleancss-webpack-plugin.ts b/packages/@angular/cli/plugins/cleancss-webpack-plugin.ts
new file mode 100644
index 000000000000..2b469c0264ba
--- /dev/null
+++ b/packages/@angular/cli/plugins/cleancss-webpack-plugin.ts
@@ -0,0 +1,111 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+import { Compiler } from 'webpack';
+import { RawSource, SourceMapSource } from 'webpack-sources';
+
+const CleanCSS = require('clean-css');
+
+interface Chunk {
+ files: string[];
+}
+
+export interface CleanCssWebpackPluginOptions {
+ sourceMap: boolean;
+}
+
+export class CleanCssWebpackPlugin {
+
+ constructor(private options: Partial = {}) {}
+
+ apply(compiler: Compiler): void {
+ compiler.plugin('compilation', (compilation: any) => {
+ compilation.plugin('optimize-chunk-assets',
+ (chunks: Array, callback: (err?: Error) => void) => {
+
+ const cleancss = new CleanCSS({
+ compatibility: 'ie9',
+ level: 2,
+ inline: false,
+ returnPromise: true,
+ sourceMap: this.options.sourceMap,
+ });
+
+ const files: string[] = [...compilation.additionalChunkAssets];
+
+ chunks.forEach(chunk => {
+ if (chunk.files && chunk.files.length > 0) {
+ files.push(...chunk.files);
+ }
+ });
+
+ const actions = files
+ .filter(file => file.endsWith('.css'))
+ .map(file => {
+ const asset = compilation.assets[file];
+ if (!asset) {
+ return Promise.resolve();
+ }
+
+ let content: string;
+ let map: any;
+ if (asset.sourceAndMap) {
+ const sourceAndMap = asset.sourceAndMap();
+ content = sourceAndMap.source;
+ map = sourceAndMap.map;
+ } else {
+ content = asset.source();
+ }
+
+ if (content.length === 0) {
+ return Promise.resolve();
+ }
+
+ return Promise.resolve()
+ .then(() => cleancss.minify(content, map))
+ .then((output: any) => {
+ let hasWarnings = false;
+ if (output.warnings && output.warnings.length > 0) {
+ compilation.warnings.push(...output.warnings);
+ hasWarnings = true;
+ }
+
+ if (output.errors && output.errors.length > 0) {
+ output.errors
+ .forEach((error: string) => compilation.errors.push(new Error(error)));
+ return;
+ }
+
+ // generally means invalid syntax so bail
+ if (hasWarnings && output.stats.minifiedSize === 0) {
+ return;
+ }
+
+ let newSource;
+ if (output.sourceMap) {
+ newSource = new SourceMapSource(
+ output.styles,
+ file,
+ output.sourceMap.toString(),
+ content,
+ map,
+ );
+ } else {
+ newSource = new RawSource(output.styles);
+ }
+
+ compilation.assets[file] = newSource;
+ });
+ });
+
+ Promise.all(actions)
+ .then(() => callback())
+ .catch(err => callback(err));
+ });
+ });
+ }
+}
diff --git a/packages/@angular/cli/plugins/insert-concat-assets-webpack-plugin.ts b/packages/@angular/cli/plugins/insert-concat-assets-webpack-plugin.ts
deleted file mode 100644
index 039c0afafd00..000000000000
--- a/packages/@angular/cli/plugins/insert-concat-assets-webpack-plugin.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// Add assets from `ConcatPlugin` to index.html.
-
-
-export class InsertConcatAssetsWebpackPlugin {
- // Priority list of where to insert asset.
- private insertAfter = [
- /polyfills(\.[0-9a-f]{20})?\.bundle\.js/,
- /inline(\.[0-9a-f]{20})?\.bundle\.js/,
- ];
-
- constructor(private entryNames: string[]) { }
-
- apply(compiler: any): void {
- compiler.plugin('compilation', (compilation: any) => {
- compilation.plugin('html-webpack-plugin-before-html-generation',
- (htmlPluginData: any, callback: any) => {
-
- const fileNames = this.entryNames.map((entryName) => {
- const fileName = htmlPluginData.assets.webpackConcat
- && htmlPluginData.assets.webpackConcat[entryName];
-
- if (!fileName) {
- // Something went wrong and the asset was not correctly added.
- throw new Error(`Cannot find file for ${entryName} script.`);
- }
-
- if (htmlPluginData.assets.publicPath) {
- if (htmlPluginData.assets.publicPath.endsWith('/')) {
- return htmlPluginData.assets.publicPath + fileName;
- }
- return htmlPluginData.assets.publicPath + '/' + fileName;
- }
- return fileName;
- });
-
- let insertAt = 0;
-
- // TODO: try to figure out if there are duplicate bundle names when adding and throw
- for (let el of this.insertAfter) {
- const jsIdx = htmlPluginData.assets.js.findIndex((js: string) => js.match(el));
- if (jsIdx !== -1) {
- insertAt = jsIdx + 1;
- break;
- }
- }
-
- htmlPluginData.assets.js.splice(insertAt, 0, ...fileNames);
- callback(null, htmlPluginData);
- });
- });
- }
-}
diff --git a/packages/@angular/cli/plugins/karma.ts b/packages/@angular/cli/plugins/karma.ts
index ad893a5fadb5..3f813871912d 100644
--- a/packages/@angular/cli/plugins/karma.ts
+++ b/packages/@angular/cli/plugins/karma.ts
@@ -53,7 +53,7 @@ const init: any = (config: any, emitter: any, customFileHandlers: any) => {
environment: 'dev',
codeCoverage: false,
sourcemaps: true,
- progress: true,
+ progress: process.stdout.isTTY === true,
preserveSymlinks: false,
}, config.angularCli);
diff --git a/packages/@angular/cli/plugins/scripts-webpack-plugin.ts b/packages/@angular/cli/plugins/scripts-webpack-plugin.ts
new file mode 100644
index 000000000000..e65056264bfa
--- /dev/null
+++ b/packages/@angular/cli/plugins/scripts-webpack-plugin.ts
@@ -0,0 +1,140 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+import { Compiler, loader } from 'webpack';
+import { CachedSource, ConcatSource, OriginalSource, RawSource, Source } from 'webpack-sources';
+import { interpolateName } from 'loader-utils';
+import * as path from 'path';
+
+const Chunk = require('webpack/lib/Chunk');
+
+export interface ScriptsWebpackPluginOptions {
+ name: string;
+ sourceMap: boolean;
+ scripts: string[];
+ filename: string;
+ basePath: string;
+}
+
+interface ScriptOutput {
+ filename: string;
+ source: CachedSource;
+}
+
+export class ScriptsWebpackPlugin {
+ private _lastBuildTime?: number;
+ private _cachedOutput?: ScriptOutput;
+
+ constructor(private options: Partial = {}) {}
+
+ shouldSkip(compilation: any, scripts: string[]): boolean {
+ if (this._lastBuildTime == undefined) {
+ this._lastBuildTime = Date.now();
+ return false;
+ }
+
+ for (let i = 0; i < scripts.length; i++) {
+ const scriptTime = compilation.fileTimestamps[scripts[i]];
+ if (!scriptTime || scriptTime > this._lastBuildTime) {
+ this._lastBuildTime = Date.now();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private _insertOutput(compilation: any, { filename, source }: ScriptOutput, cached = false) {
+ const chunk = new Chunk();
+ chunk.rendered = !cached;
+ chunk.id = this.options.name;
+ chunk.ids = [chunk.id];
+ chunk.name = this.options.name;
+ chunk.isInitial = () => true;
+ chunk.files.push(filename);
+
+ compilation.chunks.push(chunk);
+ compilation.assets[filename] = source;
+ }
+
+ apply(compiler: Compiler): void {
+ if (!this.options.scripts || this.options.scripts.length === 0) {
+ return;
+ }
+
+ const scripts = this.options.scripts
+ .filter(script => !!script)
+ .map(script => path.resolve(this.options.basePath || '', script));
+
+ compiler.plugin('this-compilation', (compilation: any) => {
+ compilation.plugin('additional-assets', (callback: (err?: Error) => void) => {
+ if (this.shouldSkip(compilation, scripts)) {
+ if (this._cachedOutput) {
+ this._insertOutput(compilation, this._cachedOutput, true);
+ }
+ compilation.fileDependencies.push(...scripts);
+
+ callback();
+
+ return;
+ }
+
+ const sourceGetters = scripts.map(fullPath => {
+ return new Promise((resolve, reject) => {
+ compilation.inputFileSystem.readFile(fullPath, (err: Error, data: Buffer) => {
+ if (err) {
+ reject(err);
+ return;
+ }
+
+ const content = data.toString();
+
+ let source;
+ if (this.options.sourceMap) {
+ // TODO: Look for source map file (for '.min' scripts, etc.)
+
+ let adjustedPath = fullPath;
+ if (this.options.basePath) {
+ adjustedPath = path.relative(this.options.basePath, fullPath);
+ }
+ source = new OriginalSource(content, adjustedPath);
+ } else {
+ source = new RawSource(content);
+ }
+
+ resolve(source);
+ });
+ });
+ });
+
+ Promise.all(sourceGetters)
+ .then(sources => {
+ const concatSource = new ConcatSource();
+ sources.forEach(source => {
+ concatSource.add(source);
+ concatSource.add('\n;');
+ });
+
+ const combinedSource = new CachedSource(concatSource);
+ const filename = interpolateName(
+ { resourcePath: 'scripts.js' } as loader.LoaderContext,
+ this.options.filename,
+ { content: combinedSource.source() },
+ );
+
+ const output = { filename, source: combinedSource };
+ this._insertOutput(compilation, output);
+ this._cachedOutput = output;
+ compilation.fileDependencies.push(...scripts);
+
+ callback();
+ })
+ .catch((err: Error) => callback(err));
+ });
+ });
+ }
+}
diff --git a/packages/@angular/cli/plugins/webpack.ts b/packages/@angular/cli/plugins/webpack.ts
index a51f71eff8d4..c834b494a23d 100644
--- a/packages/@angular/cli/plugins/webpack.ts
+++ b/packages/@angular/cli/plugins/webpack.ts
@@ -1,6 +1,8 @@
// Exports the webpack plugins we use internally.
export { BaseHrefWebpackPlugin } from '../lib/base-href-webpack/base-href-webpack-plugin';
+export { CleanCssWebpackPlugin, CleanCssWebpackPluginOptions } from './cleancss-webpack-plugin';
export { GlobCopyWebpackPlugin, GlobCopyWebpackPluginOptions } from './glob-copy-webpack-plugin';
-export { InsertConcatAssetsWebpackPlugin } from './insert-concat-assets-webpack-plugin';
+export { BundleBudgetPlugin, BundleBudgetPluginOptions } from './bundle-budget';
export { NamedLazyChunksWebpackPlugin } from './named-lazy-chunks-webpack-plugin';
+export { ScriptsWebpackPlugin, ScriptsWebpackPluginOptions } from './scripts-webpack-plugin';
export { SuppressExtractedTextChunksWebpackPlugin } from './suppress-entry-chunks-webpack-plugin';
diff --git a/packages/@angular/cli/tasks/e2e.ts b/packages/@angular/cli/tasks/e2e.ts
index 40228aafeb83..f73ab5a0d36e 100644
--- a/packages/@angular/cli/tasks/e2e.ts
+++ b/packages/@angular/cli/tasks/e2e.ts
@@ -59,6 +59,10 @@ export const E2eTask = Task.extend({
additionalProtractorConfig['specs'] = e2eTaskOptions.specs;
}
+ if (e2eTaskOptions.suite && e2eTaskOptions.suite.length !== 0) {
+ additionalProtractorConfig['suite'] = e2eTaskOptions.suite;
+ }
+
if (e2eTaskOptions.webdriverUpdate) {
// The webdriver-manager update command can only be accessed via a deep import.
const webdriverDeepImport = 'webdriver-manager/built/lib/cmds/update';
diff --git a/packages/@angular/cli/tasks/eject.ts b/packages/@angular/cli/tasks/eject.ts
index a782ac21e640..9f9ac2b171c4 100644
--- a/packages/@angular/cli/tasks/eject.ts
+++ b/packages/@angular/cli/tasks/eject.ts
@@ -7,6 +7,7 @@ import { getAppFromConfig } from '../utilities/app-utils';
import { EjectTaskOptions } from '../commands/eject';
import { NgCliWebpackConfig } from '../models/webpack-config';
import { CliConfig } from '../models/config';
+import { usesServiceWorker } from '../utilities/service-worker';
import { stripBom } from '../utilities/strip-bom';
import { AotPlugin, AngularCompilerPlugin } from '@ngtools/webpack';
import { PurifyPlugin } from '@angular-devkit/build-optimizer';
@@ -25,7 +26,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
const SubresourceIntegrityPlugin = require('webpack-subresource-integrity');
const SilentError = require('silent-error');
const CircularDependencyPlugin = require('circular-dependency-plugin');
-const ConcatPlugin = require('webpack-concat-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const Task = require('../ember-cli/lib/models/task');
@@ -90,6 +90,13 @@ class JsonWebpackSerializer {
};
}
+ private _bundleBudgetPluginSerialize(value: any): any {
+ let budgets = value.options.budgets;
+ return {
+ budgets
+ };
+ }
+
private _insertConcatAssetsWebpackPluginSerialize(value: any): any {
return value.entryNames;
}
@@ -155,19 +162,7 @@ class JsonWebpackSerializer {
}
private _licenseWebpackPlugin(plugin: any) {
- return plugin.options;
- }
-
- private _concatPlugin(plugin: any) {
- const options = plugin.settings;
- if (!options || !options.filesToConcat) {
- return options;
- }
-
- const filesToConcat = options.filesToConcat
- .map((file: string) => path.relative(process.cwd(), file));
-
- return { ...options, filesToConcat };
+ return this._licenseReplacer(plugin.options);
}
private _uglifyjsPlugin(plugin: any) {
@@ -202,7 +197,9 @@ class JsonWebpackSerializer {
this._addImport('webpack.optimize', 'ModuleConcatenationPlugin');
break;
case angularCliPlugins.BaseHrefWebpackPlugin:
+ case angularCliPlugins.CleanCssWebpackPlugin:
case angularCliPlugins.NamedLazyChunksWebpackPlugin:
+ case angularCliPlugins.ScriptsWebpackPlugin:
case angularCliPlugins.SuppressExtractedTextChunksWebpackPlugin:
this._addImport('@angular/cli/plugins/webpack', plugin.constructor.name);
break;
@@ -210,6 +207,10 @@ class JsonWebpackSerializer {
args = this._globCopyWebpackPluginSerialize(plugin);
this._addImport('@angular/cli/plugins/webpack', 'GlobCopyWebpackPlugin');
break;
+ case angularCliPlugins.BundleBudgetPlugin:
+ args = this._bundleBudgetPluginSerialize(plugin);
+ this._addImport('@angular/cli/plugins/webpack', 'BundleBudgetPlugin');
+ break;
case angularCliPlugins.InsertConcatAssetsWebpackPlugin:
args = this._insertConcatAssetsWebpackPluginSerialize(plugin);
this._addImport('@angular/cli/plugins/webpack', 'InsertConcatAssetsWebpackPlugin');
@@ -248,10 +249,6 @@ class JsonWebpackSerializer {
args = this._licenseWebpackPlugin(plugin);
this._addImport('license-webpack-plugin', 'LicenseWebpackPlugin');
break;
- case ConcatPlugin:
- args = this._concatPlugin(plugin);
- this.variableImports['webpack-concat-plugin'] = 'ConcatPlugin';
- break;
case UglifyJSPlugin:
args = this._uglifyjsPlugin(plugin);
this.variableImports['uglifyjs-webpack-plugin'] = 'UglifyJsPlugin';
@@ -409,6 +406,13 @@ class JsonWebpackSerializer {
});
}
+ private _licenseReplacer(value: any) {
+ return Object.assign({}, value, {
+ outputTemplate: this._relativePath(
+ 'process.cwd()', path.relative(this._root, value.outputTemplate))
+ });
+ }
+
private _replacer(_key: string, value: any) {
if (value === undefined) {
return value;
@@ -484,7 +488,6 @@ class JsonWebpackSerializer {
}
}
-
export default Task.extend({
run: function (runTaskOptions: EjectTaskOptions) {
const project = this.project;
@@ -521,31 +524,35 @@ export default Task.extend({
.then((packageJson: string) => JSON.parse(packageJson))
.then((packageJson: any) => {
const scripts = packageJson['scripts'];
- if (scripts['build'] && scripts['build'] !== 'ng build' && !force) {
- throw new SilentError(oneLine`
- Your package.json scripts must not contain a build script as it will be overwritten.
- `);
- }
- if (scripts['start'] && scripts['start'] !== 'ng serve' && !force) {
- throw new SilentError(oneLine`
- Your package.json scripts must not contain a start script as it will be overwritten.
- `);
- }
- if (scripts['pree2e'] && scripts['pree2e'] !== pree2eNpmScript && !force) {
- throw new SilentError(oneLine`
- Your package.json scripts must not contain a pree2e script as it will be
- overwritten.
- `);
- }
- if (scripts['e2e'] && scripts['e2e'] !== 'ng e2e' && !force) {
- throw new SilentError(oneLine`
- Your package.json scripts must not contain a e2e script as it will be overwritten.
- `);
- }
- if (scripts['test'] && scripts['test'] !== 'ng test' && !force) {
- throw new SilentError(oneLine`
- Your package.json scripts must not contain a test script as it will be overwritten.
- `);
+ if (!force) {
+ if (scripts['build']
+ && scripts['build'] != 'ng build'
+ && scripts['build'] != 'ng build --prod') {
+ throw new SilentError(oneLine`
+ Your package.json scripts must not contain a build script as it will be overwritten.
+ `);
+ }
+ if (scripts['start'] && scripts['start'] !== 'ng serve') {
+ throw new SilentError(oneLine`
+ Your package.json scripts must not contain a start script as it will be overwritten.
+ `);
+ }
+ if (scripts['pree2e'] && scripts['pree2e'] !== pree2eNpmScript) {
+ throw new SilentError(oneLine`
+ Your package.json scripts must not contain a pree2e script as it will be
+ overwritten.
+ `);
+ }
+ if (scripts['e2e'] && scripts['e2e'] !== 'ng e2e') {
+ throw new SilentError(oneLine`
+ Your package.json scripts must not contain a e2e script as it will be overwritten.
+ `);
+ }
+ if (scripts['test'] && scripts['test'] !== 'ng test') {
+ throw new SilentError(oneLine`
+ Your package.json scripts must not contain a test script as it will be overwritten.
+ `);
+ }
}
packageJson['scripts']['build'] = 'webpack';
@@ -554,6 +561,16 @@ export default Task.extend({
packageJson['scripts']['pree2e'] = pree2eNpmScript;
packageJson['scripts']['e2e'] = 'protractor ./protractor.conf.js';
+ if (!!appConfig.serviceWorker && runTaskOptions.target === 'production' &&
+ usesServiceWorker(project.root) && !!runTaskOptions.serviceWorker) {
+ packageJson['scripts']['build'] += ' && npm run sw-config && npm run sw-copy';
+ packageJson['scripts']['sw-config'] = `ngsw-config ${outputPath} src/ngsw-config.json`;
+ packageJson['scripts']['sw-copy'] =
+ `cpx node_modules/@angular/service-worker/ngsw-worker.js ${outputPath}`;
+
+ packageJson['devDependencies']['cpx'] = '^1.5.0';
+ }
+
// Add new dependencies based on our dependencies.
const ourPackageJson = require('../package.json');
if (!packageJson['devDependencies']) {
@@ -567,13 +584,13 @@ export default Task.extend({
'webpack',
'autoprefixer',
'css-loader',
- 'cssnano',
'exports-loader',
'file-loader',
'html-webpack-plugin',
'json-loader',
'karma-sourcemap-loader',
'less-loader',
+ 'postcss-import',
'postcss-loader',
'postcss-url',
'raw-loader',
@@ -584,7 +601,6 @@ export default Task.extend({
'stylus-loader',
'url-loader',
'circular-dependency-plugin',
- 'webpack-concat-plugin',
'copy-webpack-plugin',
'uglifyjs-webpack-plugin',
].forEach((packageName: string) => {
diff --git a/packages/@angular/cli/tasks/lint.ts b/packages/@angular/cli/tasks/lint.ts
index 576a2d49d035..4b747ac72bdb 100644
--- a/packages/@angular/cli/tasks/lint.ts
+++ b/packages/@angular/cli/tasks/lint.ts
@@ -177,7 +177,7 @@ function getFilesToLint(
let programFiles = linter.getFileNames(program);
if (ignore && ignore.length > 0) {
- const ignoreMatchers = ignore.map(pattern => new Minimatch(pattern));
+ const ignoreMatchers = ignore.map(pattern => new Minimatch(pattern, { dot: true }));
programFiles = programFiles
.filter(file => !ignoreMatchers.some(matcher => matcher.match(file)));
diff --git a/packages/@angular/cli/tasks/render-universal.ts b/packages/@angular/cli/tasks/render-universal.ts
new file mode 100644
index 000000000000..01e3bc1d5eb2
--- /dev/null
+++ b/packages/@angular/cli/tasks/render-universal.ts
@@ -0,0 +1,33 @@
+import { requireProjectModule } from '../utilities/require-project-module';
+import { join } from 'path';
+
+const fs = require('fs');
+const Task = require('../ember-cli/lib/models/task');
+
+export interface RenderUniversalTaskOptions {
+ inputIndexPath: string;
+ route: string;
+ serverOutDir: string;
+ outputIndexPath: string;
+}
+
+export default Task.extend({
+ run: function(options: RenderUniversalTaskOptions): Promise {
+ requireProjectModule(this.project.root, 'zone.js/dist/zone-node');
+
+ const renderModuleFactory =
+ requireProjectModule(this.project.root, '@angular/platform-server').renderModuleFactory;
+
+ // Get the main bundle from the server build's output directory.
+ const serverDir = fs.readdirSync(options.serverOutDir);
+ const serverMainBundle = serverDir
+ .filter((file: string) => /main\.(?:[a-zA-Z0-9]{20}\.)?bundle\.js/.test(file))[0];
+ const serverBundlePath = join(options.serverOutDir, serverMainBundle);
+ const AppServerModuleNgFactory = require(serverBundlePath).AppServerModuleNgFactory;
+
+ const index = fs.readFileSync(options.inputIndexPath, 'utf8');
+ // Render to HTML and overwrite the client index file.
+ return renderModuleFactory(AppServerModuleNgFactory, {document: index, url: options.route})
+ .then((html: string) => fs.writeFileSync(options.outputIndexPath, html));
+ }
+});
diff --git a/packages/@angular/cli/tasks/schematic-get-help-output.ts b/packages/@angular/cli/tasks/schematic-get-help-output.ts
index 5b3e2b2171f4..2bdd9c054d34 100644
--- a/packages/@angular/cli/tasks/schematic-get-help-output.ts
+++ b/packages/@angular/cli/tasks/schematic-get-help-output.ts
@@ -1,7 +1,7 @@
import chalk from 'chalk';
const Task = require('../ember-cli/lib/models/task');
-const { cyan, grey } = chalk;
+const { cyan, green, grey } = chalk;
export interface SchematicGetHelpOptions {
collectionName: string;
@@ -40,7 +40,7 @@ export default Task.extend({
}), nonSchematicOptions])
.then(([availableOptions, nonSchematicOptions]: [SchematicAvailableOptions[], any[]]) => {
const output: string[] = [];
- [...(nonSchematicOptions || []), ...availableOptions]
+ [...(nonSchematicOptions || []), ...availableOptions || []]
.filter(opt => hiddenOptions.indexOf(opt.name) === -1)
.forEach(opt => {
let text = cyan(` --${opt.name}`);
@@ -63,6 +63,11 @@ export default Task.extend({
output.push(grey(` aliases: ${aliasText}`));
}
});
+ if (availableOptions === null) {
+ output.push(green('This schematic accept additional options, but did not provide '
+ + 'documentation.'));
+ }
+
return output;
});
}
diff --git a/packages/@angular/cli/tasks/schematic-get-options.ts b/packages/@angular/cli/tasks/schematic-get-options.ts
index 77c300150b11..44c28e580270 100644
--- a/packages/@angular/cli/tasks/schematic-get-options.ts
+++ b/packages/@angular/cli/tasks/schematic-get-options.ts
@@ -18,7 +18,7 @@ export interface SchematicAvailableOptions {
}
export default Task.extend({
- run: function (options: SchematicGetOptions): Promise {
+ run: function (options: SchematicGetOptions): Promise {
const collectionName = options.collectionName ||
CliConfig.getValue('defaults.schematics.collection');
@@ -26,10 +26,15 @@ export default Task.extend({
const schematic = getSchematic(collection, options.schematicName);
+ if (!schematic.description.schemaJson) {
+ return Promise.resolve(null);
+ }
+
const properties = schematic.description.schemaJson.properties;
const keys = Object.keys(properties);
const availableOptions = keys
.map(key => ({...properties[key], ...{name: stringUtils.dasherize(key)}}))
+ .filter(opt => opt.visible !== false)
.map(opt => {
let type;
const schematicType = opt.type;
diff --git a/packages/@angular/cli/tasks/schematic-run.ts b/packages/@angular/cli/tasks/schematic-run.ts
index f3cddcc7c49b..b49ddee6fa71 100644
--- a/packages/@angular/cli/tasks/schematic-run.ts
+++ b/packages/@angular/cli/tasks/schematic-run.ts
@@ -168,12 +168,14 @@ export default Task.extend({
});
function prepOptions(schematic: Schematic<{}, {}>, options: SchematicOptions): SchematicOptions {
+ const properties = (schematic.description).schemaJson
+ ? (schematic.description).schemaJson.properties
+ : options;
- const properties = (schematic.description).schemaJson.properties;
const keys = Object.keys(properties);
if (['component', 'c', 'directive', 'd'].indexOf(schematic.description.name) !== -1) {
options.prefix = (options.prefix === 'false' || options.prefix === '')
- ? '' : options.prefix;
+ ? undefined : options.prefix;
}
let preppedOptions = {
diff --git a/packages/@angular/cli/tasks/serve.ts b/packages/@angular/cli/tasks/serve.ts
index 18274a5c92c5..698a8fc8211e 100644
--- a/packages/@angular/cli/tasks/serve.ts
+++ b/packages/@angular/cli/tasks/serve.ts
@@ -73,8 +73,8 @@ export default Task.extend({
}
const serveDefaults = {
- // default deployUrl to '' on serve to prevent the default from .angular-cli.json
- deployUrl: ''
+ deployUrl: appConfig.deployUrl || '',
+ baseHref: appConfig.baseHref || '',
};
serveTaskOptions = Object.assign({}, serveDefaults, serveTaskOptions);
@@ -108,18 +108,18 @@ export default Task.extend({
if (serveTaskOptions.liveReload) {
// This allows for live reload of page when changes are made to repo.
- // https://webpack.github.io/docs/webpack-dev-server.html#inline-mode
+ // https://webpack.js.org/configuration/dev-server/#devserver-inline
let entryPoints = [
`webpack-dev-server/client?${clientAddress}`
];
if (serveTaskOptions.hmr) {
- const webpackHmrLink = 'https://webpack.github.io/docs/hot-module-replacement.html';
+ const webpackHmrLink = 'https://webpack.js.org/guides/hot-module-replacement';
ui.writeLine(oneLine`
${yellow('NOTICE')} Hot Module Replacement (HMR) is enabled for the dev server.
`);
- const showWarning = CliConfig.fromGlobal().get('warnings.hmrWarning');
+ const showWarning = CliConfig.fromProject().get('warnings.hmrWarning');
if (showWarning) {
ui.writeLine(' The project will still live reload when HMR is enabled,');
ui.writeLine(' but to take advantage of HMR additional application code is required');
@@ -127,7 +127,7 @@ export default Task.extend({
ui.writeLine(` See ${chalk.blue(webpackHmrLink)}`);
ui.writeLine(' for information on working with HMR for Webpack.');
ui.writeLine(oneLine`
- ${yellow('To disable this warning use "ng set --global warnings.hmrWarning=false"')}
+ ${yellow('To disable this warning use "ng set warnings.hmrWarning=false"')}
`);
}
entryPoints.push('webpack/hot/dev-server');
@@ -193,7 +193,8 @@ export default Task.extend({
if (!servePath && servePath !== '') {
const defaultServePath =
findDefaultServePath(serveTaskOptions.baseHref, serveTaskOptions.deployUrl);
- if (defaultServePath == null) {
+ const showWarning = CliConfig.fromProject().get('warnings.servePathDefault');
+ if (defaultServePath == null && showWarning) {
ui.writeLine(oneLine`
${chalk.yellow('WARNING')} --deploy-url and/or --base-href contain
unsupported values for ng serve. Default serve path of '/' used.
diff --git a/packages/@angular/cli/upgrade/version.ts b/packages/@angular/cli/upgrade/version.ts
index 0fcf5f226642..9234eb3b1908 100644
--- a/packages/@angular/cli/upgrade/version.ts
+++ b/packages/@angular/cli/upgrade/version.ts
@@ -169,7 +169,9 @@ export class Version {
const versionCombos = [
{ compiler: '>=2.3.1 <3.0.0', typescript: '>=2.0.2 <2.3.0' },
{ compiler: '>=4.0.0 <5.0.0', typescript: '>=2.1.0 <2.4.0' },
- { compiler: '>=5.0.0 <6.0.0', typescript: '>=2.4.2 <2.5.0' }
+ { compiler: '>=5.0.0 <5.1.0', typescript: '>=2.4.2 <2.5.0' },
+ { compiler: '>=5.1.0 <5.2.0', typescript: '>=2.4.2 <2.6.0' },
+ { compiler: '>=5.2.0 <6.0.0', typescript: '>=2.4.2 <2.7.0' }
];
const currentCombo = versionCombos.find((combo) => satisfies(compilerVersion, combo.compiler));
diff --git a/packages/@angular/cli/utilities/bundle-calculator.ts b/packages/@angular/cli/utilities/bundle-calculator.ts
new file mode 100644
index 000000000000..6a048f6f51ea
--- /dev/null
+++ b/packages/@angular/cli/utilities/bundle-calculator.ts
@@ -0,0 +1,204 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+export type BudgetType = 'all' | 'allScript' | 'any' | 'anyScript' | 'bundle' | 'initial';
+
+export interface Budget {
+ /**
+ * The type of budget
+ */
+ type: BudgetType;
+ /**
+ * The name of the bundle
+ */
+ name?: string;
+ /**
+ * The baseline size for comparison.
+ */
+ baseline?: string;
+ /**
+ * The maximum threshold for warning relative to the baseline.
+ */
+ maximumWarning?: string;
+ /**
+ * The maximum threshold for error relative to the baseline.
+ */
+ maximumError?: string;
+ /**
+ * The minimum threshold for warning relative to the baseline.
+ */
+ minimumWarning?: string;
+ /**
+ * The minimum threshold for error relative to the baseline.
+ */
+ minimumError?: string;
+ /**
+ * The threshold for warning relative to the baseline (min & max).
+ */
+ warning?: string;
+ /**
+ * The threshold for error relative to the baseline (min & max).
+ */
+ error?: string;
+}
+
+export interface Compilation {
+ assets: any;
+ chunks: any[];
+ warnings: string[];
+ errors: string[];
+}
+
+export interface Size {
+ size: number;
+ label?: string;
+}
+
+export function calculateSizes(budget: Budget, compilation: Compilation): Size[] {
+ const calculatorMap = {
+ all: AllCalculator,
+ allScript: AllScriptCalculator,
+ any: AnyCalculator,
+ anyScript: AnyScriptCalculator,
+ bundle: BundleCalculator,
+ initial: InitialCalculator,
+ };
+ const ctor = calculatorMap[budget.type];
+ const calculator = new ctor(budget, compilation);
+ return calculator.calculate();
+}
+
+export abstract class Calculator {
+ constructor (protected budget: Budget, protected compilation: Compilation) {}
+
+ abstract calculate(): Size[];
+}
+
+/**
+ * A named bundle.
+ */
+class BundleCalculator extends Calculator {
+ calculate() {
+ const size: number = this.compilation.chunks
+ .filter(chunk => chunk.name === this.budget.name)
+ .reduce((files, chunk) => [...files, ...chunk.files], [])
+ .map((file: string) => this.compilation.assets[file].size())
+ .reduce((total: number, size: number) => total + size, 0);
+ return [{size, label: this.budget.name}];
+ }
+}
+
+/**
+ * The sum of all initial chunks (marked as initial by webpack).
+ */
+class InitialCalculator extends Calculator {
+ calculate() {
+ const initialChunks = this.compilation.chunks.filter(chunk => chunk.isInitial);
+ const size: number = initialChunks
+ .reduce((files, chunk) => [...files, ...chunk.files], [])
+ .map((file: string) => this.compilation.assets[file].size())
+ .reduce((total: number, size: number) => total + size, 0);
+ return [{size, label: 'initial'}];
+ }
+}
+
+/**
+ * The sum of all the scripts portions.
+ */
+class AllScriptCalculator extends Calculator {
+ calculate() {
+ const size: number = Object.keys(this.compilation.assets)
+ .filter(key => /\.js$/.test(key))
+ .map(key => this.compilation.assets[key])
+ .map(asset => asset.size())
+ .reduce((total: number, size: number) => total + size, 0);
+ return [{size, label: 'total scripts'}];
+ }
+}
+
+/**
+ * All scripts and assets added together.
+ */
+class AllCalculator extends Calculator {
+ calculate() {
+ const size: number = Object.keys(this.compilation.assets)
+ .map(key => this.compilation.assets[key].size())
+ .reduce((total: number, size: number) => total + size, 0);
+ return [{size, label: 'total'}];
+ }
+}
+
+/**
+ * Any script, individually.
+ */
+class AnyScriptCalculator extends Calculator {
+ calculate() {
+ return Object.keys(this.compilation.assets)
+ .filter(key => /\.js$/.test(key))
+ .map(key => {
+ const asset = this.compilation.assets[key];
+ return {
+ size: asset.size(),
+ label: key
+ };
+ });
+ }
+}
+
+/**
+ * Any script or asset (images, css, etc).
+ */
+class AnyCalculator extends Calculator {
+ calculate() {
+ return Object.keys(this.compilation.assets)
+ .map(key => {
+ const asset = this.compilation.assets[key];
+ return {
+ size: asset.size(),
+ label: key
+ };
+ });
+ }
+}
+
+/**
+ * Calculate the bytes given a string value.
+ */
+export function calculateBytes(val: string, baseline?: string, factor?: ('pos' | 'neg')): number {
+ if (/^\d+$/.test(val)) {
+ return parseFloat(val);
+ }
+
+ if (/^(\d+)%$/.test(val)) {
+ return calculatePercentBytes(val, baseline, factor);
+ }
+
+ const multiplier = getMultiplier(val);
+
+ const numberVal = parseFloat(val.replace(/((k|m|M|)b?)$/, ''));
+ const baselineVal = baseline ? parseFloat(baseline.replace(/((k|m|M|)b?)$/, '')) : 0;
+ const baselineMultiplier = baseline ? getMultiplier(baseline) : 1;
+ const factorMultiplier = factor ? (factor === 'pos' ? 1 : -1) : 1;
+
+ return numberVal * multiplier + baselineVal * baselineMultiplier * factorMultiplier;
+}
+
+function getMultiplier(val?: string): number {
+ if (/^(\d+)b?$/.test(val)) {
+ return 1;
+ } else if (/^(\d+)kb$/.test(val)) {
+ return 1000;
+ } else if (/^(\d+)(m|M)b$/.test(val)) {
+ return 1000 * 1000;
+ }
+}
+
+function calculatePercentBytes(val: string, baseline?: string, factor?: ('pos' | 'neg')): number {
+ const baselineBytes = calculateBytes(baseline);
+ const percentage = parseFloat(val.replace(/%/g, ''));
+ return baselineBytes + baselineBytes * percentage / 100 * (factor === 'pos' ? 1 : -1);
+}
diff --git a/packages/@angular/cli/utilities/dynamic-path-parser.ts b/packages/@angular/cli/utilities/dynamic-path-parser.ts
index b6795b928a09..7835939eb27d 100644
--- a/packages/@angular/cli/utilities/dynamic-path-parser.ts
+++ b/packages/@angular/cli/utilities/dynamic-path-parser.ts
@@ -12,11 +12,11 @@ export interface DynamicPathOptions {
export function dynamicPathParser(options: DynamicPathOptions) {
const projectRoot = options.project.root;
- const sourceDir = options.appConfig.root.replace('/', path.sep);
+ const sourceDir = options.appConfig.root.replace(/\//g, path.sep);
const p = options.appConfig.appRoot === undefined
? 'app'
- : options.appConfig.appRoot.replace('/', path.sep);
+ : options.appConfig.appRoot.replace(/\//g, path.sep);
const appRoot = path.join(sourceDir, p);
const cwd = process.env.PWD;
diff --git a/packages/@angular/cli/utilities/package-chunk-sort.ts b/packages/@angular/cli/utilities/package-chunk-sort.ts
index a7841aeb544c..67322ff20156 100644
--- a/packages/@angular/cli/utilities/package-chunk-sort.ts
+++ b/packages/@angular/cli/utilities/package-chunk-sort.ts
@@ -15,6 +15,10 @@ export function packageChunkSort(appConfig: any) {
extraEntryParser(appConfig.styles, './', 'styles').forEach(pushExtraEntries);
}
+ if (appConfig.scripts) {
+ extraEntryParser(appConfig.scripts, './', 'scripts').forEach(pushExtraEntries);
+ }
+
entryPoints.push(...['vendor', 'main']);
function sort(left: any, right: any) {
diff --git a/packages/@angular/cli/utilities/schematics.ts b/packages/@angular/cli/utilities/schematics.ts
index f94067a8e42c..ff468fba4880 100644
--- a/packages/@angular/cli/utilities/schematics.ts
+++ b/packages/@angular/cli/utilities/schematics.ts
@@ -5,16 +5,19 @@
* require('@schematics/angular')
*/
+import { schema } from '@angular-devkit/core';
import {
Collection,
Engine,
Schematic,
SchematicEngine,
+ formats,
} from '@angular-devkit/schematics';
import {
FileSystemCollectionDesc,
FileSystemSchematicDesc,
- NodeModulesEngineHost
+ NodeModulesEngineHost,
+ validateOptionsWithSchema
} from '@angular-devkit/schematics/tools';
import { SchemaClassFactory } from '@ngtools/json-schema';
import 'rxjs/add/operator/concatMap';
@@ -26,6 +29,10 @@ const engineHost = new NodeModulesEngineHost();
const engine: Engine
= new SchematicEngine(engineHost);
+// Add support for schemaJson.
+const registry = new schema.CoreSchemaRegistry(formats.standardFormats);
+engineHost.registerOptionsTransform(validateOptionsWithSchema(registry));
+
export function getEngineHost() {
return engineHost;
diff --git a/packages/@angular/cli/utilities/service-worker/index.ts b/packages/@angular/cli/utilities/service-worker/index.ts
index 8d8b93ac7f55..0d167b632776 100644
--- a/packages/@angular/cli/utilities/service-worker/index.ts
+++ b/packages/@angular/cli/utilities/service-worker/index.ts
@@ -1,11 +1,11 @@
import { Filesystem } from '@angular/service-worker/config';
-import { stripIndent } from 'common-tags';
+import { oneLine } from 'common-tags';
import * as crypto from 'crypto';
import * as fs from 'fs';
import * as path from 'path';
import * as semver from 'semver';
-export const NEW_SW_VERSION = '>= 5.0.0-rc.0';
+export const NEW_SW_VERSION = '5.0.0-rc.0';
class CliFilesystem implements Filesystem {
constructor(private base: string) {}
@@ -58,7 +58,7 @@ export function usesServiceWorker(projectRoot: string): boolean {
const swPackageJson = fs.readFileSync(`${swModule}/package.json`).toString();
const swVersion = JSON.parse(swPackageJson)['version'];
- return semver.satisfies(swVersion, NEW_SW_VERSION);
+ return semver.gte(swVersion, NEW_SW_VERSION);
}
export function augmentAppWithServiceWorker(projectRoot: string, appRoot: string,
@@ -71,9 +71,9 @@ export function augmentAppWithServiceWorker(projectRoot: string, appRoot: string
const configPath = path.resolve(appRoot, 'ngsw-config.json');
if (!fs.existsSync(configPath)) {
- throw new Error(stripIndent`Expected to find an ngsw-config.json configuration file in the
- application root. Either provide one or disable Service Worker
- build support in angular-cli.json.`);
+ throw new Error(oneLine`Error: Expected to find an ngsw-config.json configuration
+ file in the ${appRoot} folder. Either provide one or disable Service Worker
+ in .angular-cli.json.`);
}
const config = fs.readFileSync(configPath, 'utf8');
diff --git a/packages/@angular/cli/utilities/stats.ts b/packages/@angular/cli/utilities/stats.ts
index be9001019aca..c58f4b0bcc17 100644
--- a/packages/@angular/cli/utilities/stats.ts
+++ b/packages/@angular/cli/utilities/stats.ts
@@ -26,11 +26,9 @@ export function statsToString(json: any, statsConfig: any) {
const g = (x: string) => colors ? bold(green(x)) : x;
const y = (x: string) => colors ? bold(yellow(x)) : x;
- return rs(stripIndents`
- Date: ${w(new Date().toISOString())}
- Hash: ${w(json.hash)}
- Time: ${w('' + json.time)}ms
- ${json.chunks.map((chunk: any) => {
+ const changedChunksStats = json.chunks
+ .filter((chunk: any) => chunk.rendered)
+ .map((chunk: any) => {
const asset = json.assets.filter((x: any) => x.name == chunk.files[0])[0];
const size = asset ? ` ${_formatSize(asset.size)}` : '';
const files = chunk.files.join(', ');
@@ -41,8 +39,24 @@ export function statsToString(json: any, statsConfig: any) {
.join('');
return `chunk {${y(chunk.id)}} ${g(files)}${names}${size} ${initial}${flags}`;
- }).join('\n')}
- `);
+ });
+
+ const unchangedChunkNumber = json.chunks.length - changedChunksStats.length;
+
+ if (unchangedChunkNumber > 0) {
+ return rs(stripIndents`
+ Date: ${w(new Date().toISOString())} • Hash: ${w(json.hash)} • Time: ${w('' + json.time)}ms
+ ${unchangedChunkNumber} unchanged chunks
+ ${changedChunksStats.join('\n')}
+ `);
+ } else {
+ return rs(stripIndents`
+ Date: ${w(new Date().toISOString())}
+ Hash: ${w(json.hash)}
+ Time: ${w('' + json.time)}ms
+ ${changedChunksStats.join('\n')}
+ `);
+ }
}
export function statsWarningsToString(json: any, statsConfig: any) {
diff --git a/packages/@angular/cli/webpack-custom-typings.d.ts b/packages/@angular/cli/webpack-custom-typings.d.ts
deleted file mode 100644
index b57841eb3c17..000000000000
--- a/packages/@angular/cli/webpack-custom-typings.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as webpack from 'webpack';
-
-declare module 'webpack' {
- export class NamedChunksPlugin {
- constructor(nameResolver: (chunk: any) => string | null);
- }
- export class HashedModuleIdsPlugin {
- constructor();
- }
-}
diff --git a/packages/@ngtools/webpack/README.md b/packages/@ngtools/webpack/README.md
index fc3fc2529462..7163bc3bd2ca 100644
--- a/packages/@ngtools/webpack/README.md
+++ b/packages/@ngtools/webpack/README.md
@@ -64,7 +64,7 @@ The loader works with webpack plugin to compile your TypeScript. It's important
* `basePath`. Optional. The root to use by the compiler to resolve file paths. By default, use the `tsConfigPath` root.
* `entryModule`. Optional if specified in `angularCompilerOptions`. The path and classname of the main application module. This follows the format `path/to/file#ClassName`.
* `mainPath`. Optional if `entryModule` is specified. The `main.ts` file containing the bootstrap code. The plugin will use AST to determine the `entryModule`.
-* `skipCodeGeneration`. Optional, defaults to false. Disable code generation and do not refactor the code to bootstrap. This replaces `templateUrl: "string"` with `template: require("string")` (and similar for styles) to allow for webpack to properly link the resources. Only available in `AotPlugin`.
+* `skipCodeGeneration`. Optional, defaults to false. Disable code generation and do not refactor the code to bootstrap. This replaces `templateUrl: "string"` with `template: require("string")` (and similar for styles) to allow for webpack to properly link the resources.
* `typeChecking`. Optional, defaults to true. Enable type checking through your application. This will slow down compilation, but show syntactic and semantic errors in webpack. Only available in `AotPlugin`.
* `exclude`. Optional. Extra files to exclude from TypeScript compilation. Not supported with `AngularCompilerPlugin`.
* `sourceMap`. Optional. Include sourcemaps.
diff --git a/packages/@ngtools/webpack/package.json b/packages/@ngtools/webpack/package.json
index 3b7d315e8138..4b4b155b98ba 100644
--- a/packages/@ngtools/webpack/package.json
+++ b/packages/@ngtools/webpack/package.json
@@ -1,6 +1,6 @@
{
"name": "@ngtools/webpack",
- "version": "1.9.0-beta.2",
+ "version": "1.10.0-beta.1",
"description": "Webpack plugin that AoT compiles your Angular components and modules.",
"main": "./src/index.js",
"typings": "src/index.d.ts",
@@ -21,7 +21,7 @@
},
"homepage": "https://github.com/angular/angular-cli/tree/master/packages/@ngtools/webpack",
"engines": {
- "node": ">= 4.1.0",
+ "node": ">= 6.9.0",
"npm": ">= 3.0.0"
},
"dependencies": {
@@ -31,7 +31,8 @@
"enhanced-resolve": "^3.1.0",
"magic-string": "^0.22.3",
"semver": "^5.3.0",
- "source-map": "^0.5.6"
+ "source-map": "^0.5.6",
+ "webpack-sources": "^1.1.0"
},
"peerDependencies": {
"webpack": "^2.2.0 || ^3.0.0"
diff --git a/packages/@ngtools/webpack/src/angular_compiler_plugin.ts b/packages/@ngtools/webpack/src/angular_compiler_plugin.ts
index f0c8342791d6..9aa58816a62e 100644
--- a/packages/@ngtools/webpack/src/angular_compiler_plugin.ts
+++ b/packages/@ngtools/webpack/src/angular_compiler_plugin.ts
@@ -19,6 +19,7 @@ import {
import { resolveEntryModuleFromMain } from './entry_resolver';
import {
replaceBootstrap,
+ replaceServerBootstrap,
exportNgFactory,
exportLazyModuleMap,
removeDecorators,
@@ -27,7 +28,7 @@ import {
replaceResources,
} from './transformers';
import { time, timeEnd } from './benchmark';
-import { InitMessage, UpdateMessage } from './type_checker';
+import { InitMessage, UpdateMessage, AUTO_START_ARG } from './type_checker';
import { gatherDiagnostics, hasErrors } from './gather_diagnostics';
import {
CompilerCliIsSupported,
@@ -106,8 +107,9 @@ export class AngularCompilerPlugin implements Tapable {
// Webpack plugin.
private _firstRun = true;
private _donePromise: Promise | null;
- private _compiler: any = null;
- private _compilation: any = null;
+ private _normalizedLocale: string;
+ private _warnings: (string | Error)[] = [];
+ private _errors: (string | Error)[] = [];
// TypeChecker process.
private _forkTypeChecker = true;
@@ -133,9 +135,9 @@ export class AngularCompilerPlugin implements Tapable {
if (!this._entryModule) {
return undefined;
}
- const splitted = this._entryModule.split('#');
+ const splitted = this._entryModule.split(/(#[a-zA-Z_]([\w]+))$/);
const path = splitted[0];
- const className = splitted[1] || 'default';
+ const className = !!splitted[1] ? splitted[1].substring(1) : 'default';
return { path, className };
}
@@ -173,7 +175,7 @@ export class AngularCompilerPlugin implements Tapable {
}
this._rootNames = config.rootNames.concat(...this._singleFileIncludes);
- this._compilerOptions = config.options;
+ this._compilerOptions = { ...config.options, ...options.compilerOptions };
this._basePath = config.options.basePath;
// Overwrite outDir so we can find generated files next to their .ts origin in compilerHost.
@@ -225,7 +227,9 @@ export class AngularCompilerPlugin implements Tapable {
this._compilerOptions.i18nOutFormat = options.i18nOutFormat;
}
if (options.locale !== undefined) {
- this._compilerOptions.i18nInLocale = this._validateLocale(options.locale);
+ this._compilerOptions.i18nInLocale = options.locale;
+ this._compilerOptions.i18nOutLocale = options.locale;
+ this._normalizedLocale = this._validateLocale(options.locale);
}
if (options.missingTranslation !== undefined) {
this._compilerOptions.i18nInMissingTranslations =
@@ -445,7 +449,7 @@ export class AngularCompilerPlugin implements Tapable {
if (moduleKey in this._lazyRoutes) {
if (this._lazyRoutes[moduleKey] !== modulePath) {
// Found a duplicate, this is an error.
- this._compilation.warnings.push(
+ this._warnings.push(
new Error(`Duplicated path in loadChildren detected during a rebuild. `
+ `We will take the latest version detected and override it to save rebuild time. `
+ `You should perform a full build to validate that your routes don't overlap.`)
@@ -463,7 +467,7 @@ export class AngularCompilerPlugin implements Tapable {
const g: any = global;
const typeCheckerFile: string = g['angularCliIsLocal']
? './type_checker_bootstrap.js'
- : './type_checker.js';
+ : './type_checker_worker.js';
const debugArgRegex = /--inspect(?:-brk|-port)?|--debug(?:-brk|-port)/;
@@ -472,21 +476,46 @@ export class AngularCompilerPlugin implements Tapable {
// Workaround for https://github.com/nodejs/node/issues/9435
return !debugArgRegex.test(arg);
});
-
+ // Signal the process to start listening for messages
+ // Solves https://github.com/angular/angular-cli/issues/9071
+ const forkArgs = [AUTO_START_ARG];
const forkOptions: ForkOptions = { execArgv };
- this._typeCheckerProcess = fork(path.resolve(__dirname, typeCheckerFile), [], forkOptions);
+ this._typeCheckerProcess = fork(
+ path.resolve(__dirname, typeCheckerFile),
+ forkArgs,
+ forkOptions);
this._typeCheckerProcess.send(new InitMessage(this._compilerOptions, this._basePath,
this._JitMode, this._rootNames));
// Cleanup.
const killTypeCheckerProcess = () => {
- treeKill(this._typeCheckerProcess.pid, 'SIGTERM');
+ if (this._typeCheckerProcess && this._typeCheckerProcess.pid) {
+ treeKill(this._typeCheckerProcess.pid, 'SIGTERM');
+ this._typeCheckerProcess = undefined;
+ this._forkTypeChecker = false;
+ }
+ };
+
+ // Handle child process exit.
+ const handleChildProcessExit = () => {
+ killTypeCheckerProcess();
+ const msg = 'AngularCompilerPlugin: Forked Type Checker exited unexpectedly. ' +
+ 'Falling back to typechecking on main thread.';
+ this._warnings.push(msg);
+ };
+ this._typeCheckerProcess.once('exit', handleChildProcessExit);
+ this._typeCheckerProcess.once('SIGINT', handleChildProcessExit);
+ this._typeCheckerProcess.once('uncaughtException', handleChildProcessExit);
+
+ // Handle parent process exit.
+ const handleParentProcessExit = () => {
+ killTypeCheckerProcess();
process.exit();
};
- process.once('exit', killTypeCheckerProcess);
- process.once('SIGINT', killTypeCheckerProcess);
- process.once('uncaughtException', killTypeCheckerProcess);
+ process.once('exit', handleParentProcessExit);
+ process.once('SIGINT', handleParentProcessExit);
+ process.once('uncaughtException', handleParentProcessExit);
}
private _updateForkedTypeChecker(rootNames: string[], changedCompilationFiles: string[]) {
@@ -496,8 +525,6 @@ export class AngularCompilerPlugin implements Tapable {
// Registration hook for webpack plugin.
apply(compiler: any) {
- this._compiler = compiler;
-
// Decorate inputFileSystem to serve contents of CompilerHost.
// Use decorated inputFileSystem in watchFileSystem.
compiler.plugin('environment', () => {
@@ -571,7 +598,6 @@ export class AngularCompilerPlugin implements Tapable {
});
compiler.plugin('done', () => {
this._donePromise = null;
- this._compilation = null;
});
// TODO: consider if it's better to remove this plugin and instead make it wait on the
@@ -581,9 +607,9 @@ export class AngularCompilerPlugin implements Tapable {
// Wait for the plugin to be done when requesting `.ts` files directly (entry points), or
// when the issuer is a `.ts` or `.ngfactory.js` file.
compiler.resolvers.normal.plugin('before-resolve', (request: any, cb: () => void) => {
- if (request.request.endsWith('.ts')
- || (request.context.issuer && /\.ts|ngfactory\.js$/.test(request.context.issuer))) {
- this.done!.then(() => cb(), () => cb());
+ if (this.done && (request.request.endsWith('.ts')
+ || (request.context.issuer && /\.ts|ngfactory\.js$/.test(request.context.issuer)))) {
+ this.done.then(() => cb(), () => cb());
} else {
cb();
}
@@ -602,14 +628,13 @@ export class AngularCompilerPlugin implements Tapable {
private _make(compilation: any, cb: (err?: any, request?: any) => void) {
time('AngularCompilerPlugin._make');
- this._compilation = compilation;
this._emitSkipped = true;
- if (this._compilation._ngToolsWebpackPluginInstance) {
+ if (compilation._ngToolsWebpackPluginInstance) {
return cb(new Error('An @ngtools/webpack plugin already exist for this compilation.'));
}
// Set a private variable for this plugin instance.
- this._compilation._ngToolsWebpackPluginInstance = this;
+ compilation._ngToolsWebpackPluginInstance = this;
// Update the resource loader with the new webpack compilation.
this._resourceLoader.update(compilation);
@@ -622,15 +647,24 @@ export class AngularCompilerPlugin implements Tapable {
this._donePromise = Promise.resolve()
.then(() => this._update())
.then(() => {
+ this.pushCompilationErrors(compilation);
timeEnd('AngularCompilerPlugin._make');
cb();
}, (err: any) => {
compilation.errors.push(err.stack);
+ this.pushCompilationErrors(compilation);
timeEnd('AngularCompilerPlugin._make');
cb();
});
}
+ private pushCompilationErrors(compilation: any) {
+ compilation.errors.push(...this._errors);
+ compilation.warnings.push(...this._warnings);
+ this._errors = [];
+ this._warnings = [];
+ }
+
private _makeTransformers() {
const isAppPath = (fileName: string) =>
@@ -652,9 +686,9 @@ export class AngularCompilerPlugin implements Tapable {
// If we have a locale, auto import the locale data file.
// This transform must go before replaceBootstrap because it looks for the entry module
// import, which will be replaced.
- if (this._compilerOptions.i18nInLocale) {
+ if (this._normalizedLocale) {
this._transformers.push(registerLocaleData(isAppPath, getEntryModule,
- this._compilerOptions.i18nInLocale));
+ this._normalizedLocale));
}
if (!this._JitMode) {
@@ -664,7 +698,9 @@ export class AngularCompilerPlugin implements Tapable {
} else if (this._platform === PLATFORM.Server) {
this._transformers.push(exportLazyModuleMap(isMainPath, getLazyRoutes));
if (!this._JitMode) {
- this._transformers.push(exportNgFactory(isMainPath, getEntryModule));
+ this._transformers.push(
+ exportNgFactory(isMainPath, getEntryModule),
+ replaceServerBootstrap(isMainPath, getEntryModule, getTypeChecker));
}
}
}
@@ -728,18 +764,18 @@ export class AngularCompilerPlugin implements Tapable {
if (errors.length > 0) {
const message = formatDiagnostics(errors);
- this._compilation.errors.push(message);
+ this._errors.push(message);
}
if (warnings.length > 0) {
const message = formatDiagnostics(warnings);
- this._compilation.warnings.push(message);
+ this._warnings.push(message);
}
this._emitSkipped = !emitResult || emitResult.emitSkipped;
// Reset changed files on successful compilation.
- if (!this._emitSkipped && this._compilation.errors.length === 0) {
+ if (!this._emitSkipped && this._errors.length === 0) {
this._compilerHost.resetChangedFileTracker();
}
timeEnd('AngularCompilerPlugin._update');
@@ -788,16 +824,20 @@ export class AngularCompilerPlugin implements Tapable {
.map((p) => this._compilerHost.denormalizePath(p));
}
} else {
- // Check if the TS file exists.
- if (fileName.endsWith('.ts') && !this._compilerHost.fileExists(fileName, false)) {
- throw new Error(`${fileName} is not part of the compilation. `
- + `Please make sure it is in your tsconfig via the 'files' or 'include' property.`);
- }
+ // Check if the TS input file and the JS output file exist.
+ if ((fileName.endsWith('.ts') && !this._compilerHost.fileExists(fileName, false))
+ || !this._compilerHost.fileExists(outputFile, false)) {
+ let msg = `${fileName} is missing from the TypeScript compilation. `
+ + `Please make sure it is in your tsconfig via the 'files' or 'include' property.`;
+
+ if (/(\\|\/)node_modules(\\|\/)/.test(fileName)) {
+ msg += '\nThe missing file seems to be part of a third party library. '
+ + 'TS files in published libraries are often a sign of a badly packaged library. '
+ + 'Please open an issue in the library repository to alert its author and ask them '
+ + 'to package the library using the Angular Package Format (https://goo.gl/jB3GVv).';
+ }
- // Check if the output file exists.
- if (!this._compilerHost.fileExists(outputFile, false)) {
- throw new Error(`${fileName} is not part of the compilation output. `
- + `Please check the other error messages for details.`);
+ throw new Error(msg);
}
outputText = this._compilerHost.readFile(outputFile);
diff --git a/packages/@ngtools/webpack/src/compiler_host.ts b/packages/@ngtools/webpack/src/compiler_host.ts
index 33cc54fe46d6..d53ba4a110bb 100644
--- a/packages/@ngtools/webpack/src/compiler_host.ts
+++ b/packages/@ngtools/webpack/src/compiler_host.ts
@@ -97,7 +97,6 @@ export class WebpackCompilerHost implements ts.CompilerHost {
private _delegate: ts.CompilerHost;
private _files: {[path: string]: VirtualFileStats | null} = Object.create(null);
private _directories: {[path: string]: VirtualDirStats | null} = Object.create(null);
- private _cachedResources: {[path: string]: string | undefined} = Object.create(null);
private _changedFiles: {[path: string]: boolean} = Object.create(null);
private _changedDirs: {[path: string]: boolean} = Object.create(null);
@@ -174,8 +173,8 @@ export class WebpackCompilerHost implements ts.CompilerHost {
fileName = this.resolve(fileName);
if (fileName in this._files) {
this._files[fileName] = null;
- this._changedFiles[fileName] = true;
}
+ this._changedFiles[fileName] = true;
}
fileExists(fileName: string, delegate = true): boolean {
@@ -299,22 +298,7 @@ export class WebpackCompilerHost implements ts.CompilerHost {
if (this._resourceLoader) {
// These paths are meant to be used by the loader so we must denormalize them.
const denormalizedFileName = this.denormalizePath(fileName);
- const resourceDeps = this._resourceLoader.getResourceDependencies(denormalizedFileName);
-
- if (this._cachedResources[fileName] === undefined
- || resourceDeps.some((dep) => this._changedFiles[this.resolve(dep)])) {
- return this._resourceLoader.get(denormalizedFileName)
- .then((resource) => {
- // Add resource dependencies to the compiler host file list.
- // This way we can check the changed files list to determine whether to use cache.
- this._resourceLoader.getResourceDependencies(denormalizedFileName)
- .forEach((dep) => this.readFile(dep));
- this._cachedResources[fileName] = resource;
- return resource;
- });
- } else {
- return this._cachedResources[fileName];
- }
+ return this._resourceLoader.get(denormalizedFileName);
} else {
return this.readFile(fileName);
}
diff --git a/packages/@ngtools/webpack/src/index.ts b/packages/@ngtools/webpack/src/index.ts
index 6292e36f96f8..25689f51811d 100644
--- a/packages/@ngtools/webpack/src/index.ts
+++ b/packages/@ngtools/webpack/src/index.ts
@@ -1,12 +1,12 @@
// @ignoreDep typescript
-import { satisfies } from 'semver';
+import { gte } from 'semver';
// Test if typescript is available. This is a hack. We should be using peerDependencies instead
// but can't until we split global and local packages.
// See https://github.com/angular/angular-cli/issues/8107#issuecomment-338185872
try {
const version = require('typescript').version;
- if (!satisfies(version, '^2.0.2')) {
+ if (!gte(version, '2.0.2')) {
throw new Error();
}
} catch (e) {
diff --git a/packages/@ngtools/webpack/src/ngtools_api.ts b/packages/@ngtools/webpack/src/ngtools_api.ts
index e66ea1a71809..074ab5df2fc6 100644
--- a/packages/@ngtools/webpack/src/ngtools_api.ts
+++ b/packages/@ngtools/webpack/src/ngtools_api.ts
@@ -144,8 +144,9 @@ export function CompilerCliIsSupported() {
+ 'Please clean your node_modules and reinstall.');
}
- // Throw if we're neither 2.3.1 or more, nor 4.x.y, nor 5.x.y.
- if (!(version.major == '5'
+ // Throw if we're neither 2.3.1 or more, nor 4.x.y, nor 5.x.y, nor 6.x.y.
+ if (!(version.major == '6'
+ || version.major == '5'
|| version.major == '4'
|| (version.major == '2'
&& (version.minor == '4'
diff --git a/packages/@ngtools/webpack/src/paths-plugin.ts b/packages/@ngtools/webpack/src/paths-plugin.ts
index 8f05721669a9..c3e05b00bd53 100644
--- a/packages/@ngtools/webpack/src/paths-plugin.ts
+++ b/packages/@ngtools/webpack/src/paths-plugin.ts
@@ -124,7 +124,7 @@ export class PathsPlugin implements Tapable {
this._nmf.plugin('before-resolve', (request: NormalModuleFactoryRequest,
callback: Callback) => {
// Only work on TypeScript issuers.
- if (!request.contextInfo.issuer || !request.contextInfo.issuer.endsWith('.ts')) {
+ if (!request.contextInfo.issuer || !request.contextInfo.issuer.match(/\.[jt]s$/)) {
return callback(null, request);
}
diff --git a/packages/@ngtools/webpack/src/resource_loader.ts b/packages/@ngtools/webpack/src/resource_loader.ts
index 38dc019c6fbc..cce18e26fa77 100644
--- a/packages/@ngtools/webpack/src/resource_loader.ts
+++ b/packages/@ngtools/webpack/src/resource_loader.ts
@@ -1,5 +1,6 @@
import * as vm from 'vm';
import * as path from 'path';
+import { RawSource } from 'webpack-sources';
const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
@@ -17,6 +18,7 @@ export class WebpackResourceLoader {
private _context: string;
private _uniqueId = 0;
private _resourceDependencies = new Map();
+ private _cachedResources = new Map();
constructor() {}
@@ -36,6 +38,11 @@ export class WebpackResourceLoader {
throw new Error('WebpackResourceLoader cannot be used without parentCompilation');
}
+ // Simple sanity check.
+ if (filePath.match(/\.[jt]s$/)) {
+ return Promise.reject('Cannot use a JavaScript or TypeScript file for styleUrl.');
+ }
+
const compilerName = `compiler(${this._uniqueId++})`;
const outputOptions = { filename: filePath };
const relativePath = path.relative(this._context || '', filePath);
@@ -48,12 +55,7 @@ export class WebpackResourceLoader {
new LoaderTargetPlugin('node')
);
- // Store the result of the parent compilation before we start the child compilation
- let assetsBeforeCompilation = Object.assign(
- {},
- this._parentCompilation.assets[outputOptions.filename]
- );
-
+ // NOTE: This is not needed with webpack 3.6+
// Fix for "Uncaught TypeError: __webpack_require__(...) is not a function"
// Hot module replacement requires that every child compiler has its own
// cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179
@@ -66,9 +68,30 @@ export class WebpackResourceLoader {
}
});
+ childCompiler.plugin('this-compilation', (compilation: any) => {
+ compilation.plugin('additional-assets', (callback: (err?: Error) => void) => {
+ if (this._cachedResources.has(compilation.fullHash)) {
+ callback();
+ return;
+ }
+
+ const asset = compilation.assets[filePath];
+ if (asset) {
+ this._evaluate({ outputName: filePath, source: asset.source() })
+ .then(output => {
+ compilation.assets[filePath] = new RawSource(output);
+ callback();
+ })
+ .catch(err => callback(err));
+ } else {
+ callback();
+ }
+ });
+ });
+
// Compile and return a promise
return new Promise((resolve, reject) => {
- childCompiler.runAsChild((err: Error, entries: any[], childCompilation: any) => {
+ childCompiler.compile((err: Error, childCompilation: any) => {
// Resolve / reject the promise
if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
const errorDetails = childCompilation.errors.map(function (error: any) {
@@ -78,47 +101,35 @@ export class WebpackResourceLoader {
} else if (err) {
reject(err);
} else {
- // Replace [hash] placeholders in filename
- const outputName = this._parentCompilation.mainTemplate.applyPluginsWaterfall(
- 'asset-path', outputOptions.filename, {
- hash: childCompilation.hash,
- chunk: entries[0]
- });
-
- // Restore the parent compilation to the state like it was before the child compilation.
- Object.keys(childCompilation.assets).forEach((fileName) => {
- // If it wasn't there and it's a source file (absolute path) - delete it.
- if (assetsBeforeCompilation[fileName] === undefined && path.isAbsolute(fileName)) {
- delete this._parentCompilation.assets[fileName];
- } else {
- // Otherwise, add it to the parent compilation.
- this._parentCompilation.assets[fileName] = childCompilation.assets[fileName];
+ Object.keys(childCompilation.assets).forEach(assetName => {
+ if (assetName !== filePath && this._parentCompilation.assets[assetName] == undefined) {
+ this._parentCompilation.assets[assetName] = childCompilation.assets[assetName];
}
});
// Save the dependencies for this resource.
- this._resourceDependencies.set(outputName, childCompilation.fileDependencies);
+ this._resourceDependencies.set(filePath, childCompilation.fileDependencies);
- resolve({
- // Output name.
- outputName,
- // Compiled code.
- source: childCompilation.assets[outputName].source()
- });
+ const compilationHash = childCompilation.fullHash;
+ if (this._cachedResources.has(compilationHash)) {
+ resolve({
+ outputName: filePath,
+ source: this._cachedResources.get(compilationHash),
+ });
+ } else {
+ const source = childCompilation.assets[filePath].source();
+ this._cachedResources.set(compilationHash, source);
+ resolve({ outputName: filePath, source });
+ }
}
});
});
}
- private _evaluate(output: CompilationOutput): Promise {
+ private _evaluate({ outputName, source }: CompilationOutput): Promise {
try {
- const outputName = output.outputName;
- const vmContext = vm.createContext(Object.assign({ require: require }, global));
- const vmScript = new vm.Script(output.source, { filename: outputName });
-
- // Evaluate code and cast to string
- let evaluatedSource: string;
- evaluatedSource = vmScript.runInContext(vmContext);
+ // Evaluate code
+ const evaluatedSource = vm.runInNewContext(source, undefined, { filename: outputName });
if (typeof evaluatedSource == 'string') {
return Promise.resolve(evaluatedSource);
@@ -132,6 +143,6 @@ export class WebpackResourceLoader {
get(filePath: string): Promise {
return this._compile(filePath)
- .then((result: CompilationOutput) => this._evaluate(result));
+ .then((result: CompilationOutput) => result.source);
}
}
diff --git a/packages/@ngtools/webpack/src/transformers/elide_imports.ts b/packages/@ngtools/webpack/src/transformers/elide_imports.ts
index a12bb030f77b..d1cd5b640c34 100644
--- a/packages/@ngtools/webpack/src/transformers/elide_imports.ts
+++ b/packages/@ngtools/webpack/src/transformers/elide_imports.ts
@@ -99,7 +99,11 @@ export function elideImports(
.forEach((id) => {
if (removedSymbolMap.has(id.text)) {
const symbol = removedSymbolMap.get(id.text);
- if (typeChecker.getSymbolAtLocation(id) === symbol.symbol) {
+
+ // Check if the symbol is the same or if it is a named export.
+ // Named exports don't have the same symbol but will have the same name.
+ if ((id.parent && id.parent.kind === ts.SyntaxKind.ExportSpecifier)
+ || typeChecker.getSymbolAtLocation(id) === symbol.symbol) {
symbol.all.push(id);
}
}
diff --git a/packages/@ngtools/webpack/src/transformers/index.ts b/packages/@ngtools/webpack/src/transformers/index.ts
index 4ee76368978c..e523cc7782e8 100644
--- a/packages/@ngtools/webpack/src/transformers/index.ts
+++ b/packages/@ngtools/webpack/src/transformers/index.ts
@@ -4,6 +4,7 @@ export * from './make_transform';
export * from './insert_import';
export * from './elide_imports';
export * from './replace_bootstrap';
+export * from './replace_server_bootstrap';
export * from './export_ngfactory';
export * from './export_lazy_module_map';
export * from './register_locale_data';
diff --git a/packages/@ngtools/webpack/src/transformers/make_transform.ts b/packages/@ngtools/webpack/src/transformers/make_transform.ts
index ae6befae01bf..c2f6ed85eb59 100644
--- a/packages/@ngtools/webpack/src/transformers/make_transform.ts
+++ b/packages/@ngtools/webpack/src/transformers/make_transform.ts
@@ -129,11 +129,18 @@ function visitEachChildWorkaround(node: ts.Node, visitor: ts.Visitor,
}
-// If TS sees an empty decorator array, it will still emit a `__decorate` call.
-// This seems to be a TS bug.
+// 1) If TS sees an empty decorator array, it will still emit a `__decorate` call.
+// This seems to be a TS bug.
+// 2) Also ensure nodes with modified decorators have parents
+// built in TS transformers assume certain nodes have parents (fixed in TS 2.7+)
function cleanupDecorators(node: ts.Node) {
- if (node.decorators && node.decorators.length == 0) {
- node.decorators = undefined;
+ if (node.decorators) {
+ if (node.decorators.length == 0) {
+ node.decorators = undefined;
+ } else if (node.parent == undefined) {
+ const originalNode = ts.getParseTreeNode(node);
+ node.parent = originalNode.parent;
+ }
}
ts.forEachChild(node, node => cleanupDecorators(node));
diff --git a/packages/@ngtools/webpack/src/transformers/remove_decorators.spec.ts b/packages/@ngtools/webpack/src/transformers/remove_decorators.spec.ts
index 3fbfe4ad7203..fedf80298ca3 100644
--- a/packages/@ngtools/webpack/src/transformers/remove_decorators.spec.ts
+++ b/packages/@ngtools/webpack/src/transformers/remove_decorators.spec.ts
@@ -76,6 +76,54 @@ describe('@ngtools/webpack transformers', () => {
expect(oneLine`${result}`).toEqual(oneLine`${output}`);
});
+ it('should keep other decorators on class member', () => {
+ const input = stripIndent`
+ import { Component, HostListener } from '@angular/core';
+ import { AnotherDecorator } from 'another-lib';
+
+ @Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
+ })
+ export class AppComponent {
+ title = 'app';
+
+ @HostListener('document:keydown.escape')
+ @AnotherDecorator()
+ onEscape() {
+ console.log('run');
+ }
+ }
+ `;
+ const output = stripIndent`
+ import * as tslib_1 from "tslib";
+ import { AnotherDecorator } from 'another-lib';
+
+ export class AppComponent {
+ constructor() {
+ this.title = 'app';
+ }
+
+ onEscape() {
+ console.log('run');
+ }
+ }
+ tslib_1.__decorate([
+ AnotherDecorator()
+ ], AppComponent.prototype, "onEscape", null);
+ `;
+
+ const { program, compilerHost } = createTypescriptContext(input);
+ const transformer = removeDecorators(
+ () => true,
+ () => program.getTypeChecker(),
+ );
+ const result = transformTypescript(undefined, [transformer], program, compilerHost);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${output}`);
+ });
+
it('should remove imports for identifiers within the decorator', () => {
const input = stripIndent`
import { Component } from '@angular/core';
@@ -111,7 +159,7 @@ describe('@ngtools/webpack transformers', () => {
it('should not remove imports from types that are still used', () => {
const input = stripIndent`
- import { Component, EventEmitter } from '@angular/core';
+ import { Component, ChangeDetectionStrategy, EventEmitter } from '@angular/core';
@Component({
selector: 'app-root',
@@ -123,9 +171,11 @@ describe('@ngtools/webpack transformers', () => {
notify: EventEmitter = new EventEmitter();
title = 'app';
}
+
+ export { ChangeDetectionStrategy };
`;
const output = stripIndent`
- import { EventEmitter } from '@angular/core';
+ import { ChangeDetectionStrategy, EventEmitter } from '@angular/core';
export class AppComponent {
constructor() {
@@ -133,6 +183,8 @@ describe('@ngtools/webpack transformers', () => {
this.title = 'app';
}
}
+
+ export { ChangeDetectionStrategy };
`;
const { program, compilerHost } = createTypescriptContext(input);
diff --git a/packages/@ngtools/webpack/src/transformers/replace_resources.spec.ts b/packages/@ngtools/webpack/src/transformers/replace_resources.spec.ts
index 0382d746c96f..d3c454e00d33 100644
--- a/packages/@ngtools/webpack/src/transformers/replace_resources.spec.ts
+++ b/packages/@ngtools/webpack/src/transformers/replace_resources.spec.ts
@@ -41,6 +41,43 @@ describe('@ngtools/webpack transformers', () => {
expect(oneLine`${result}`).toEqual(oneLine`${output}`);
});
+ it('should replace resources with backticks', () => {
+ const input = stripIndent`
+ import { Component } from '@angular/core';
+
+ @Component({
+ selector: 'app-root',
+ templateUrl: \`./app.component.html\`,
+ styleUrls: [\`./app.component.css\`, \`./app.component.2.css\`]
+ })
+ export class AppComponent {
+ title = 'app';
+ }
+ `;
+ const output = stripIndent`
+ import * as tslib_1 from "tslib";
+ import { Component } from '@angular/core';
+ let AppComponent = class AppComponent {
+ constructor() {
+ this.title = 'app';
+ }
+ };
+ AppComponent = tslib_1.__decorate([
+ Component({
+ selector: 'app-root',
+ template: require("./app.component.html"),
+ styles: [require("./app.component.css"), require("./app.component.2.css")]
+ })
+ ], AppComponent);
+ export { AppComponent };
+ `;
+
+ const transformer = replaceResources(() => true);
+ const result = transformTypescript(input, [transformer]);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${output}`);
+ });
+
it('should not replace resources if shouldTransform returns false', () => {
const input = stripIndent`
import { Component } from '@angular/core';
diff --git a/packages/@ngtools/webpack/src/transformers/replace_resources.ts b/packages/@ngtools/webpack/src/transformers/replace_resources.ts
index 7d206e809b19..875ee464856e 100644
--- a/packages/@ngtools/webpack/src/transformers/replace_resources.ts
+++ b/packages/@ngtools/webpack/src/transformers/replace_resources.ts
@@ -131,7 +131,10 @@ function _getContentOfKeyLiteral(node?: ts.Node): string | null {
}
function _getResourceRequest(element: ts.Expression, sourceFile: ts.SourceFile) {
- if (element.kind == ts.SyntaxKind.StringLiteral) {
+ if (
+ element.kind === ts.SyntaxKind.StringLiteral ||
+ element.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral
+ ) {
const url = (element as ts.StringLiteral).text;
// If the URL does not start with ./ or ../, prepends ./ to it.
return `${/^\.?\.\//.test(url) ? '' : './'}${url}`;
diff --git a/packages/@ngtools/webpack/src/transformers/replace_server_bootstrap.spec.ts b/packages/@ngtools/webpack/src/transformers/replace_server_bootstrap.spec.ts
new file mode 100644
index 000000000000..5ca49b0e2ab3
--- /dev/null
+++ b/packages/@ngtools/webpack/src/transformers/replace_server_bootstrap.spec.ts
@@ -0,0 +1,215 @@
+import { oneLine, stripIndent } from 'common-tags';
+import { createTypescriptContext, transformTypescript } from './ast_helpers';
+import { replaceServerBootstrap } from './replace_server_bootstrap';
+
+describe('@ngtools/webpack transformers', () => {
+ describe('replace_server_bootstrap', () => {
+ it('should replace bootstrap', () => {
+ const input = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { platformDynamicServer } from '@angular/platform-server';
+
+ import { AppModule } from './app/app.module';
+ import { environment } from './environments/environment';
+
+ if (environment.production) {
+ enableProdMode();
+ }
+
+ platformDynamicServer().bootstrapModule(AppModule);
+ `;
+
+ // tslint:disable:max-line-length
+ const output = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { environment } from './environments/environment';
+
+ import * as __NgCli_bootstrap_1 from "./app/app.module.ngfactory";
+ import * as __NgCli_bootstrap_2 from "@angular/platform-server";
+
+ if (environment.production) {
+ enableProdMode();
+ }
+ __NgCli_bootstrap_2.platformServer().bootstrapModuleFactory(__NgCli_bootstrap_1.AppModuleNgFactory);
+ `;
+ // tslint:enable:max-line-length
+
+ const { program, compilerHost } = createTypescriptContext(input);
+ const transformer = replaceServerBootstrap(
+ () => true,
+ () => ({ path: '/project/src/app/app.module', className: 'AppModule' }),
+ () => program.getTypeChecker(),
+ );
+ const result = transformTypescript(undefined, [transformer], program, compilerHost);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${output}`);
+ });
+
+ it('should replace renderModule', () => {
+ const input = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { renderModule } from '@angular/platform-server';
+
+ import { AppModule } from './app/app.module';
+ import { environment } from './environments/environment';
+
+ if (environment.production) {
+ enableProdMode();
+ }
+
+ renderModule(AppModule, {
+ document: ' ',
+ url: '/'
+ });
+ `;
+
+ // tslint:disable:max-line-length
+ const output = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { environment } from './environments/environment';
+
+ import * as __NgCli_bootstrap_1 from "./app/app.module.ngfactory";
+ import * as __NgCli_bootstrap_2 from "@angular/platform-server";
+
+ if (environment.production) {
+ enableProdMode();
+ }
+ __NgCli_bootstrap_2.renderModuleFactory(__NgCli_bootstrap_1.AppModuleNgFactory, {
+ document: ' ',
+ url: '/'
+ });
+ `;
+ // tslint:enable:max-line-length
+
+ const { program, compilerHost } = createTypescriptContext(input);
+ const transformer = replaceServerBootstrap(
+ () => true,
+ () => ({ path: '/project/src/app/app.module', className: 'AppModule' }),
+ () => program.getTypeChecker(),
+ );
+ const result = transformTypescript(undefined, [transformer], program, compilerHost);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${output}`);
+ });
+
+ it('should replace when the module is used in a config object', () => {
+ const input = stripIndent`
+ import * as express from 'express';
+
+ import { enableProdMode } from '@angular/core';
+ import { ngExpressEngine } from '@nguniversal/express-engine';
+
+ import { AppModule } from './app/app.module';
+ import { environment } from './environments/environment';
+
+ if (environment.production) {
+ enableProdMode();
+ }
+
+ const server = express();
+ server.engine('html', ngExpressEngine({
+ bootstrap: AppModule
+ }));
+ `;
+
+ // tslint:disable:max-line-length
+ const output = stripIndent`
+ import * as express from 'express';
+
+ import { enableProdMode } from '@angular/core';
+ import { ngExpressEngine } from '@nguniversal/express-engine';
+
+ import { environment } from './environments/environment';
+
+ import * as __NgCli_bootstrap_1 from "./app/app.module.ngfactory";
+
+ if (environment.production) {
+ enableProdMode();
+ }
+
+ const server = express();
+ server.engine('html', ngExpressEngine({
+ bootstrap: __NgCli_bootstrap_1.AppModuleNgFactory
+ }));
+ `;
+ // tslint:enable:max-line-length
+
+ const { program, compilerHost } = createTypescriptContext(input);
+ const transformer = replaceServerBootstrap(
+ () => true,
+ () => ({ path: '/project/src/app/app.module', className: 'AppModule' }),
+ () => program.getTypeChecker(),
+ );
+ const result = transformTypescript(undefined, [transformer], program, compilerHost);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${output}`);
+ });
+
+ it('should replace bootstrap when barrel files are used', () => {
+ const input = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { platformDynamicServer } from '@angular/platform-browser-dynamic';
+
+ import { AppModule } from './app';
+ import { environment } from './environments/environment';
+
+ if (environment.production) {
+ enableProdMode();
+ }
+
+ platformDynamicServer().bootstrapModule(AppModule);
+ `;
+
+ // tslint:disable:max-line-length
+ const output = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { environment } from './environments/environment';
+
+ import * as __NgCli_bootstrap_1 from "./app/app.module.ngfactory";
+ import * as __NgCli_bootstrap_2 from "@angular/platform-server";
+
+ if (environment.production) {
+ enableProdMode();
+ }
+ __NgCli_bootstrap_2.platformServer().bootstrapModuleFactory(__NgCli_bootstrap_1.AppModuleNgFactory);
+ `;
+ // tslint:enable:max-line-length
+
+ const { program, compilerHost } = createTypescriptContext(input);
+ const transformer = replaceServerBootstrap(
+ () => true,
+ () => ({ path: '/project/src/app/app.module', className: 'AppModule' }),
+ () => program.getTypeChecker(),
+ );
+ const result = transformTypescript(undefined, [transformer], program, compilerHost);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${output}`);
+ });
+
+ it('should not replace bootstrap when there is no entry module', () => {
+ const input = stripIndent`
+ import { enableProdMode } from '@angular/core';
+ import { platformDynamicServer } from '@angular/platform-browser-dynamic';
+
+ import { AppModule } from './app/app.module';
+ import { environment } from './environments/environment';
+
+ if (environment.production) {
+ enableProdMode();
+ }
+
+ platformDynamicServer().bootstrapModule(AppModule);
+ `;
+
+ const { program, compilerHost } = createTypescriptContext(input);
+ const transformer = replaceServerBootstrap(
+ () => true,
+ () => undefined,
+ () => program.getTypeChecker(),
+ );
+ const result = transformTypescript(undefined, [transformer], program, compilerHost);
+
+ expect(oneLine`${result}`).toEqual(oneLine`${input}`);
+ });
+ });
+});
diff --git a/packages/@ngtools/webpack/src/transformers/replace_server_bootstrap.ts b/packages/@ngtools/webpack/src/transformers/replace_server_bootstrap.ts
new file mode 100644
index 000000000000..a38ee8982c26
--- /dev/null
+++ b/packages/@ngtools/webpack/src/transformers/replace_server_bootstrap.ts
@@ -0,0 +1,135 @@
+// @ignoreDep typescript
+import * as ts from 'typescript';
+import { relative, dirname } from 'path';
+
+import { collectDeepNodes } from './ast_helpers';
+import { insertStarImport } from './insert_import';
+import { StandardTransform, ReplaceNodeOperation, TransformOperation } from './interfaces';
+import { makeTransform } from './make_transform';
+
+export function replaceServerBootstrap(
+ shouldTransform: (fileName: string) => boolean,
+ getEntryModule: () => { path: string, className: string },
+ getTypeChecker: () => ts.TypeChecker,
+): ts.TransformerFactory {
+
+ const standardTransform: StandardTransform = function (sourceFile: ts.SourceFile) {
+ const ops: TransformOperation[] = [];
+
+ const entryModule = getEntryModule();
+
+ if (!shouldTransform(sourceFile.fileName) || !entryModule) {
+ return ops;
+ }
+
+ // Find all identifiers.
+ const entryModuleIdentifiers = collectDeepNodes(sourceFile,
+ ts.SyntaxKind.Identifier)
+ .filter(identifier => identifier.text === entryModule.className);
+
+ if (entryModuleIdentifiers.length === 0) {
+ return [];
+ }
+
+ const relativeEntryModulePath = relative(dirname(sourceFile.fileName), entryModule.path);
+ const normalizedEntryModulePath = `./${relativeEntryModulePath}`.replace(/\\/g, '/');
+ const factoryClassName = entryModule.className + 'NgFactory';
+ const factoryModulePath = normalizedEntryModulePath + '.ngfactory';
+
+ // Find the bootstrap calls.
+ entryModuleIdentifiers.forEach(entryModuleIdentifier => {
+ if (!entryModuleIdentifier.parent) {
+ return;
+ }
+
+ if (entryModuleIdentifier.parent.kind !== ts.SyntaxKind.CallExpression &&
+ entryModuleIdentifier.parent.kind !== ts.SyntaxKind.PropertyAssignment) {
+ return;
+ }
+
+ if (entryModuleIdentifier.parent.kind === ts.SyntaxKind.CallExpression) {
+ // Figure out if it's a `platformDynamicServer().bootstrapModule(AppModule)` call.
+
+ const callExpr = entryModuleIdentifier.parent as ts.CallExpression;
+
+ if (callExpr.expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
+
+ const propAccessExpr = callExpr.expression as ts.PropertyAccessExpression;
+
+ if (!(propAccessExpr.name.text === 'bootstrapModule'
+ && propAccessExpr.expression.kind === ts.SyntaxKind.CallExpression)) {
+ return;
+ }
+
+ const bootstrapModuleIdentifier = propAccessExpr.name;
+ const innerCallExpr = propAccessExpr.expression as ts.CallExpression;
+
+ if (!(
+ innerCallExpr.expression.kind === ts.SyntaxKind.Identifier
+ && (innerCallExpr.expression as ts.Identifier).text === 'platformDynamicServer'
+ )) {
+ return;
+ }
+
+ const platformDynamicServerIdentifier = innerCallExpr.expression as ts.Identifier;
+
+ const idPlatformServer = ts.createUniqueName('__NgCli_bootstrap_');
+ const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
+
+ // Add the transform operations.
+ ops.push(
+ // Replace the entry module import.
+ ...insertStarImport(sourceFile, idNgFactory, factoryModulePath),
+ new ReplaceNodeOperation(sourceFile, entryModuleIdentifier,
+ ts.createPropertyAccess(idNgFactory, ts.createIdentifier(factoryClassName))),
+ // Replace the platformBrowserDynamic import.
+ ...insertStarImport(sourceFile, idPlatformServer, '@angular/platform-server'),
+ new ReplaceNodeOperation(sourceFile, platformDynamicServerIdentifier,
+ ts.createPropertyAccess(idPlatformServer, 'platformServer')),
+ new ReplaceNodeOperation(sourceFile, bootstrapModuleIdentifier,
+ ts.createIdentifier('bootstrapModuleFactory')),
+ );
+ } else if (callExpr.expression.kind === ts.SyntaxKind.Identifier) {
+ // Figure out if it is renderModule
+
+ const identifierExpr = callExpr.expression as ts.Identifier;
+
+ if (identifierExpr.text !== 'renderModule') {
+ return;
+ }
+
+ const renderModuleIdentifier = identifierExpr as ts.Identifier;
+
+ const idPlatformServer = ts.createUniqueName('__NgCli_bootstrap_');
+ const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
+
+ ops.push(
+ // Replace the entry module import.
+ ...insertStarImport(sourceFile, idNgFactory, factoryModulePath),
+ new ReplaceNodeOperation(sourceFile, entryModuleIdentifier,
+ ts.createPropertyAccess(idNgFactory, ts.createIdentifier(factoryClassName))),
+ // Replace the renderModule import.
+ ...insertStarImport(sourceFile, idPlatformServer, '@angular/platform-server'),
+ new ReplaceNodeOperation(sourceFile, renderModuleIdentifier,
+ ts.createPropertyAccess(idPlatformServer, 'renderModuleFactory')),
+ );
+ }
+ } else if (entryModuleIdentifier.parent.kind === ts.SyntaxKind.PropertyAssignment) {
+ // This is for things that accept a module as a property in a config object
+ // .ie the express engine
+
+ const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
+
+ ops.push(
+ ...insertStarImport(sourceFile, idNgFactory, factoryModulePath),
+ new ReplaceNodeOperation(sourceFile, entryModuleIdentifier,
+ ts.createPropertyAccess(idNgFactory, ts.createIdentifier(factoryClassName)))
+ );
+ }
+ });
+
+ return ops;
+ };
+
+ return makeTransform(standardTransform, getTypeChecker);
+}
diff --git a/packages/@ngtools/webpack/src/type_checker.ts b/packages/@ngtools/webpack/src/type_checker.ts
index e17f363b78ff..e14b8a55b88b 100644
--- a/packages/@ngtools/webpack/src/type_checker.ts
+++ b/packages/@ngtools/webpack/src/type_checker.ts
@@ -1,11 +1,6 @@
// @ignoreDep typescript
-import * as process from 'process';
import * as ts from 'typescript';
import chalk from 'chalk';
-
-import { WebpackCompilerHost } from './compiler_host';
-import { time, timeEnd } from './benchmark';
-import { CancellationToken, gatherDiagnostics } from './gather_diagnostics';
import {
Program,
CompilerOptions,
@@ -14,12 +9,19 @@ import {
createCompilerHost,
formatDiagnostics,
} from './ngtools_api';
+import { WebpackCompilerHost } from './compiler_host';
+import { time, timeEnd } from './benchmark';
+import { CancellationToken, gatherDiagnostics } from './gather_diagnostics';
+
+
+// This file should run in a child process with the AUTO_START_ARG argument
// Force basic color support on terminals with no color support.
// Chalk typings don't have the correct constructor parameters.
const chalkCtx = new (chalk.constructor as any)(chalk.supportsColor ? {} : { level: 1 });
const { bold, red, yellow } = chalkCtx;
+
export enum MESSAGE_KIND {
Init,
Update
@@ -46,43 +48,9 @@ export class UpdateMessage extends TypeCheckerMessage {
}
}
-let typeChecker: TypeChecker;
-let lastCancellationToken: CancellationToken;
-
-process.on('message', (message: TypeCheckerMessage) => {
- time('TypeChecker.message');
- switch (message.kind) {
- case MESSAGE_KIND.Init:
- const initMessage = message as InitMessage;
- typeChecker = new TypeChecker(
- initMessage.compilerOptions,
- initMessage.basePath,
- initMessage.jitMode,
- initMessage.rootNames,
- );
- break;
- case MESSAGE_KIND.Update:
- if (!typeChecker) {
- throw new Error('TypeChecker: update message received before initialization');
- }
- if (lastCancellationToken) {
- // This cancellation token doesn't seem to do much, messages don't seem to be processed
- // before the diagnostics finish.
- lastCancellationToken.requestCancellation();
- }
- const updateMessage = message as UpdateMessage;
- lastCancellationToken = new CancellationToken();
- typeChecker.update(updateMessage.rootNames, updateMessage.changedCompilationFiles,
- lastCancellationToken);
- break;
- default:
- throw new Error(`TypeChecker: Unexpected message received: ${message}.`);
- }
- timeEnd('TypeChecker.message');
-});
-
+export const AUTO_START_ARG = '9d93e901-158a-4cf9-ba1b-2f0582ffcfeb';
-class TypeChecker {
+export class TypeChecker {
private _program: ts.Program | Program;
private _compilerHost: WebpackCompilerHost & CompilerHost;
@@ -171,3 +139,4 @@ class TypeChecker {
this._diagnose(cancellationToken);
}
}
+
diff --git a/packages/@ngtools/webpack/src/type_checker_bootstrap.js b/packages/@ngtools/webpack/src/type_checker_bootstrap.js
index e5a3ab002ecc..9326a42d9b4f 100644
--- a/packages/@ngtools/webpack/src/type_checker_bootstrap.js
+++ b/packages/@ngtools/webpack/src/type_checker_bootstrap.js
@@ -1,2 +1,2 @@
require('../../../../lib/bootstrap-local');
-require('./type_checker.ts');
+require('./type_checker_worker.ts');
diff --git a/packages/@ngtools/webpack/src/type_checker_worker.ts b/packages/@ngtools/webpack/src/type_checker_worker.ts
new file mode 100644
index 000000000000..ce1cafba57cb
--- /dev/null
+++ b/packages/@ngtools/webpack/src/type_checker_worker.ts
@@ -0,0 +1,53 @@
+import * as process from 'process';
+
+import { time, timeEnd } from './benchmark';
+import { CancellationToken } from './gather_diagnostics';
+
+import {
+ AUTO_START_ARG,
+ TypeCheckerMessage,
+ InitMessage,
+ MESSAGE_KIND,
+ UpdateMessage,
+ TypeChecker
+} from './type_checker';
+
+let typeChecker: TypeChecker;
+let lastCancellationToken: CancellationToken;
+
+// only listen to messages if started from the AngularCompilerPlugin
+if (process.argv.indexOf(AUTO_START_ARG) >= 0) {
+ process.on('message', (message: TypeCheckerMessage) => {
+ time('TypeChecker.message');
+ switch (message.kind) {
+ case MESSAGE_KIND.Init:
+ const initMessage = message as InitMessage;
+ typeChecker = new TypeChecker(
+ initMessage.compilerOptions,
+ initMessage.basePath,
+ initMessage.jitMode,
+ initMessage.rootNames,
+ );
+ break;
+ case MESSAGE_KIND.Update:
+ if (!typeChecker) {
+ throw new Error('TypeChecker: update message received before initialization');
+ }
+ if (lastCancellationToken) {
+ // This cancellation token doesn't seem to do much, messages don't seem to be processed
+ // before the diagnostics finish.
+ lastCancellationToken.requestCancellation();
+ }
+ const updateMessage = message as UpdateMessage;
+ lastCancellationToken = new CancellationToken();
+ typeChecker.update(updateMessage.rootNames, updateMessage.changedCompilationFiles,
+ lastCancellationToken);
+ break;
+ default:
+ throw new Error(`TypeChecker: Unexpected message received: ${message}.`);
+ }
+ timeEnd('TypeChecker.message');
+ });
+}
+
+
diff --git a/scripts/test-licenses.js b/scripts/test-licenses.js
index b7c700c21c90..ae68d7f75d1e 100644
--- a/scripts/test-licenses.js
+++ b/scripts/test-licenses.js
@@ -79,6 +79,7 @@ const ignoredPackages = [
'spdx-license-ids@2.0.1', // CC0 but it's content only (index.json, no code) and not distributed.
'map-stream@0.1.0', // MIT, license but it's not listed in package.json.
'xmldom@0.1.27', // LGPL,MIT but has a broken licenses array.
+ 'true-case-path@1.0.2', // Apache-2.0 but broken license in package.json
'jsonify@0.0.0', // TODO(hansl): fix this. this is not an acceptable license, but is 8 deps down
// so hard to manage. In talk with owner and users to switch over.
diff --git a/tests/acceptance/bundle-calculator.spec.ts b/tests/acceptance/bundle-calculator.spec.ts
new file mode 100644
index 000000000000..d60ac083ac3a
--- /dev/null
+++ b/tests/acceptance/bundle-calculator.spec.ts
@@ -0,0 +1,86 @@
+import * as path from 'path';
+import { calculateBytes, calculateSizes } from '@angular/cli/utilities/bundle-calculator';
+import mockFs = require('mock-fs');
+
+
+describe('bundle calculator', () => {
+ describe('calculateBytes', () => {
+ const kb = (n: number) => n * 1000;
+ const mb = (n: number) => n * 1000 * 1000;
+ const scenarios: any[] = [
+ { expect: 1, val: '1' },
+ { expect: 1, val: '1b' },
+ { expect: kb(1), val: '1kb' },
+ { expect: mb(1), val: '1mb' },
+ { expect: 110, val: '100b', baseline: '10', factor: 'pos' },
+ { expect: 110, val: '100b', baseline: '10b', factor: 'pos' },
+ { expect: 90, val: '100b', baseline: '10', factor: 'neg' },
+ { expect: 90, val: '100b', baseline: '10b', factor: 'neg' },
+ { expect: 15, val: '50%', baseline: '10', factor: 'pos' },
+ { expect: 5, val: '50%', baseline: '10', factor: 'neg' },
+ { expect: kb(50) + mb(1), val: '50kb', baseline: '1mb', factor: 'pos' },
+ { expect: mb(1.25), val: '25%', baseline: '1mb', factor: 'pos' },
+ { expect: mb(0.75), val: '25%', baseline: '1mb', factor: 'neg' },
+ ];
+ scenarios.forEach(s => {
+ const specMsg = `${s.val} => ${s.expect}`;
+ const baselineMsg = s.baseline ? ` (baseline: ${s.baseline})` : ``;
+ const factor = s.factor ? ` (factor: ${s.factor})` : ``;
+ it(`should calculateBytes ${specMsg}${baselineMsg}${factor}`, () => {
+ const result = calculateBytes(s.val, s.baseline, s.factor);
+ expect(s.expect).toEqual(result);
+ });
+ });
+ });
+
+ describe('calculateSizes', () => {
+ let compilation: any;
+ beforeEach(() => {
+ compilation = {
+ assets: {
+ 'asset1.js': { size: () => 1 },
+ 'asset2': { size: () => 2 },
+ 'asset3.js': { size: () => 4 },
+ 'asset4': { size: () => 8 },
+ 'asset5': { size: () => 16 },
+ },
+ chunks: [
+ { name: 'chunk1', files: ['asset1.js'], isInitial: true },
+ { name: 'chunk2', files: ['asset2'], isInitial: false },
+ { name: 'chunk3', files: ['asset3.js', 'asset4'], isInitial: false }
+ ]
+ };
+ });
+
+ const scenarios: any[] = [
+ { expect: [{size: 31, label: 'total'}], budget: { type: 'all' } },
+ { expect: [{size: 5, label: 'total scripts'}], budget: { type: 'allScript' } },
+ { expect: [
+ {size: 1, label: 'asset1.js'},
+ {size: 2, label: 'asset2'},
+ {size: 4, label: 'asset3.js'},
+ {size: 8, label: 'asset4'},
+ {size: 16, label: 'asset5'},
+ ], budget: { type: 'any' } },
+ { expect: [
+ {size: 1, label: 'asset1.js'},
+ {size: 4, label: 'asset3.js'},
+ ], budget: { type: 'anyScript' } },
+ { expect: [{size: 2, label: 'chunk2'}], budget: { type: 'bundle', name: 'chunk2' } },
+ { expect: [{size: 12, label: 'chunk3'}], budget: { type: 'bundle', name: 'chunk3' } },
+ { expect: [{size: 1, label: 'initial'}], budget: { type: 'initial' } },
+ ];
+
+ scenarios.forEach(s => {
+ const budgetName = s.budget.name ? ` (${s.budget.name})` : '';
+ it(`should calulate sizes for ${s.budget.type}${budgetName}`, () => {
+ const sizes = calculateSizes(s.budget, compilation);
+ expect(sizes.length).toEqual(s.expect.length);
+ for (let i = 0; i < sizes.length; i++) {
+ expect(sizes[i].size).toEqual((s.expect[i].size));
+ expect(sizes[i].label).toEqual((s.expect[i].label));
+ }
+ });
+ });
+ });
+});
diff --git a/tests/e2e/assets/images/spectrum.png b/tests/e2e/assets/images/spectrum.png
new file mode 100644
index 000000000000..2a5f123afc84
Binary files /dev/null and b/tests/e2e/assets/images/spectrum.png differ
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.html b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.html
new file mode 100644
index 000000000000..5a532db9308f
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.html
@@ -0,0 +1,5 @@
+
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.scss b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.scss
new file mode 100644
index 000000000000..5cde7b922336
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.scss
@@ -0,0 +1,3 @@
+:host {
+ background-color: blue;
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.ts
new file mode 100644
index 000000000000..82a4059565d3
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.component.ts
@@ -0,0 +1,15 @@
+import {Component, ViewEncapsulation} from '@angular/core';
+import {MyInjectable} from './injectable';
+
+
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.scss'],
+ encapsulation: ViewEncapsulation.None
+})
+export class AppComponent {
+ constructor(public inj: MyInjectable) {
+ console.log(inj);
+ }
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/app.module.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.module.ts
new file mode 100644
index 000000000000..7c8a0c296448
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/app.module.ts
@@ -0,0 +1,36 @@
+import { NgModule, Component } from '@angular/core';
+import { ServerModule } from '@angular/platform-server';
+import { BrowserModule } from '@angular/platform-browser';
+import { RouterModule } from '@angular/router';
+
+import { AppComponent } from './app.component';
+import { MyInjectable } from './injectable';
+
+@Component({
+ selector: 'home-view',
+ template: 'home!'
+})
+export class HomeView {}
+
+
+@NgModule({
+ declarations: [
+ AppComponent,
+ HomeView
+ ],
+ imports: [
+ BrowserModule.withServerTransition({
+ appId: 'app'
+ }),
+ ServerModule,
+ RouterModule.forRoot([
+ {path: 'lazy', loadChildren: './lazy.module#LazyModule'},
+ {path: '', component: HomeView}
+ ])
+ ],
+ providers: [MyInjectable],
+ bootstrap: [AppComponent]
+})
+export class AppModule {
+ static testProp: string;
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/feature/feature.module.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/feature/feature.module.ts
new file mode 100644
index 000000000000..f464ca028b05
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/feature/feature.module.ts
@@ -0,0 +1,20 @@
+import {NgModule, Component} from '@angular/core';
+import {RouterModule} from '@angular/router';
+
+@Component({
+ selector: 'feature-component',
+ template: 'foo.html'
+})
+export class FeatureComponent {}
+
+@NgModule({
+ declarations: [
+ FeatureComponent
+ ],
+ imports: [
+ RouterModule.forChild([
+ { path: '', component: FeatureComponent}
+ ])
+ ]
+})
+export class FeatureModule {}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/feature/lazy-feature.module.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/feature/lazy-feature.module.ts
new file mode 100644
index 000000000000..8fafca158b24
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/feature/lazy-feature.module.ts
@@ -0,0 +1,23 @@
+import {NgModule, Component} from '@angular/core';
+import {RouterModule} from '@angular/router';
+import {HttpModule, Http} from '@angular/http';
+
+@Component({
+ selector: 'lazy-feature-comp',
+ template: 'lazy feature!'
+})
+export class LazyFeatureComponent {}
+
+@NgModule({
+ imports: [
+ RouterModule.forChild([
+ {path: '', component: LazyFeatureComponent, pathMatch: 'full'},
+ {path: 'feature', loadChildren: './feature.module#FeatureModule'}
+ ]),
+ HttpModule
+ ],
+ declarations: [LazyFeatureComponent]
+})
+export class LazyFeatureModule {
+ constructor(http: Http) {}
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/injectable.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/injectable.ts
new file mode 100644
index 000000000000..b357678ae77a
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/injectable.ts
@@ -0,0 +1,8 @@
+import {Injectable, Inject, ViewContainerRef} from '@angular/core';
+import {DOCUMENT} from '@angular/platform-browser';
+
+
+@Injectable()
+export class MyInjectable {
+ constructor(@Inject(DOCUMENT) public doc) {}
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/lazy.module.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/lazy.module.ts
new file mode 100644
index 000000000000..96da4de7515b
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/lazy.module.ts
@@ -0,0 +1,26 @@
+import {NgModule, Component} from '@angular/core';
+import {RouterModule} from '@angular/router';
+import {HttpModule, Http} from '@angular/http';
+
+@Component({
+ selector: 'lazy-comp',
+ template: 'lazy!'
+})
+export class LazyComponent {}
+
+@NgModule({
+ imports: [
+ RouterModule.forChild([
+ {path: '', component: LazyComponent, pathMatch: 'full'},
+ {path: 'feature', loadChildren: './feature/feature.module#FeatureModule'},
+ {path: 'lazy-feature', loadChildren: './feature/lazy-feature.module#LazyFeatureModule'}
+ ]),
+ HttpModule
+ ],
+ declarations: [LazyComponent]
+})
+export class LazyModule {
+ constructor(http: Http) {}
+}
+
+export class SecondModule {}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/main.commonjs.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/main.commonjs.ts
new file mode 100644
index 000000000000..ce26d93a11de
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/main.commonjs.ts
@@ -0,0 +1 @@
+export { AppModule } from './app.module';
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/app/main.ts b/tests/e2e/assets/webpack/test-server-app-ng5/app/main.ts
new file mode 100644
index 000000000000..5d57aafca8ae
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/app/main.ts
@@ -0,0 +1,12 @@
+import 'core-js/es7/reflect';
+import {platformDynamicServer, renderModule} from '@angular/platform-server';
+import {AppModule} from './app.module';
+
+AppModule.testProp = 'testing';
+
+platformDynamicServer().bootstrapModule(AppModule);
+
+renderModule(AppModule, {
+ document: ' ',
+ url: '/'
+});
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/index.html b/tests/e2e/assets/webpack/test-server-app-ng5/index.html
new file mode 100644
index 000000000000..89fb0893c35d
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/index.html
@@ -0,0 +1,12 @@
+
+
+
+ Document
+
+
+
+
+
+
+
+
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/index.js b/tests/e2e/assets/webpack/test-server-app-ng5/index.js
new file mode 100644
index 000000000000..bdfb2e792acd
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/index.js
@@ -0,0 +1,12 @@
+const fs = require('fs');
+const { AppModuleNgFactory } = require('./dist/app.main');
+const { renderModuleFactory } = require('@angular/platform-server');
+
+require('zone.js/dist/zone-node');
+
+renderModuleFactory(AppModuleNgFactory, {
+ url: '/',
+ document: ' '
+}).then(html => {
+ fs.writeFileSync('dist/index.html', html);
+})
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/package.json b/tests/e2e/assets/webpack/test-server-app-ng5/package.json
new file mode 100644
index 000000000000..b499eaaa4e25
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "test",
+ "license": "MIT",
+ "dependencies": {
+ "@angular/animations": "^5.0.0",
+ "@angular/common": "^5.0.0",
+ "@angular/compiler": "^5.0.0",
+ "@angular/compiler-cli": "^5.0.0",
+ "@angular/core": "^5.0.0",
+ "@angular/http": "^5.0.0",
+ "@angular/platform-browser": "^5.0.0",
+ "@angular/platform-browser-dynamic": "^5.0.0",
+ "@angular/platform-server": "^5.0.0",
+ "@angular/router": "^5.0.0",
+ "@ngtools/webpack": "0.0.0",
+ "core-js": "^2.4.1",
+ "rxjs": "^5.4.2",
+ "zone.js": "^0.8.14"
+ },
+ "devDependencies": {
+ "node-sass": "^4.5.0",
+ "performance-now": "^0.2.0",
+ "raw-loader": "^0.5.1",
+ "sass-loader": "^6.0.3",
+ "typescript": "~2.5.0",
+ "webpack": "2.2.1"
+ }
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/tsconfig.json b/tests/e2e/assets/webpack/test-server-app-ng5/tsconfig.json
new file mode 100644
index 000000000000..5822e780bfc7
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/tsconfig.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "baseUrl": "",
+ "module": "es2015",
+ "moduleResolution": "node",
+ "target": "es5",
+ "noImplicitAny": false,
+ "sourceMap": true,
+ "mapRoot": "",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "lib": [
+ "es2017",
+ "dom"
+ ],
+ "outDir": "lib",
+ "skipLibCheck": true,
+ "rootDir": "."
+ },
+ "angularCompilerOptions": {
+ "genDir": "./app/ngfactory",
+ "entryModule": "app/app.module#AppModule"
+ }
+}
diff --git a/tests/e2e/assets/webpack/test-server-app-ng5/webpack.config.js b/tests/e2e/assets/webpack/test-server-app-ng5/webpack.config.js
new file mode 100644
index 000000000000..4764b17b23dc
--- /dev/null
+++ b/tests/e2e/assets/webpack/test-server-app-ng5/webpack.config.js
@@ -0,0 +1,32 @@
+const { AngularCompilerPlugin, PLATFORM } = require('@ngtools/webpack');
+
+module.exports = {
+ resolve: {
+ extensions: ['.ts', '.js']
+ },
+ target: 'web',
+ entry: './app/main.ts',
+ output: {
+ path: './dist',
+ publicPath: 'dist/',
+ filename: 'app.main.js'
+ },
+ plugins: [
+ new AngularCompilerPlugin({
+ tsConfigPath: './tsconfig.json',
+ mainPath: './app/main.ts',
+ platform: PLATFORM.Server
+ })
+ ],
+ module: {
+ loaders: [
+ { test: /\.scss$/, loaders: ['raw-loader', 'sass-loader'] },
+ { test: /\.css$/, loader: 'raw-loader' },
+ { test: /\.html$/, loader: 'raw-loader' },
+ { test: /\.ts$/, loader: '@ngtools/webpack' }
+ ]
+ },
+ devServer: {
+ historyApiFallback: true
+ }
+};
diff --git a/tests/e2e/setup/100-global-cli.ts b/tests/e2e/setup/100-global-cli.ts
index 5f3bc897c7a1..0db3b19c3780 100644
--- a/tests/e2e/setup/100-global-cli.ts
+++ b/tests/e2e/setup/100-global-cli.ts
@@ -13,7 +13,9 @@ export default function () {
}
// Install global Angular CLI.
- return silentNpm('install', '-g', packages['@angular/cli'].tar);
+ // --unsafe-perm is needed for circleci
+ // because of https://github.com/sass/node-sass/issues/2006
+ return silentNpm('install', '-g', packages['@angular/cli'].tar, '--unsafe-perm');
})
.then(() => exec(process.platform.startsWith('win') ? 'where' : 'which', 'ng'));
}
diff --git a/tests/e2e/setup/500-create-project.ts b/tests/e2e/setup/500-create-project.ts
index b4aa8f108e99..0e784d13de07 100644
--- a/tests/e2e/setup/500-create-project.ts
+++ b/tests/e2e/setup/500-create-project.ts
@@ -5,6 +5,7 @@ import {
updateTsConfig,
updateJsonFile,
useNg2,
+ useNg4,
useSha,
useCIChrome,
useCIDefaults,
@@ -45,6 +46,7 @@ export default function() {
.then(() => useCIChrome())
.then(() => useCIDefaults())
.then(() => argv['ng2'] ? useNg2() : Promise.resolve())
+ .then(() => argv['ng4'] ? useNg4() : Promise.resolve())
.then(() => argv.nightly || argv['ng-sha'] ? useSha() : Promise.resolve())
// npm link on Circle CI is very noisy.
.then(() => silentNpm('install'))
diff --git a/tests/e2e/tests/build/aot/aot.ts b/tests/e2e/tests/basic/aot.ts
similarity index 66%
rename from tests/e2e/tests/build/aot/aot.ts
rename to tests/e2e/tests/basic/aot.ts
index bbeb6c2004d4..5ec34d6d563d 100644
--- a/tests/e2e/tests/build/aot/aot.ts
+++ b/tests/e2e/tests/basic/aot.ts
@@ -1,5 +1,5 @@
-import {ng} from '../../../utils/process';
-import {expectFileToMatch} from '../../../utils/fs';
+import {ng} from '../../utils/process';
+import {expectFileToMatch} from '../../utils/fs';
export default function() {
return ng('build', '--aot')
diff --git a/tests/e2e/tests/build/assets.ts b/tests/e2e/tests/basic/assets.ts
similarity index 90%
rename from tests/e2e/tests/build/assets.ts
rename to tests/e2e/tests/basic/assets.ts
index 9b7e91941339..4b5a9a07a9d7 100644
--- a/tests/e2e/tests/build/assets.ts
+++ b/tests/e2e/tests/basic/assets.ts
@@ -1,3 +1,4 @@
+import * as path from 'path';
import {
writeMultipleFiles,
createDir,
@@ -10,6 +11,10 @@ import { expectToFail } from '../../utils/utils';
import {getGlobalVariable} from '../../utils/env';
+const temp = require('temp');
+const tempDir = path.join(temp.mkdirSync('angular-cli-e2e-assets-'), 'out');
+
+
export default function () {
// Disable parts of it in webpack tests.
const ejected = getGlobalVariable('argv').eject;
@@ -55,6 +60,21 @@ export default function () {
}))
.then(() => expectToFail(() => ng('build')))
+ // This asset will not fail with the exception above.
+ .then(() => updateJsonFile('.angular-cli.json', configJson => {
+ const app = configJson['apps'][0];
+ app['outDir'] = tempDir;
+ app['assets'] = [
+ { 'glob': '**/*', 'input': '../node_modules/some-package/', 'output': tempDir,
+ 'allowOutsideOutDir': true }
+ ];
+ }))
+ .then(() => ng('build'))
+ .then(() => updateJsonFile('.angular-cli.json', configJson => {
+ const app = configJson['apps'][0];
+ app['outDir'] = 'dist';
+ })
+
// This asset should also fail from reading from outside the project.
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson['apps'][0];
diff --git a/tests/e2e/tests/build/dev-build.ts b/tests/e2e/tests/basic/dev-build.ts
similarity index 100%
rename from tests/e2e/tests/build/dev-build.ts
rename to tests/e2e/tests/basic/dev-build.ts
diff --git a/tests/e2e/tests/test/e2e.ts b/tests/e2e/tests/basic/e2e.ts
similarity index 67%
rename from tests/e2e/tests/test/e2e.ts
rename to tests/e2e/tests/basic/e2e.ts
index aca46ca1f624..6558deb50909 100644
--- a/tests/e2e/tests/test/e2e.ts
+++ b/tests/e2e/tests/basic/e2e.ts
@@ -4,9 +4,9 @@ import {
execAndWaitForOutputToMatch,
killAllProcesses
} from '../../utils/process';
-import { updateJsonFile } from '../../utils/project';
-import { expectToFail } from '../../utils/utils';
-import { moveFile, copyFile } from '../../utils/fs';
+import {updateJsonFile} from '../../utils/project';
+import {expectToFail} from '../../utils/utils';
+import {moveFile, copyFile, replaceInFile} from '../../utils/fs';
export default function () {
@@ -34,6 +34,21 @@ export default function () {
.then(() => copyFile('./e2e/renamed-app.e2e-spec.ts', './e2e/another-app.e2e-spec.ts'))
.then(() => ng('e2e', '--specs', './e2e/renamed-app.e2e-spec.ts',
'--specs', './e2e/another-app.e2e-spec.ts'))
+ // Suites block need to be added in the protractor.conf.js file to test suites
+ .then(() => replaceInFile('protractor.conf.js', `allScriptsTimeout: 11000,`,
+ `allScriptsTimeout: 11000,
+ suites: {
+ app: './e2e/app.e2e-spec.ts'
+ },
+ `))
+ .then(() => ng('e2e', '--suite=app'))
+ // remove suites block from protractor.conf.js file after testing suites
+ .then(() => replaceInFile('protractor.conf.js', `allScriptsTimeout: 11000,
+ suites: {
+ app: './e2e/app.e2e-spec.ts'
+ },
+ `, `allScriptsTimeout: 11000,`
+ ))
// Should start up Element Explorer
.then(() => execAndWaitForOutputToMatch('ng', ['e2e', '--element-explorer'],
/Element Explorer/))
@@ -44,5 +59,9 @@ export default function () {
// Should run side-by-side with `ng serve`
.then(() => execAndWaitForOutputToMatch('ng', ['serve'],
/webpack: Compiled successfully./))
- .then(() => ng('e2e'));
+ .then(() => ng('e2e'))
+ .then(() => killAllProcesses(), (err: any) => {
+ killAllProcesses();
+ throw err;
+ });
}
diff --git a/tests/e2e/tests/build/rebuild.ts b/tests/e2e/tests/basic/rebuild.ts
similarity index 93%
rename from tests/e2e/tests/build/rebuild.ts
rename to tests/e2e/tests/basic/rebuild.ts
index d253e3632df0..4e4c29609578 100644
--- a/tests/e2e/tests/build/rebuild.ts
+++ b/tests/e2e/tests/basic/rebuild.ts
@@ -20,14 +20,9 @@ export default function() {
return Promise.resolve();
}
- let oldNumberOfChunks = 0;
- const chunkRegExp = /chunk\s+\{/g;
+ const lazyChunkRegExp = /lazy\.module\.chunk\.js/g;
return execAndWaitForOutputToMatch('ng', ['serve'], validBundleRegEx)
- // Count the bundles.
- .then(({ stdout }) => {
- oldNumberOfChunks = stdout.split(chunkRegExp).length;
- })
// Add a lazy module.
.then(() => ng('generate', 'module', 'lazy', '--routing'))
// Should trigger a rebuild with a new bundle.
@@ -65,8 +60,7 @@ export default function() {
// Count the bundles.
.then((results) => {
const stdout = results[0].stdout;
- let newNumberOfChunks = stdout.split(chunkRegExp).length;
- if (oldNumberOfChunks >= newNumberOfChunks) {
+ if (!lazyChunkRegExp.test(stdout)) {
throw new Error('Expected webpack to create a new chunk, but did not.');
}
})
diff --git a/tests/e2e/tests/build/scripts-array.ts b/tests/e2e/tests/basic/scripts-array.ts
similarity index 100%
rename from tests/e2e/tests/build/scripts-array.ts
rename to tests/e2e/tests/basic/scripts-array.ts
diff --git a/tests/e2e/tests/build/styles/styles-array.ts b/tests/e2e/tests/basic/styles-array.ts
similarity index 93%
rename from tests/e2e/tests/build/styles/styles-array.ts
rename to tests/e2e/tests/basic/styles-array.ts
index 8149363993f3..c7ac5d756e41 100644
--- a/tests/e2e/tests/build/styles/styles-array.ts
+++ b/tests/e2e/tests/basic/styles-array.ts
@@ -1,9 +1,9 @@
import {
writeMultipleFiles,
expectFileToMatch
-} from '../../../utils/fs';
-import { ng } from '../../../utils/process';
-import { updateJsonFile } from '../../../utils/project';
+} from '../../utils/fs';
+import { ng } from '../../utils/process';
+import { updateJsonFile } from '../../utils/project';
import { oneLineTrim } from 'common-tags';
export default function () {
diff --git a/tests/e2e/tests/test/test.ts b/tests/e2e/tests/basic/test.ts
similarity index 100%
rename from tests/e2e/tests/test/test.ts
rename to tests/e2e/tests/basic/test.ts
diff --git a/tests/e2e/tests/build/aot/exclude.ts b/tests/e2e/tests/build/aot/exclude.ts
index 94b474832f23..3266012f1f35 100644
--- a/tests/e2e/tests/build/aot/exclude.ts
+++ b/tests/e2e/tests/build/aot/exclude.ts
@@ -7,9 +7,8 @@ export default function () {
// Disable parts of it in webpack tests.
const ejected = getGlobalVariable('argv').eject;
- // Skip this in ng5 tests, it only happens in ng2/4.
- // This check should be changed once ng5 because the default.
- if (getGlobalVariable('argv').nightly) {
+ // This test is only for Angular 2/4 projects.
+ if (!getGlobalVariable('argv').ng2 && !getGlobalVariable('argv').ng4) {
return Promise.resolve();
}
diff --git a/tests/e2e/tests/build/base-href.ts b/tests/e2e/tests/build/base-href.ts
index 1f14735bf2e3..23a1633283dd 100644
--- a/tests/e2e/tests/build/base-href.ts
+++ b/tests/e2e/tests/build/base-href.ts
@@ -1,15 +1,9 @@
import {ng} from '../../utils/process';
import {expectFileToMatch} from '../../utils/fs';
-import {getGlobalVariable} from '../../utils/env';
import {updateJsonFile} from '../../utils/project';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return ng('build', '--base-href', '/myUrl')
.then(() => expectFileToMatch('dist/index.html', / /))
.then(() => updateJsonFile('.angular-cli.json', configJson => {
diff --git a/tests/e2e/tests/build/build-app-shell-with-schematic.ts b/tests/e2e/tests/build/build-app-shell-with-schematic.ts
new file mode 100644
index 000000000000..41f799cd90e7
--- /dev/null
+++ b/tests/e2e/tests/build/build-app-shell-with-schematic.ts
@@ -0,0 +1,42 @@
+import { ng, npm } from '../../utils/process';
+import { expectFileToMatch, appendToFile } from '../../utils/fs';
+import { getGlobalVariable } from '../../utils/env';
+import { expectToFail } from '../../utils/utils';
+import { updateJsonFile } from '../../utils/project';
+import { readNgVersion } from '../../utils/version';
+
+
+export default function () {
+ // Skip this in ejected tests.
+ if (getGlobalVariable('argv').eject) {
+ return Promise.resolve();
+ }
+
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
+ return Promise.resolve();
+ }
+
+ let platformServerVersion = readNgVersion();
+
+ if (getGlobalVariable('argv').nightly) {
+ platformServerVersion = 'github:angular/platform-server-builds';
+ }
+
+
+ return Promise.resolve()
+ .then(() => expectToFail(() => {
+ return ng('generate', 'appShell', '--universal-app', 'universal');
+ })
+ .then(() => appendToFile('src/app/app.component.html', ' '))
+ .then(() => ng('generate', 'appShell', '--universal-app', 'universal'))
+ .then(() => updateJsonFile('package.json', packageJson => {
+ const dependencies = packageJson['dependencies'];
+ dependencies['@angular/platform-server'] = platformServerVersion;
+ })
+ .then(() => npm('install'))
+ .then(() => ng('build', '--prod'))
+ .then(() => expectFileToMatch('dist/index.html', /app-shell works!/))
+ .then(() => ng('build', '--prod', '--skip-app-shell'))
+ .then(() => expectToFail(() => expectFileToMatch('dist/index.html', /app-shell works!/)));
+}
diff --git a/tests/e2e/tests/build/build-app-shell.ts b/tests/e2e/tests/build/build-app-shell.ts
new file mode 100644
index 000000000000..cc531557f1ac
--- /dev/null
+++ b/tests/e2e/tests/build/build-app-shell.ts
@@ -0,0 +1,147 @@
+import { ng, npm } from '../../utils/process';
+import { expectFileToMatch, writeFile } from '../../utils/fs';
+import { getGlobalVariable } from '../../utils/env';
+import { expectToFail } from '../../utils/utils';
+import { updateJsonFile } from '../../utils/project';
+import { readNgVersion } from '../../utils/version';
+import { stripIndent } from 'common-tags';
+
+
+export default function () {
+ // Skip this in ejected tests.
+ if (getGlobalVariable('argv').eject) {
+ return Promise.resolve();
+ }
+
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
+ return Promise.resolve();
+ }
+
+ let platformServerVersion = readNgVersion();
+
+ if (getGlobalVariable('argv').nightly) {
+ platformServerVersion = 'github:angular/platform-server-builds';
+ }
+
+ return Promise.resolve()
+ .then(() => updateJsonFile('.angular-cli.json', configJson => {
+ const app = configJson['apps'][0];
+ app['appShell'] = {
+ app: '1',
+ route: 'shell'
+ };
+ configJson['apps'].push({
+ platform: 'server',
+ root: 'src',
+ outDir: 'dist-server',
+ assets: [
+ 'assets',
+ 'favicon.ico'
+ ],
+ index: 'index.html',
+ main: 'main.server.ts',
+ test: 'test.ts',
+ tsconfig: 'tsconfig.server.json',
+ testTsconfig: 'tsconfig.spec.json',
+ prefix: 'app',
+ styles: [
+ 'styles.css'
+ ],
+ scripts: [],
+ environmentSource: 'environments/environment.ts',
+ environments: {
+ dev: 'environments/environment.ts',
+ prod: 'environments/environment.prod.ts'
+ }
+ });
+ }))
+ .then(() => writeFile('src/app/app.module.ts', stripIndent`
+ import { BrowserModule } from '@angular/platform-browser';
+ import { NgModule } from '@angular/core';
+ import { RouterModule } from '@angular/router';
+
+ import { AppComponent } from './app.component';
+
+ @NgModule({
+ imports: [
+ BrowserModule.withServerTransition({ appId: 'appshell-play' }),
+ RouterModule
+ ],
+ declarations: [AppComponent],
+ bootstrap: [AppComponent]
+ })
+ export class AppModule { }
+ `))
+ .then(() => writeFile('src/app/app.component.html', stripIndent`
+ Hello World
+
+ `))
+ .then(() => writeFile('src/tsconfig.server.json', stripIndent`
+ {
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/app",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "types": []
+ },
+ "exclude": [
+ "test.ts",
+ "**/*.spec.ts"
+ ],
+ "angularCompilerOptions": {
+ "entryModule": "app/app.server.module#AppServerModule"
+ }
+ }
+ `))
+ .then(() => writeFile('src/main.server.ts', stripIndent`
+ export {AppServerModule} from './app/app.server.module';
+ `))
+ .then(() => writeFile('src/app/app.server.module.ts', stripIndent`
+ import {NgModule} from '@angular/core';
+ import {ServerModule} from '@angular/platform-server';
+ import { Routes, RouterModule } from '@angular/router';
+
+ import { AppModule } from './app.module';
+ import { AppComponent } from './app.component';
+ import { ShellComponent } from './shell.component';
+
+ const routes: Routes = [
+ { path: 'shell', component: ShellComponent }
+ ];
+
+ @NgModule({
+ imports: [
+ // The AppServerModule should import your AppModule followed
+ // by the ServerModule from @angular/platform-server.
+ AppModule,
+ ServerModule,
+ RouterModule.forRoot(routes),
+ ],
+ // Since the bootstrapped component is not inherited from your
+ // imported AppModule, it needs to be repeated here.
+ bootstrap: [AppComponent],
+ declarations: [ShellComponent],
+ })
+ export class AppServerModule {}
+ `))
+ .then(() => writeFile('src/app/shell.component.ts', stripIndent`
+ import { Component } from '@angular/core';
+ @Component({
+ selector: 'app-shell',
+ template: 'shell Works!
',
+ styles: []
+ })
+ export class ShellComponent {}
+ `))
+ .then(() => updateJsonFile('package.json', packageJson => {
+ const dependencies = packageJson['dependencies'];
+ dependencies['@angular/platform-server'] = platformServerVersion;
+ })
+ .then(() => npm('install')))
+ .then(() => ng('build', '--prod'))
+ .then(() => expectFileToMatch('dist/index.html', /shell Works!/))
+ .then(() => ng('build', '--prod', '--skip-app-shell'))
+ .then(() => expectToFail(() => expectFileToMatch('dist/index.html', /shell Works!/)));
+}
diff --git a/tests/e2e/tests/build/build-errors.ts b/tests/e2e/tests/build/build-errors.ts
index 341debe750b0..a5a97af7fb49 100644
--- a/tests/e2e/tests/build/build-errors.ts
+++ b/tests/e2e/tests/build/build-errors.ts
@@ -1,6 +1,6 @@
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
-import { writeFile, appendToFile, readFile } from '../../utils/fs';
+import { writeFile, appendToFile, readFile, replaceInFile } from '../../utils/fs';
import { getGlobalVariable } from '../../utils/env';
import { expectToFail } from '../../utils/utils';
@@ -15,13 +15,14 @@ export default function () {
if (process.platform.startsWith('win')) {
return Promise.resolve();
}
+
// Skip this in ejected tests.
if (getGlobalVariable('argv').eject) {
return Promise.resolve();
}
- // Skip in non-nightly tests. Switch this check around when ng5 is out.
- if (!getGlobalVariable('argv').nightly) {
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
return Promise.resolve();
}
@@ -38,7 +39,7 @@ export default function () {
}))
.then(() => expectToFail(() => ng('build')))
.then(({ message }) => {
- if (!message.includes('polyfills.ts is not part of the compilation')) {
+ if (!message.includes('polyfills.ts is missing from the TypeScript compilation')) {
throw new Error(`Expected missing TS file error, got this instead:\n${message}`);
}
if (extraErrors.some((e) => message.includes(e))) {
@@ -61,11 +62,12 @@ export default function () {
}
})
.then(() => writeFile('./src/app/app.component.ts', origContent))
- // Check errors when files were not emitted.
- .then(() => writeFile('./src/app/app.component.ts', ''))
+ // Check errors when files were not emitted due to static analysis errors.
+ .then(() => replaceInFile('./src/app/app.component.ts', `'app-root'`, `(() => 'app-root')()`))
.then(() => expectToFail(() => ng('build', '--aot')))
.then(({ message }) => {
- if (!message.includes(`Unexpected value 'AppComponent`)) {
+ if (!message.includes('Function calls are not supported')
+ && !message.includes('Function expressions are not supported in decorators')) {
throw new Error(`Expected static analysis error, got this instead:\n${message}`);
}
if (extraErrors.some((e) => message.includes(e))) {
diff --git a/tests/e2e/tests/build/build-optimizer.ts b/tests/e2e/tests/build/build-optimizer.ts
index 6e0dd82b2bdf..399909bfa986 100644
--- a/tests/e2e/tests/build/build-optimizer.ts
+++ b/tests/e2e/tests/build/build-optimizer.ts
@@ -9,12 +9,12 @@ export default function () {
.then(() => expectToFail(() => expectFileToExist('dist/vendor.js')))
.then(() => expectToFail(() => expectFileToMatch('dist/main.js', /\.decorators =/)))
.then(() => {
- // Check if build optimizer is on by default in ng5 prod builds
- // This check should be changed once ng5 because the default.
- if (!getGlobalVariable('argv').nightly) {
+ // Skip this part of the test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
return Promise.resolve();
}
+ // Check if build optimizer is on by default in ng5 prod builds
return Promise.resolve()
.then(() => ng('build', '--prod'))
.then(() => expectToFail(() => expectFileToExist('dist/vendor.js')))
diff --git a/tests/e2e/tests/build/bundle-budgets.ts b/tests/e2e/tests/build/bundle-budgets.ts
new file mode 100644
index 000000000000..92d35a51b557
--- /dev/null
+++ b/tests/e2e/tests/build/bundle-budgets.ts
@@ -0,0 +1,74 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import { getGlobalVariable } from '../../utils/env';
+import { ng } from '../../utils/process';
+import { updateJsonFile } from '../../utils/project';
+import { expectToFail } from '../../utils/utils';
+
+// tslint:disable:max-line-length
+export default function () {
+ const budgetConfigs = [
+ {
+ expectation: 'pass',
+ message: 'BIG max for all, should not error',
+ budget: { type: 'allScript', maximumError: '100mb' },
+ },
+ {
+ expectation: 'error',
+ message: 'Budget error: all, max error',
+ budget: { type: 'all', maximumError: '100b' },
+ },
+ {
+ expectation: 'warning',
+ message: 'Budget warning: all, min warning',
+ budget: { type: 'all', minimumWarning: '100mb' },
+ }
+ ];
+
+ const promiseFactories = budgetConfigs.map(cfg => {
+ if (cfg.expectation === 'error') {
+ return () => {
+ return updateJsonFile('.angular-cli.json', (json) => { json.apps[0].budgets = [cfg.budget]; })
+ .then(() => expectToFail(() => ng('build', '--prod')))
+ .then(errorMessage => {
+ if (!/ERROR in budgets/.test(errorMessage)) {
+ throw new Error(cfg.message);
+ }
+ });
+ };
+ } else if (cfg.expectation === 'warning') {
+ return () => {
+ return updateJsonFile('.angular-cli.json', (json) => { json.apps[0].budgets = [cfg.budget]; })
+ .then(() => ng('build', '--prod'))
+ .then(({ stdout }) => {
+ if (!/WARNING in budgets/.test(stdout)) {
+ throw new Error(cfg.message);
+ }
+ });
+ };
+ } else { // pass
+ return () => {
+ return updateJsonFile('.angular-cli.json', (json) => { json.apps[0].budgets = [cfg.budget]; })
+ .then(() => ng('build', '--prod'))
+ .then(({ stdout }) => {
+ if (/(WARNING|ERROR)/.test(stdout)) {
+ throw new Error(cfg.message);
+ }
+ });
+ };
+ }
+ });
+
+ let promiseChain = Promise.resolve();
+ for (let i = 0; i < promiseFactories.length; i++) {
+ promiseChain = promiseChain.then(promiseFactories[i]);
+ }
+
+ return promiseChain;
+}
diff --git a/tests/e2e/tests/build/chunk-hash.ts b/tests/e2e/tests/build/chunk-hash.ts
index 13e5a2cb8298..57cae6db7d16 100644
--- a/tests/e2e/tests/build/chunk-hash.ts
+++ b/tests/e2e/tests/build/chunk-hash.ts
@@ -2,7 +2,6 @@ import * as fs from 'fs';
import {ng} from '../../utils/process';
import {writeFile, prependToFile, replaceInFile} from '../../utils/fs';
-import {getGlobalVariable} from '../../utils/env';
const OUTPUT_RE = /(main|polyfills|vendor|inline|styles|\d+)\.[a-z0-9]+\.(chunk|bundle)\.(js|css)$/;
@@ -43,12 +42,6 @@ function validateHashes(
}
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
-
let oldHashes: Map;
let newHashes: Map;
// First, collect the hashes.
diff --git a/tests/e2e/tests/build/css-urls.ts b/tests/e2e/tests/build/css-urls.ts
index 9bc565a428d3..e8e3e13223a1 100644
--- a/tests/e2e/tests/build/css-urls.ts
+++ b/tests/e2e/tests/build/css-urls.ts
@@ -1,4 +1,3 @@
-import * as fs from 'fs';
import { ng } from '../../utils/process';
import {
expectFileToMatch,
@@ -6,8 +5,8 @@ import {
expectFileMatchToExist,
writeMultipleFiles
} from '../../utils/fs';
+import { copyProjectAsset } from '../../utils/assets';
import { expectToFail } from '../../utils/utils';
-import { getGlobalVariable } from '../../utils/env';
const imgSvg = `
@@ -16,42 +15,39 @@ const imgSvg = `
`;
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
// Verify absolute/relative paths in global/component css.
.then(() => writeMultipleFiles({
'src/styles.css': `
h1 { background: url('/assets/global-img-absolute.svg'); }
- h2 { background: url('./assets/global-img-relative.svg'); }
+ h2 { background: url('./assets/global-img-relative.png'); }
`,
'src/app/app.component.css': `
h3 { background: url('/assets/component-img-absolute.svg'); }
- h4 { background: url('../assets/component-img-relative.svg'); }
+ h4 { background: url('../assets/component-img-relative.png'); }
`,
- // Using SVGs because they are loaded via file-loader and thus never inlined.
'src/assets/global-img-absolute.svg': imgSvg,
- 'src/assets/global-img-relative.svg': imgSvg,
- 'src/assets/component-img-absolute.svg': imgSvg,
- 'src/assets/component-img-relative.svg': imgSvg
+ 'src/assets/component-img-absolute.svg': imgSvg
}))
+ // use image with file size >10KB to prevent inlining
+ .then(() => copyProjectAsset('images/spectrum.png', './assets/global-img-relative.png'))
+ .then(() => copyProjectAsset('images/spectrum.png', './assets/component-img-relative.png'))
.then(() => ng('build', '--extract-css', '--aot'))
// Check paths are correctly generated.
.then(() => expectFileToMatch('dist/styles.bundle.css', '/assets/global-img-absolute.svg'))
.then(() => expectFileToMatch('dist/styles.bundle.css',
- /global-img-relative\.[0-9a-f]{20}\.svg/))
+ /url\('\/assets\/global-img-absolute\.svg'\)/))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ /global-img-relative\.[0-9a-f]{20}\.png/))
.then(() => expectFileToMatch('dist/main.bundle.js',
'/assets/component-img-absolute.svg'))
.then(() => expectFileToMatch('dist/main.bundle.js',
- /component-img-relative\.[0-9a-f]{20}\.svg/))
+ /component-img-relative\.[0-9a-f]{20}\.png/))
// Check files are correctly created.
.then(() => expectToFail(() => expectFileToExist('dist/global-img-absolute.svg')))
.then(() => expectToFail(() => expectFileToExist('dist/component-img-absolute.svg')))
- .then(() => expectFileMatchToExist('./dist', /global-img-relative\.[0-9a-f]{20}\.svg/))
- .then(() => expectFileMatchToExist('./dist', /component-img-relative\.[0-9a-f]{20}\.svg/))
+ .then(() => expectFileMatchToExist('./dist', /global-img-relative\.[0-9a-f]{20}\.png/))
+ .then(() => expectFileMatchToExist('./dist', /component-img-relative\.[0-9a-f]{20}\.png/))
// Check urls with deploy-url scheme are used as is.
.then(() => ng('build', '--base-href=/base/', '--deploy-url=http://deploy.url/',
'--extract-css'))
@@ -79,9 +75,31 @@ export default function () {
.then(() => expectFileToMatch('dist/styles.bundle.css',
'/base/deploy/assets/global-img-absolute.svg'))
.then(() => expectFileToMatch('dist/styles.bundle.css',
- /global-img-relative\.[0-9a-f]{20}\.svg/))
+ /global-img-relative\.[0-9a-f]{20}\.png/))
.then(() => expectFileToMatch('dist/main.bundle.js',
'/base/deploy/assets/component-img-absolute.svg'))
.then(() => expectFileToMatch('dist/main.bundle.js',
- /deploy\/component-img-relative\.[0-9a-f]{20}\.svg/));
+ /deploy\/component-img-relative\.[0-9a-f]{20}\.png/))
+ // Check with identical base-href and deploy-url flags.
+ .then(() => ng('build', '--base-href=/base/', '--deploy-url=/base/',
+ '--extract-css', '--aot'))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ '/base/assets/global-img-absolute.svg'))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ /global-img-relative\.[0-9a-f]{20}\.png/))
+ .then(() => expectFileToMatch('dist/main.bundle.js',
+ '/base/assets/component-img-absolute.svg'))
+ .then(() => expectFileToMatch('dist/main.bundle.js',
+ /\/base\/component-img-relative\.[0-9a-f]{20}\.png/))
+ // Check with only base-href flag.
+ .then(() => ng('build', '--base-href=/base/',
+ '--extract-css', '--aot'))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ '/base/assets/global-img-absolute.svg'))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ /global-img-relative\.[0-9a-f]{20}\.png/))
+ .then(() => expectFileToMatch('dist/main.bundle.js',
+ '/base/assets/component-img-absolute.svg'))
+ .then(() => expectFileToMatch('dist/main.bundle.js',
+ /component-img-relative\.[0-9a-f]{20}\.png/));
}
diff --git a/tests/e2e/tests/build/delete-output-path.ts b/tests/e2e/tests/build/delete-output-path.ts
index e503a67f6db7..9a5b658f8e7e 100644
--- a/tests/e2e/tests/build/delete-output-path.ts
+++ b/tests/e2e/tests/build/delete-output-path.ts
@@ -4,11 +4,6 @@ import {deleteFile, expectFileToExist} from '../../utils/fs';
import {getGlobalVariable} from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
// Skip this in ejected tests.
if (getGlobalVariable('argv').eject) {
return Promise.resolve();
diff --git a/tests/e2e/tests/build/deploy-url.ts b/tests/e2e/tests/build/deploy-url.ts
index 5882d2c8e5ba..36acdcfdda98 100644
--- a/tests/e2e/tests/build/deploy-url.ts
+++ b/tests/e2e/tests/build/deploy-url.ts
@@ -1,29 +1,21 @@
import { ng } from '../../utils/process';
+import { copyProjectAsset } from '../../utils/assets';
import { expectFileToMatch, writeMultipleFiles } from '../../utils/fs';
import { updateJsonFile } from '../../utils/project';
import { getGlobalVariable } from '../../utils/env';
-import { stripIndents } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
-
return Promise.resolve()
.then(() => writeMultipleFiles({
- 'src/styles.css': 'div { background: url("./assets/more.svg"); }',
- 'src/assets/more.svg': stripIndents`
-
-
-
- `}))
+ 'src/styles.css': 'div { background: url("./assets/more.png"); }',
+ }))
+ // use image with file size >10KB to prevent inlining
+ .then(() => copyProjectAsset('images/spectrum.png', './assets/more.png'))
.then(() => ng('build', '--deploy-url=deployUrl/', '--extract-css'))
.then(() => expectFileToMatch('dist/index.html', 'deployUrl/main.bundle.js'))
// verify --deploy-url isn't applied to extracted css urls
- .then(() => expectFileToMatch('dist/styles.bundle.css', /url\(more\.[0-9a-f]{20}\.svg\)/))
+ .then(() => expectFileToMatch('dist/styles.bundle.css', /url\(more\.[0-9a-f]{20}\.png\)/))
.then(() => ng('build', '--deploy-url=http://example.com/some/path/', '--extract-css'))
.then(() => expectFileToMatch('dist/index.html', 'http://example.com/some/path/main.bundle.js'))
// verify option also works in config
@@ -36,5 +28,13 @@ export default function () {
// verify --deploy-url is applied to non-extracted css urls
.then(() => ng('build', '--deploy-url=deployUrl/', '--extract-css=false'))
.then(() => expectFileToMatch('dist/styles.bundle.js',
- /__webpack_require__.p \+ \"more\.[0-9a-f]{20}\.svg\"/));
+ /__webpack_require__.p \+ \"more\.[0-9a-f]{20}\.png\"/))
+ .then(() => expectFileToMatch('dist/inline.bundle.js',
+ /__webpack_require__\.p = "deployUrl\/";/))
+ // verify slash is appended to the end of --deploy-url if missing
+ .then(() => ng('build', '--deploy-url=deployUrl', '--extract-css=false'))
+ // skip this in ejected tests
+ .then(() => getGlobalVariable('argv').eject
+ ? Promise.resolve()
+ : expectFileToMatch('dist/inline.bundle.js', /__webpack_require__\.p = "deployUrl\/";/));
}
diff --git a/tests/e2e/tests/build/filename.ts b/tests/e2e/tests/build/filename.ts
index 2399e833a803..e8979648f9a6 100644
--- a/tests/e2e/tests/build/filename.ts
+++ b/tests/e2e/tests/build/filename.ts
@@ -2,15 +2,9 @@ import {ng} from '../../utils/process';
import {expectFileToExist} from '../../utils/fs';
import {updateJsonFile} from '../../utils/project';
import {copyFile} from '../../utils/fs';
-import {getGlobalVariable} from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => copyFile('src/index.html', 'src/config-index.html'))
.then(() => updateJsonFile('.angular-cli.json', configJson => {
diff --git a/tests/e2e/tests/build/json.ts b/tests/e2e/tests/build/json.ts
index 71cfa32f0544..dc116f60719a 100644
--- a/tests/e2e/tests/build/json.ts
+++ b/tests/e2e/tests/build/json.ts
@@ -5,11 +5,6 @@ import {getGlobalVariable} from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
// Skip this in ejected tests.
if (getGlobalVariable('argv').eject) {
return Promise.resolve();
diff --git a/tests/e2e/tests/build/module-id.ts b/tests/e2e/tests/build/module-id.ts
index 581d8bbddf1d..ad75d230a419 100644
--- a/tests/e2e/tests/build/module-id.ts
+++ b/tests/e2e/tests/build/module-id.ts
@@ -1,14 +1,8 @@
import { ng } from '../../utils/process';
import { replaceInFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => replaceInFile('src/app/app.component.ts',
'@Component({',
diff --git a/tests/e2e/tests/build/no-angular-router.ts b/tests/e2e/tests/build/no-angular-router.ts
index 84eb22cd14d0..b6680e99d9f9 100644
--- a/tests/e2e/tests/build/no-angular-router.ts
+++ b/tests/e2e/tests/build/no-angular-router.ts
@@ -1,16 +1,10 @@
import {ng} from '../../utils/process';
import {expectFileToExist, moveFile} from '../../utils/fs';
-import {updateJsonFile} from '../../utils/project';
import {getGlobalVariable} from '../../utils/env';
import * as path from 'path';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
const tmp = getGlobalVariable('tmp-root');
return Promise.resolve()
diff --git a/tests/e2e/tests/build/no-implicit-any.ts b/tests/e2e/tests/build/no-implicit-any.ts
index 340f7169b698..08927a41467e 100644
--- a/tests/e2e/tests/build/no-implicit-any.ts
+++ b/tests/e2e/tests/build/no-implicit-any.ts
@@ -1,14 +1,8 @@
import {updateTsConfig} from '../../utils/project';
import {ng} from '../../utils/process';
-import {getGlobalVariable} from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return updateTsConfig(json => {
json['compilerOptions']['noImplicitAny'] = true;
})
diff --git a/tests/e2e/tests/build/output-hashing.ts b/tests/e2e/tests/build/output-hashing.ts
index a7c091c25041..aba9758f6dd5 100644
--- a/tests/e2e/tests/build/output-hashing.ts
+++ b/tests/e2e/tests/build/output-hashing.ts
@@ -1,7 +1,7 @@
-import {stripIndents} from 'common-tags';
import {ng} from '../../utils/process';
+import { copyProjectAsset } from '../../utils/assets';
import { writeMultipleFiles, expectFileToMatch, expectFileMatchToExist } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
+
function verifyMedia(css: RegExp, content: RegExp) {
return expectFileMatchToExist('./dist', css)
@@ -9,39 +9,33 @@ function verifyMedia(css: RegExp, content: RegExp) {
}
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => writeMultipleFiles({
- 'src/styles.css': stripIndents`
- body { background-image: url("image.svg"); }
- `,
- 'src/image.svg': 'I would like to be an image someday.'
+ 'src/styles.css': 'body { background-image: url("./assets/image.png"); }'
}))
+ // use image with file size >10KB to prevent inlining
+ .then(() => copyProjectAsset('images/spectrum.png', './assets/image.png'))
.then(() => ng('build', '--dev', '--output-hashing=all'))
.then(() => expectFileToMatch('dist/index.html', /inline\.[0-9a-f]{20}\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /main\.[0-9a-f]{20}\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /styles\.[0-9a-f]{20}\.bundle\.(css|js)/))
- .then(() => verifyMedia(/styles\.[0-9a-f]{20}\.bundle\.(css|js)/, /image\.[0-9a-f]{20}\.svg/))
+ .then(() => verifyMedia(/styles\.[0-9a-f]{20}\.bundle\.(css|js)/, /image\.[0-9a-f]{20}\.png/))
.then(() => ng('build', '--prod', '--output-hashing=none'))
.then(() => expectFileToMatch('dist/index.html', /inline\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /main\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /styles\.bundle\.(css|js)/))
- .then(() => verifyMedia(/styles\.bundle\.(css|js)/, /image\.svg/))
+ .then(() => verifyMedia(/styles\.bundle\.(css|js)/, /image\.png/))
.then(() => ng('build', '--dev', '--output-hashing=media'))
.then(() => expectFileToMatch('dist/index.html', /inline\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /main\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /styles\.bundle\.(css|js)/))
- .then(() => verifyMedia(/styles\.bundle\.(css|js)/, /image\.[0-9a-f]{20}\.svg/))
+ .then(() => verifyMedia(/styles\.bundle\.(css|js)/, /image\.[0-9a-f]{20}\.png/))
.then(() => ng('build', '--dev', '--output-hashing=bundles'))
.then(() => expectFileToMatch('dist/index.html', /inline\.[0-9a-f]{20}\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /main\.[0-9a-f]{20}\.bundle\.js/))
.then(() => expectFileToMatch('dist/index.html', /styles\.[0-9a-f]{20}\.bundle\.(css|js)/))
- .then(() => verifyMedia(/styles\.[0-9a-f]{20}\.bundle\.(css|js)/, /image\.svg/));
+ .then(() => verifyMedia(/styles\.[0-9a-f]{20}\.bundle\.(css|js)/, /image\.png/));
}
diff --git a/tests/e2e/tests/build/platform-server.ts b/tests/e2e/tests/build/platform-server.ts
index 8d7622c90c55..d2943d162070 100644
--- a/tests/e2e/tests/build/platform-server.ts
+++ b/tests/e2e/tests/build/platform-server.ts
@@ -14,11 +14,6 @@ import { readNgVersion } from '../../utils/version';
import { expectToFail } from '../../utils/utils';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
// Skip this for ejected tests.
if (getGlobalVariable('argv').eject) {
return Promise.resolve();
@@ -30,6 +25,11 @@ export default function () {
platformServerVersion = 'github:angular/platform-server-builds';
}
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
+ return Promise.resolve();
+ }
+
return Promise.resolve()
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson['apps'][0];
diff --git a/tests/e2e/tests/build/polyfills.ts b/tests/e2e/tests/build/polyfills.ts
index a00445c34843..2fae001ff3e0 100644
--- a/tests/e2e/tests/build/polyfills.ts
+++ b/tests/e2e/tests/build/polyfills.ts
@@ -1,14 +1,8 @@
import { expectFileToMatch } from '../../utils/fs';
import { ng } from '../../utils/process';
-import { getGlobalVariable } from '../../utils/env';
import { oneLineTrim } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => ng('build'))
// files were created successfully
diff --git a/tests/e2e/tests/build/rebuild-error.ts b/tests/e2e/tests/build/rebuild-error.ts
index 5da761dd1e76..ea20919d3a88 100644
--- a/tests/e2e/tests/build/rebuild-error.ts
+++ b/tests/e2e/tests/build/rebuild-error.ts
@@ -26,8 +26,8 @@ export default function () {
return Promise.resolve();
}
- // Skip in non-nightly tests. Switch this check around when ng5 is out.
- if (!getGlobalVariable('argv').nightly) {
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
return Promise.resolve();
}
@@ -37,13 +37,14 @@ export default function () {
// Save the original contents of `./src/app/app.component.ts`.
.then(() => readFile('./src/app/app.component.ts'))
.then((contents) => origContent = contents)
- // Add a major error on a non-main file to the initial build.
- .then(() => writeFile('src/app/app.component.ts', ''))
+ // Add a major static analysis error on a non-main file to the initial build.
+ .then(() => replaceInFile('./src/app/app.component.ts', `'app-root'`, `(() => 'app-root')()`))
// Should have an error.
.then(() => execAndWaitForOutputToMatch('ng', ['serve', '--aot'], failedRe))
.then((results) => {
const stderr = results.stderr;
- if (!stderr.includes(`Unexpected value 'AppComponent`)) {
+ if (!stderr.includes('Function calls are not supported')
+ && !stderr.includes('Function expressions are not supported in decorators')) {
throw new Error(`Expected static analysis error, got this instead:\n${stderr}`);
}
if (extraErrors.some((e) => stderr.includes(e))) {
@@ -76,18 +77,19 @@ export default function () {
// have an error message in 5s.
.then(() => Promise.all([
expectToFail(() => waitForAnyProcessOutputToMatch(errorRe, 5000)),
- replaceInFile('src/app/app.component.ts', ']]]]]', '')
+ writeFile('src/app/app.component.ts', origContent)
]))
.then(() => wait(2000))
- // Add a major error on a rebuild.
+ // Add a major static analysis error on a rebuild.
// Should fail the rebuild.
.then(() => Promise.all([
waitForAnyProcessOutputToMatch(failedRe, 20000),
- writeFile('src/app/app.component.ts', '')
+ replaceInFile('./src/app/app.component.ts', `'app-root'`, `(() => 'app-root')()`)
]))
.then((results) => {
const stderr = results[0].stderr;
- if (!stderr.includes(`Unexpected value 'AppComponent`)) {
+ if (!stderr.includes('Function calls are not supported')
+ && !stderr.includes('Function expressions are not supported in decorators')) {
throw new Error(`Expected static analysis error, got this instead:\n${stderr}`);
}
if (extraErrors.some((e) => stderr.includes(e))) {
diff --git a/tests/e2e/tests/build/rebuild-ngfactories.ts b/tests/e2e/tests/build/rebuild-ngfactories.ts
index 59969db5ed4b..e03ede0f9f4f 100644
--- a/tests/e2e/tests/build/rebuild-ngfactories.ts
+++ b/tests/e2e/tests/build/rebuild-ngfactories.ts
@@ -18,6 +18,11 @@ export default function () {
return Promise.resolve();
}
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
+ return Promise.resolve();
+ }
+
return execAndWaitForOutputToMatch('ng', ['serve', '--aot'], validBundleRegEx)
.then(() => writeMultipleFiles({
'src/app/app.component.css': `
@@ -70,8 +75,8 @@ export default function () {
}
})
.then(() => {
- // Skip in non-nightly tests. Switch this check around when ng5 is out.
- if (!getGlobalVariable('argv').nightly) {
+ // Skip this part of the test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
return Promise.resolve();
}
diff --git a/tests/e2e/tests/build/script-target.ts b/tests/e2e/tests/build/script-target.ts
index f3d847141d30..b3175a2f0ed5 100644
--- a/tests/e2e/tests/build/script-target.ts
+++ b/tests/e2e/tests/build/script-target.ts
@@ -1,9 +1,15 @@
import { expectFileToMatch } from '../../utils/fs';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
+import { getGlobalVariable } from '../../utils/env';
export default function () {
+ // Skip this test in Angular 2, it had different bundles.
+ if (getGlobalVariable('argv').ng2) {
+ return Promise.resolve();
+ }
+
return Promise.resolve()
.then(() => updateJsonFile('tsconfig.json', configJson => {
const compilerOptions = configJson['compilerOptions'];
diff --git a/tests/e2e/tests/build/service-worker.ts b/tests/e2e/tests/build/service-worker.ts
index 8a2c7aebfbae..33c6bf90158a 100644
--- a/tests/e2e/tests/build/service-worker.ts
+++ b/tests/e2e/tests/build/service-worker.ts
@@ -1,7 +1,7 @@
import {join} from 'path';
import {getGlobalVariable} from '../../utils/env';
import {expectFileNotToExist, expectFileToExist, expectFileToMatch, writeFile} from '../../utils/fs';
-import {ng, silentNpm} from '../../utils/process';
+import {ng, npm, silentNpm} from '../../utils/process';
const MANIFEST = {
index: '/index.html',
@@ -42,5 +42,11 @@ export default function() {
.then(() => expectFileToMatch('dist/ngsw.json', /"\/foo\/bar\/index.html"/))
.then(() => ng('build', '--prod', '--service-worker=false'))
.then(() => expectFileNotToExist('dist/ngsw.json'))
+ .then(() => ng('eject', '--prod'))
+ .then(() => silentNpm('install'))
+ .then(() => npm('run', 'build'))
+ .then(() => expectFileToMatch('package.json', /"sw-config"/))
+ .then(() => expectFileToExist(join(process.cwd(), 'dist/ngsw-worker.js')))
+ .then(() => expectFileToExist(join(process.cwd(), 'dist/ngsw.json')))
.then(() => ng('set', 'apps.0.serviceWorker=false'));
}
diff --git a/tests/e2e/tests/build/sourcemap.ts b/tests/e2e/tests/build/sourcemap.ts
index 4e831558d9c4..2eb1ee84793c 100644
--- a/tests/e2e/tests/build/sourcemap.ts
+++ b/tests/e2e/tests/build/sourcemap.ts
@@ -1,15 +1,9 @@
import {ng} from '../../utils/process';
import {expectFileToExist} from '../../utils/fs';
import {expectToFail} from '../../utils/utils';
-import {getGlobalVariable} from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return ng('build', '--sourcemaps')
.then(() => expectFileToExist('dist/main.bundle.js.map'))
diff --git a/tests/e2e/tests/build/styles/extract-css.ts b/tests/e2e/tests/build/styles/extract-css.ts
index 834b16dbba25..828d4cce8fd3 100644
--- a/tests/e2e/tests/build/styles/extract-css.ts
+++ b/tests/e2e/tests/build/styles/extract-css.ts
@@ -6,15 +6,9 @@ import {
import { ng } from '../../../utils/process';
import { updateJsonFile } from '../../../utils/project';
import { expectToFail } from '../../../utils/utils';
-import { getGlobalVariable } from '../../../utils/env';
import { oneLineTrim } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => writeMultipleFiles({
'src/string-style.css': '.string-style { color: red }',
diff --git a/tests/e2e/tests/build/styles/inline-urls.ts b/tests/e2e/tests/build/styles/inline-urls.ts
new file mode 100644
index 000000000000..7ba0936832d1
--- /dev/null
+++ b/tests/e2e/tests/build/styles/inline-urls.ts
@@ -0,0 +1,62 @@
+import { ng, silentNpm } from '../../../utils/process';
+import {
+ expectFileToMatch,
+ expectFileToExist,
+ expectFileMatchToExist,
+ writeMultipleFiles
+} from '../../../utils/fs';
+import { copyProjectAsset } from '../../../utils/assets';
+import { expectToFail } from '../../../utils/utils';
+import { updateJsonFile } from '../../../utils/project';
+
+const imgSvg = `
+
+
+
+`;
+
+export default function () {
+ return Promise.resolve()
+ .then(() => silentNpm('install', 'font-awesome@4.7.0'))
+ .then(() => writeMultipleFiles({
+ 'src/styles.scss': `
+ $fa-font-path: "~font-awesome/fonts";
+ @import "~font-awesome/scss/font-awesome";
+ h1 { background: url('./assets/large.png'); }
+ h2 { background: url('./assets/small.svg'); }
+ p { background: url('./assets/small-id.svg#testID'); }
+ `,
+ 'src/app/app.component.css': `
+ h3 { background: url('../assets/small.svg'); }
+ h4 { background: url('../assets/large.png'); }
+ `,
+ 'src/assets/small.svg': imgSvg,
+ 'src/assets/small-id.svg': imgSvg
+ }))
+ .then(() => copyProjectAsset('images/spectrum.png', './assets/large.png'))
+ .then(() => updateJsonFile('.angular-cli.json', configJson => {
+ const app = configJson['apps'][0];
+ app['styles'] = ['styles.scss'];
+ }))
+ .then(() => ng('build', '--extract-css', '--aot'))
+ .then(({ stdout }) => {
+ if (stdout.match(/postcss-url: \.+: Can't read file '\.+', ignoring/)) {
+ throw new Error('Expected no postcss-url file read warnings.');
+ }
+ })
+ // Check paths are correctly generated.
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ /url\([\'"]?large\.[0-9a-f]{20}\.png[\'"]?\)/))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ /url\(\\?[\'"]data:image\/svg\+xml/))
+ .then(() => expectFileToMatch('dist/styles.bundle.css',
+ /url\([\'"]?small-id\.[0-9a-f]{20}\.svg#testID[\'"]?\)/))
+ .then(() => expectFileToMatch('dist/main.bundle.js',
+ /url\(\\?[\'"]data:image\/svg\+xml/))
+ .then(() => expectFileToMatch('dist/main.bundle.js',
+ /url\([\'"]?large\.[0-9a-f]{20}\.png[\'"]?\)/))
+ // Check files are correctly created.
+ .then(() => expectToFail(() => expectFileToExist('dist/small.svg')))
+ .then(() => expectFileMatchToExist('./dist', /large\.[0-9a-f]{20}\.png/))
+ .then(() => expectFileMatchToExist('./dist', /small-id\.[0-9a-f]{20}\.svg/));
+}
diff --git a/tests/e2e/tests/build/styles/material-import.ts b/tests/e2e/tests/build/styles/material-import.ts
new file mode 100644
index 000000000000..d739502a0bc0
--- /dev/null
+++ b/tests/e2e/tests/build/styles/material-import.ts
@@ -0,0 +1,37 @@
+import {
+ writeMultipleFiles,
+ replaceInFile
+} from '../../../utils/fs';
+import { ng, silentNpm } from '../../../utils/process';
+import { stripIndents } from 'common-tags';
+import { updateJsonFile } from '../../../utils/project';
+
+export default function () {
+ const extensions = ['css', 'scss', 'less', 'styl'];
+ let promise: Promise = Promise.resolve()
+ .then(() => silentNpm('install', '@angular/material@5.0.4'));
+
+ extensions.forEach(ext => {
+ promise = promise.then(() => {
+ return writeMultipleFiles({
+ [`src/styles.${ext}`]: stripIndents`
+ @import "~@angular/material/prebuilt-themes/indigo-pink.css";
+ `,
+ [`src/app/app.component.${ext}`]: stripIndents`
+ @import "~@angular/material/prebuilt-themes/indigo-pink.css";
+ `,
+ })
+ // change files to use preprocessor
+ .then(() => updateJsonFile('.angular-cli.json', configJson => {
+ const app = configJson['apps'][0];
+ app['styles'] = [`styles.${ext}`];
+ }))
+ .then(() => replaceInFile('src/app/app.component.ts',
+ './app.component.css', `./app.component.${ext}`))
+ // run build app
+ .then(() => ng('build', '--extract-css', '--sourcemap'));
+ });
+ });
+
+ return promise;
+}
diff --git a/tests/e2e/tests/build/styles/postcss.ts b/tests/e2e/tests/build/styles/postcss.ts
index 08600f69d6eb..14636a95c7de 100644
--- a/tests/e2e/tests/build/styles/postcss.ts
+++ b/tests/e2e/tests/build/styles/postcss.ts
@@ -1,15 +1,9 @@
import * as glob from 'glob';
import { writeFile, expectFileToMatch } from '../../../utils/fs';
import { ng } from '../../../utils/process';
-import { getGlobalVariable } from '../../../utils/env';
import { stripIndents } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return writeFile('src/styles.css', stripIndents`
/* normal-comment */
/*! important-comment */
diff --git a/tests/e2e/tests/commands/new/new-routing.ts b/tests/e2e/tests/commands/new/new-routing.ts
index 953aa16190cc..1726abad6c21 100644
--- a/tests/e2e/tests/commands/new/new-routing.ts
+++ b/tests/e2e/tests/commands/new/new-routing.ts
@@ -1,14 +1,8 @@
import {ng} from '../../../utils/process';
import {createProject} from '../../../utils/project';
-import { getGlobalVariable } from '../../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => createProject('routing-project', '--routing'))
diff --git a/tests/e2e/tests/commands/new/new-skip-commit.ts b/tests/e2e/tests/commands/new/new-skip-commit.ts
index c57e34b67f48..95a4328f21f8 100644
--- a/tests/e2e/tests/commands/new/new-skip-commit.ts
+++ b/tests/e2e/tests/commands/new/new-skip-commit.ts
@@ -2,15 +2,9 @@ import {ng} from '../../../utils/process';
import {createProject} from '../../../utils/project';
import {expectToFail} from '../../../utils/utils';
import {expectGitToBeClean} from '../../../utils/git';
-import {getGlobalVariable} from '../../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => createProject('new-project', '--skip-commit'))
.then(() => expectToFail(() => expectGitToBeClean()))
diff --git a/tests/e2e/tests/commands/new/new-skip-tests.ts b/tests/e2e/tests/commands/new/new-skip-tests.ts
index 62c5328b8575..95dde0a38e88 100644
--- a/tests/e2e/tests/commands/new/new-skip-tests.ts
+++ b/tests/e2e/tests/commands/new/new-skip-tests.ts
@@ -1,14 +1,8 @@
import {createProject} from '../../../utils/project';
import {expectFileNotToExist} from '../../../utils/fs';
-import {getGlobalVariable} from '../../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => createProject('new-project-skip-tests', '--skip-tests'))
.then(() => expectFileNotToExist('src/app/app.component.spec.ts'));
diff --git a/tests/e2e/tests/i18n/build-locale.ts b/tests/e2e/tests/i18n/build-locale.ts
index 4f68d6ea37d4..033e425a499e 100644
--- a/tests/e2e/tests/i18n/build-locale.ts
+++ b/tests/e2e/tests/i18n/build-locale.ts
@@ -5,9 +5,8 @@ import { expectToFail } from '../../utils/utils';
export default function () {
- // Check if register locale works in ng5 prod builds
- // This check should be changed once ng5 because the default.
- if (!getGlobalVariable('argv').nightly) {
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
return Promise.resolve();
}
@@ -18,5 +17,9 @@ export default function () {
.then(() => expectFileToMatch('dist/main.bundle.js', /registerLocaleData/))
.then(() => expectFileToMatch('dist/main.bundle.js', /angular_common_locales_fr/))
.then(() => rimraf('dist'))
- .then(() => expectToFail(() => ng('build', '--aot', '--locale=no-locale')))
+ .then(() => ng('build', '--aot', '--locale=fr_FR'))
+ .then(() => expectFileToMatch('dist/main.bundle.js', /registerLocaleData/))
+ .then(() => expectFileToMatch('dist/main.bundle.js', /angular_common_locales_fr/))
+ .then(() => rimraf('dist'))
+ .then(() => expectToFail(() => ng('build', '--aot', '--locale=no-locale')));
}
diff --git a/tests/e2e/tests/i18n/extract-locale.ts b/tests/e2e/tests/i18n/extract-locale.ts
index 16df41a68957..1916973ed244 100644
--- a/tests/e2e/tests/i18n/extract-locale.ts
+++ b/tests/e2e/tests/i18n/extract-locale.ts
@@ -1,9 +1,6 @@
import { join } from 'path';
import { ng } from '../../utils/process';
-import {
- expectFileToExist, writeFile,
- expectFileToMatch
-} from '../../utils/fs';
+import { writeFile, expectFileToMatch } from '../../utils/fs';
export default function() {
@@ -14,8 +11,7 @@ export default function() {
.then(() => ng('xi18n', '--locale', 'fr'))
.then((output) => {
if (!output.stdout.match(/starting from Angular v4/)) {
- expectFileToExist(join('src', 'messages.xlf'));
- expectFileToMatch(join('src', 'messages.xlf'), /source-language="fr"/);
+ return expectFileToMatch(join('src', 'messages.xlf'), 'source-language="fr"');
}
});
}
diff --git a/tests/e2e/tests/i18n/extract-outfile.ts b/tests/e2e/tests/i18n/extract-outfile.ts
index 444c0e1c70fc..2948b6a17d85 100644
--- a/tests/e2e/tests/i18n/extract-outfile.ts
+++ b/tests/e2e/tests/i18n/extract-outfile.ts
@@ -1,9 +1,6 @@
import {join} from 'path';
import {ng} from '../../utils/process';
-import {
- expectFileToExist, writeFile,
- expectFileToMatch
-} from '../../utils/fs';
+import { writeFile, expectFileToMatch } from '../../utils/fs';
export default function() {
@@ -14,8 +11,7 @@ export default function() {
.then(() => ng('xi18n', '--out-file', 'messages.fr.xlf'))
.then((output) => {
if (!output.stdout.match(/starting from Angular v4/)) {
- expectFileToExist(join('src', 'messages.fr.xlf'));
- expectFileToMatch(join('src', 'messages.fr.xlf'), /Hello world/);
+ return expectFileToMatch(join('src', 'messages.fr.xlf'), 'Hello world');
}
});
}
diff --git a/tests/e2e/tests/lint/lint-no-config-section.ts b/tests/e2e/tests/lint/lint-no-config-section.ts
index 79378681cae1..d2bfc1e4992d 100644
--- a/tests/e2e/tests/lint/lint-no-config-section.ts
+++ b/tests/e2e/tests/lint/lint-no-config-section.ts
@@ -1,13 +1,7 @@
import { ng } from '../../utils/process';
-import { getGlobalVariable } from '../../utils/env';
import { oneLine } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => ng('set', 'lint', '[]'))
.then(() => ng('lint'))
diff --git a/tests/e2e/tests/lint/lint-no-project.ts b/tests/e2e/tests/lint/lint-no-project.ts
index 9e374ef040e4..d558a76c8d50 100644
--- a/tests/e2e/tests/lint/lint-no-project.ts
+++ b/tests/e2e/tests/lint/lint-no-project.ts
@@ -1,15 +1,9 @@
import { ng } from '../../utils/process';
import { writeFile } from '../../utils/fs';
import { expectToFail } from '../../utils/utils';
-import { getGlobalVariable } from '../../utils/env';
import { oneLine } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => ng('set', 'lint.0.project', ''))
.then(() => ng('lint', '--type-check'))
diff --git a/tests/e2e/tests/lint/lint-with-exclude.ts b/tests/e2e/tests/lint/lint-with-exclude.ts
index be792e2e9530..bcf193acc692 100644
--- a/tests/e2e/tests/lint/lint-with-exclude.ts
+++ b/tests/e2e/tests/lint/lint-with-exclude.ts
@@ -1,14 +1,8 @@
import { ng } from '../../utils/process';
import { writeFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
import { oneLine } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
const fileName = 'src/app/foo.ts';
return Promise.resolve()
diff --git a/tests/e2e/tests/lint/lint-with-force.ts b/tests/e2e/tests/lint/lint-with-force.ts
index ac3f2975e663..1f40b16a2346 100644
--- a/tests/e2e/tests/lint/lint-with-force.ts
+++ b/tests/e2e/tests/lint/lint-with-force.ts
@@ -1,14 +1,8 @@
import { ng } from '../../utils/process';
import { writeFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
import { oneLine } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
const fileName = 'src/app/foo.ts';
return Promise.resolve()
diff --git a/tests/e2e/tests/lint/lint-with-format-by-aliases.ts b/tests/e2e/tests/lint/lint-with-format-by-aliases.ts
index 067adb1640f6..cb0d76c12827 100644
--- a/tests/e2e/tests/lint/lint-with-format-by-aliases.ts
+++ b/tests/e2e/tests/lint/lint-with-format-by-aliases.ts
@@ -1,14 +1,8 @@
import { ng } from '../../utils/process';
import { writeFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
import { oneLine } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
const fileName = 'src/app/foo.ts';
return Promise.resolve()
diff --git a/tests/e2e/tests/lint/lint-with-format.ts b/tests/e2e/tests/lint/lint-with-format.ts
index ed21f1ae87a1..50ee8b5454a9 100644
--- a/tests/e2e/tests/lint/lint-with-format.ts
+++ b/tests/e2e/tests/lint/lint-with-format.ts
@@ -1,14 +1,8 @@
import { ng } from '../../utils/process';
import { writeFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
import { oneLine } from 'common-tags';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
const fileName = 'src/app/foo.ts';
return Promise.resolve()
diff --git a/tests/e2e/tests/lint/lint-with-nested-configs.ts b/tests/e2e/tests/lint/lint-with-nested-configs.ts
index d0580fa8f114..951c9f4aaccd 100644
--- a/tests/e2e/tests/lint/lint-with-nested-configs.ts
+++ b/tests/e2e/tests/lint/lint-with-nested-configs.ts
@@ -1,14 +1,9 @@
import { createDir, writeFile } from '../../utils/fs';
import { ng } from '../../utils/process';
import { expectToFail } from '../../utils/utils';
-import { getGlobalVariable } from '../../utils/env';
-export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function () {
const fileName = 'src/app/foo/foo.ts';
const nestedConfigContent = `
{
diff --git a/tests/e2e/tests/lint/lint-with-type-check-fail.ts b/tests/e2e/tests/lint/lint-with-type-check-fail.ts
index 9d545f7cfec0..965a18559d07 100644
--- a/tests/e2e/tests/lint/lint-with-type-check-fail.ts
+++ b/tests/e2e/tests/lint/lint-with-type-check-fail.ts
@@ -1,14 +1,9 @@
import { ng } from '../../utils/process';
import { expectToFail } from '../../utils/utils';
import { writeFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
-export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function () {
const fileName = 'src/app/foo.ts';
const fileContents = `
const ANIMATION_CSS_VALUE_REGEX = 'asda';
diff --git a/tests/e2e/tests/lint/lint-with-type-check.ts b/tests/e2e/tests/lint/lint-with-type-check.ts
index 59b8642cf6f8..ac6dfc761ba9 100644
--- a/tests/e2e/tests/lint/lint-with-type-check.ts
+++ b/tests/e2e/tests/lint/lint-with-type-check.ts
@@ -1,13 +1,8 @@
import { ng } from '../../utils/process';
import { writeFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
-export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function () {
const fileName = 'src/app/foo.ts';
const fileContents = `
const ANIMATION_CSS_VALUE_REGEX = 'asda';
diff --git a/tests/e2e/tests/misc/coverage.ts b/tests/e2e/tests/misc/coverage.ts
index 280a5cca8458..f7e008b55072 100644
--- a/tests/e2e/tests/misc/coverage.ts
+++ b/tests/e2e/tests/misc/coverage.ts
@@ -2,15 +2,9 @@ import {expectFileToExist, expectFileToMatch} from '../../utils/fs';
import {updateJsonFile} from '../../utils/project';
import {expectToFail} from '../../utils/utils';
import {ng} from '../../utils/process';
-import {getGlobalVariable} from '../../utils/env';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return ng('test', '--single-run', '--code-coverage')
.then(() => expectFileToExist('coverage/src/app'))
.then(() => expectFileToExist('coverage/lcov.info'))
diff --git a/tests/e2e/tests/misc/default-port.ts b/tests/e2e/tests/misc/default-port.ts
index a010173f2907..a9e6ef9bc590 100644
--- a/tests/e2e/tests/misc/default-port.ts
+++ b/tests/e2e/tests/misc/default-port.ts
@@ -2,14 +2,9 @@ import { request } from '../../utils/http';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
import { updateJsonFile } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
-export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function() {
return Promise.resolve()
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson.defaults;
diff --git a/tests/e2e/tests/misc/deploy-url.ts b/tests/e2e/tests/misc/deploy-url.ts
index ef2393f3b33f..b87f94060480 100644
--- a/tests/e2e/tests/misc/deploy-url.ts
+++ b/tests/e2e/tests/misc/deploy-url.ts
@@ -1,15 +1,9 @@
import { killAllProcesses } from '../../utils/process';
import { request } from '../../utils/http';
import { ngServe, updateJsonFile } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
import { writeMultipleFiles } from '../../utils/fs';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => writeMultipleFiles({
'src/string-script.js': 'console.log(\'string-script\'); var number = 1+1;',
diff --git a/tests/e2e/tests/misc/different-file-format.ts b/tests/e2e/tests/misc/different-file-format.ts
index df2fe4ff4216..9f1abbb7eab5 100644
--- a/tests/e2e/tests/misc/different-file-format.ts
+++ b/tests/e2e/tests/misc/different-file-format.ts
@@ -1,6 +1,5 @@
import {ng} from '../../utils/process';
import * as fs from '../../utils/fs';
-import {getGlobalVariable} from '../../utils/env';
const options = {
@@ -9,11 +8,6 @@ const options = {
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => fs.prependToFile('./src/tsconfig.app.json', '\ufeff', options))
.then(() => fs.prependToFile('./.angular-cli.json', '\ufeff', options))
diff --git a/tests/e2e/tests/misc/fallback.ts b/tests/e2e/tests/misc/fallback.ts
index c3cf7067aa6c..6c3cefe86864 100644
--- a/tests/e2e/tests/misc/fallback.ts
+++ b/tests/e2e/tests/misc/fallback.ts
@@ -3,15 +3,9 @@ import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
import { updateJsonFile } from '../../utils/project';
import { moveFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
// should fallback to config.app[0].index (index.html by default)
return Promise.resolve()
.then(() => ngServe())
diff --git a/tests/e2e/tests/misc/ssl-default-config.ts b/tests/e2e/tests/misc/ssl-default-config.ts
index c87641a54d11..4d77c22d9d88 100644
--- a/tests/e2e/tests/misc/ssl-default-config.ts
+++ b/tests/e2e/tests/misc/ssl-default-config.ts
@@ -2,14 +2,9 @@ import { request } from '../../utils/http';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
import { updateJsonFile } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
-export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function() {
return Promise.resolve()
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson.defaults;
diff --git a/tests/e2e/tests/misc/ssl-default.ts b/tests/e2e/tests/misc/ssl-default.ts
index 5f32001067ec..80c3952b16ab 100644
--- a/tests/e2e/tests/misc/ssl-default.ts
+++ b/tests/e2e/tests/misc/ssl-default.ts
@@ -1,15 +1,9 @@
import { request } from '../../utils/http';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- 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-config.ts b/tests/e2e/tests/misc/ssl-with-cert-config.ts
index 50e03f2485ce..7d14478e0a29 100644
--- a/tests/e2e/tests/misc/ssl-with-cert-config.ts
+++ b/tests/e2e/tests/misc/ssl-with-cert-config.ts
@@ -3,14 +3,9 @@ import { assetDir } from '../../utils/assets';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
import { updateJsonFile } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
-export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function() {
return Promise.resolve()
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson.defaults;
diff --git a/tests/e2e/tests/misc/ssl-with-cert.ts b/tests/e2e/tests/misc/ssl-with-cert.ts
index de2e0c90ca17..e15aaed9d2b8 100644
--- a/tests/e2e/tests/misc/ssl-with-cert.ts
+++ b/tests/e2e/tests/misc/ssl-with-cert.ts
@@ -2,15 +2,9 @@ import { request } from '../../utils/http';
import { assetDir } from '../../utils/assets';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
export default function() {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => ngServe(
'--ssl', 'true',
diff --git a/tests/e2e/tests/misc/typescript-warning.ts b/tests/e2e/tests/misc/typescript-warning.ts
index 6b8735a3de34..1b247eea264a 100644
--- a/tests/e2e/tests/misc/typescript-warning.ts
+++ b/tests/e2e/tests/misc/typescript-warning.ts
@@ -3,15 +3,12 @@ import { getGlobalVariable } from '../../utils/env';
export default function () {
- // typescript@2.5 is not part of the officially supported range in latest stable.
- // Update as needed.
- let unsupportedTsVersion = '2.5';
+ // typescript@2.7.0-dev.20180104 is not part of the officially supported range in latest stable.
+ let unsupportedTsVersion = '2.7.0-dev.20180104';
- // TODO: re-enable for ng5, adjust as needed. This test fails on ng5 because the 2.5 is supported.
- // When ng5 because the default this test will need to be adjusted to use 2.3 as the unsupported
- // version, and to disable the experimental angular compiler (transforms need 2.4 minimum).
- if (getGlobalVariable('argv').nightly) {
- return;
+ // Skip this test in Angular 2/4.
+ if (getGlobalVariable('argv').ng2 || getGlobalVariable('argv').ng4) {
+ return Promise.resolve();
}
return Promise.resolve()
diff --git a/tests/e2e/tests/packages/webpack/server-ng5.ts b/tests/e2e/tests/packages/webpack/server-ng5.ts
new file mode 100644
index 000000000000..021b984508d3
--- /dev/null
+++ b/tests/e2e/tests/packages/webpack/server-ng5.ts
@@ -0,0 +1,23 @@
+import { normalize } from 'path';
+import { createProjectFromAsset } from '../../../utils/assets';
+import { exec } from '../../../utils/process';
+import { expectFileToMatch, rimraf } from '../../../utils/fs';
+
+
+export default function (skipCleaning: () => void) {
+ return Promise.resolve()
+ .then(() => createProjectFromAsset('webpack/test-server-app'))
+ .then(() => exec(normalize('node_modules/.bin/webpack')))
+ .then(() => expectFileToMatch('dist/app.main.js',
+ new RegExp('MyInjectable.ctorParameters = .*'
+ + 'type: undefined, decorators.*Inject.*args: .*DOCUMENT.*'))
+ .then(() => expectFileToMatch('dist/app.main.js',
+ new RegExp('AppComponent.ctorParameters = .*MyInjectable'))
+ .then(() => expectFileToMatch('dist/app.main.js',
+ /AppModule \*\/\].*\.testProp = \'testing\'/))
+ .then(() => expectFileToMatch('dist/app.main.js',
+ /platformServer \*\/\]\)\(\)\.bootstrapModuleFactory\(.*\/\* AppModuleNgFactory \*\/\]/))
+ .then(() => expectFileToMatch('dist/app.main.js',
+ /renderModuleFactory \*\/\].*\/\* AppModuleNgFactory \*\/\]/))
+ .then(() => skipCleaning());
+}
diff --git a/tests/e2e/tests/test/e2e-baseurl.ts b/tests/e2e/tests/test/e2e-baseurl.ts
index 8a70d4ef6197..c6a66d23e0d3 100644
--- a/tests/e2e/tests/test/e2e-baseurl.ts
+++ b/tests/e2e/tests/test/e2e-baseurl.ts
@@ -2,14 +2,9 @@ import { ng, killAllProcesses } from '../../utils/process';
import { expectToFail } from '../../utils/utils';
import { ngServe } from '../../utils/project';
import { updateJsonFile } from '../../utils/project';
-import { getGlobalVariable } from '../../utils/env';
-export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function () {
return Promise.resolve()
.then(() => expectToFail(() => ng('e2e', '--no-serve')))
.then(() => updateJsonFile('.angular-cli.json', configJson => {
diff --git a/tests/e2e/tests/test/test-assets.ts b/tests/e2e/tests/test/test-assets.ts
index adf3ee27328c..12d247aad6ef 100644
--- a/tests/e2e/tests/test/test-assets.ts
+++ b/tests/e2e/tests/test/test-assets.ts
@@ -2,16 +2,10 @@ import { writeMultipleFiles } from '../../utils/fs';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
-import { getGlobalVariable } from '../../utils/env';
import { stripIndent } from 'common-tags';
// Make sure asset files are served
export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
-
return Promise.resolve()
.then(() => writeMultipleFiles({
'src/assets/file.txt': 'assets-folder-content',
diff --git a/tests/e2e/tests/test/test-backwards-compat.ts b/tests/e2e/tests/test/test-backwards-compat.ts
index 067f19b9c31e..aaac37583e5e 100644
--- a/tests/e2e/tests/test/test-backwards-compat.ts
+++ b/tests/e2e/tests/test/test-backwards-compat.ts
@@ -1,13 +1,8 @@
import { ng } from '../../utils/process';
import { replaceInFile } from '../../utils/fs';
-import { getGlobalVariable } from '../../utils/env';
-export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function () {
// Old configs (with the cli preprocessor listed) should still supported.
return Promise.resolve()
.then(() => replaceInFile('karma.conf.js',
diff --git a/tests/e2e/tests/test/test-scripts.ts b/tests/e2e/tests/test/test-scripts.ts
index 4ca07efd65db..bf42a46d1d42 100644
--- a/tests/e2e/tests/test/test-scripts.ts
+++ b/tests/e2e/tests/test/test-scripts.ts
@@ -2,15 +2,10 @@ import { writeMultipleFiles } from '../../utils/fs';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
-import { getGlobalVariable } from '../../utils/env';
import { stripIndent } from 'common-tags';
-export default function () {
- // Skip this in Appveyor tests.
- if (getGlobalVariable('argv').appveyor) {
- return Promise.resolve();
- }
+export default function () {
return Promise.resolve()
.then(() => ng('test', '--watch=false'))
// prepare global scripts test files
diff --git a/tests/e2e/tests/third-party/bootstrap.ts b/tests/e2e/tests/third-party/bootstrap.ts
index 9be757f279e9..c3fadd070b7c 100644
--- a/tests/e2e/tests/third-party/bootstrap.ts
+++ b/tests/e2e/tests/third-party/bootstrap.ts
@@ -6,7 +6,7 @@ import {oneLineTrim} from 'common-tags';
export default function() {
return Promise.resolve()
- .then(() => silentNpm('install', 'bootstrap@next'))
+ .then(() => silentNpm('install', 'bootstrap@4.0.0-beta.3'))
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson['apps'][0];
app['styles'].push('../node_modules/bootstrap/dist/css/bootstrap.css');
@@ -23,5 +23,19 @@ export default function() {
+ `))
+ .then(() => ng(
+ 'build',
+ '--prod',
+ '--extract-css',
+ '--output-hashing=none'
+ ))
+ .then(() => expectFileToMatch('dist/scripts.bundle.js', 'jQuery'))
+ .then(() => expectFileToMatch('dist/styles.bundle.css', '* Bootstrap'))
+ .then(() => expectFileToMatch('dist/index.html', oneLineTrim`
+
+
+
+
`));
}
diff --git a/tests/e2e/utils/assets.ts b/tests/e2e/utils/assets.ts
index d1a8e0a98ce2..72db65f90ef6 100644
--- a/tests/e2e/utils/assets.ts
+++ b/tests/e2e/utils/assets.ts
@@ -11,6 +11,13 @@ export function assetDir(assetName: string) {
return join(__dirname, '../assets', assetName);
}
+export function copyProjectAsset(assetName: string, to?: string) {
+ const tempRoot = join(getGlobalVariable('tmp-root'), 'test-project', 'src');
+ const sourcePath = assetDir(assetName);
+ const targetPath = join(tempRoot, to || assetName);
+
+ return copyFile(sourcePath, targetPath);
+}
export function copyAssets(assetName: string) {
const tempRoot = join(getGlobalVariable('tmp-root'), 'assets', assetName);
diff --git a/tests/e2e/utils/project.ts b/tests/e2e/utils/project.ts
index a11784cfbd12..446375fab4fd 100644
--- a/tests/e2e/utils/project.ts
+++ b/tests/e2e/utils/project.ts
@@ -42,6 +42,7 @@ export function createProject(name: string, ...args: string[]) {
.then(() => useCIChrome())
.then(() => useCIDefaults())
.then(() => argv['ng2'] ? useNg2() : Promise.resolve())
+ .then(() => argv['ng4'] ? useNg4() : Promise.resolve())
.then(() => argv.nightly || argv['ng-sha'] ? useSha() : Promise.resolve())
.then(() => console.log(`Project ${name} created... Installing npm.`))
.then(() => silentNpm('install'));
@@ -139,7 +140,7 @@ export function useCIDefaults() {
sourcemaps: false,
progress: false
};
- })
+ });
}
export function useCIChrome() {
@@ -172,7 +173,7 @@ export function useCIChrome() {
.catch(() => null);
}
-// Convert a Angular 4 project to Angular 2.
+// Convert a Angular 5 project to Angular 2.
export function useNg2() {
const ng2Deps: any = {
'dependencies': {
@@ -275,12 +276,53 @@ export function useNg2() {
Object.keys(ng2Deps['devDependencies']).forEach(pkgName => {
json['devDependencies'][pkgName] = ng2Deps['devDependencies'][pkgName];
});
- console.log(JSON.stringify(json))
+ console.log(JSON.stringify(json));
}))
.then(() => updateJsonFile('src/tsconfig.app.json', json =>
Object.assign(json, tsconfigAppJson)))
.then(() => updateJsonFile('src/tsconfig.spec.json', json =>
Object.assign(json, tsconfigSpecJson)))
.then(() => updateJsonFile('e2e/tsconfig.e2e.json', json =>
- Object.assign(json, tsconfigE2eJson)));
+ Object.assign(json, tsconfigE2eJson)))
+ .then(() => replaceInFile('src/test.ts', 'import \'zone.js/dist/zone-testing\';', `
+ import 'zone.js/dist/long-stack-trace-zone';
+ import 'zone.js/dist/proxy.js';
+ import 'zone.js/dist/sync-test';
+ import 'zone.js/dist/jasmine-patch';
+ import 'zone.js/dist/async-test';
+ import 'zone.js/dist/fake-async-test';
+ `));
+}
+
+// Convert a Angular 5 project to Angular 4.
+export function useNg4() {
+ const ng4Deps: any = {
+ 'dependencies': {
+ '@angular/common': '^4.4.6',
+ '@angular/compiler': '^4.4.6',
+ '@angular/core': '^4.4.6',
+ '@angular/forms': '^4.4.6',
+ '@angular/http': '^4.4.6',
+ '@angular/platform-browser': '^4.4.6',
+ '@angular/platform-browser-dynamic': '^4.4.6',
+ '@angular/router': '^4.4.6',
+ 'zone.js': '^0.8.14'
+ },
+ 'devDependencies': {
+ '@angular/compiler-cli': '^4.4.6',
+ 'typescript': '~2.3.3'
+ }
+ };
+
+
+ return Promise.resolve()
+ .then(() => updateJsonFile('package.json', json => {
+ Object.keys(ng4Deps['dependencies']).forEach(pkgName => {
+ json['dependencies'][pkgName] = ng4Deps['dependencies'][pkgName];
+ });
+ Object.keys(ng4Deps['devDependencies']).forEach(pkgName => {
+ json['devDependencies'][pkgName] = ng4Deps['devDependencies'][pkgName];
+ });
+ console.log(JSON.stringify(json));
+ }));
}