From ef05a2df856fafe485bd20f8c23e87257e371c64 Mon Sep 17 00:00:00 2001 From: James Zetlen Date: Thu, 4 Oct 2018 04:39:45 -0500 Subject: [PATCH 01/22] Update queries for latest 2.3 schema and add validator script (#318) * fix: update query for small_image schema change * feat(venia): Script to lint queries against schema --- README.md | 12 + package-lock.json | 615 ++++++++++-------- package.json | 2 + .../src/List/__tests__/items.spec.js | 8 +- .../peregrine/src/List/__tests__/list.spec.js | 8 +- packages/venia-concept/package.json | 1 + .../src/RootComponents/Category/category.js | 4 +- .../Gallery/__tests__/gallery.spec.js | 8 +- .../Gallery/__tests__/items.spec.js | 8 +- .../src/components/Gallery/gallery.js | 4 +- .../src/components/Gallery/item.js | 6 +- .../src/components/Gallery/items.js | 4 +- packages/venia-concept/validate-queries.js | 96 +++ 13 files changed, 506 insertions(+), 270 deletions(-) create mode 100644 packages/venia-concept/validate-queries.js diff --git a/README.md b/README.md index bb2d30b4bf0..6feedd3c52b 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,18 @@ Follow these steps to install the dependencies for all the packages in the proje 5. To run the Venia theme development experience, run `npm run watch:venia` from package root. 6. To run the full PWA Studio deeloper experience, with Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds, run `npm run watch:all` from package root. +## Troubleshooting + +### When I run the developer mode, I get validation errors + +Make sure you have created a `.env` file in `packages/venia-concept` which specifies variables for your local development environment. You can copy from the template `packages/venia-concept/.env.dist`. + +### Venia queries to GraphQL produce validation errors + +Venia and its GraphQL queries may be out of sync with the schema of your connected Magento instance. Make sure the Magento instance is up to date with the 2.3 development branch, and your copy of this repository (or your dependency on it) is up to date. + +**To test whether your queries are up to date, run `npm run validate:venia:gql` at project root.** + ## Things not to do When using a monorepo and lerna, it's important that you break some common habits that are common when developing front-end packages. diff --git a/package-lock.json b/package-lock.json index bf3b3744da8..ea1f67bc9b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,9 +81,9 @@ "dev": true }, "@babel/runtime-corejs2": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.0.0.tgz", - "integrity": "sha512-Yww0jXgolNtkhcK+Txo5JN+DjBpNmmAtD7G99HOebhEjBzjnACG09Tip9C8lSOF6PrhA56OeJWeOZduNJaKxBA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz", + "integrity": "sha512-drxaPByExlcRDKW4ZLubUO4ZkI8/8ax9k9wve1aEthdLKFzjB7XRkOQ0xoTIWGxqdDnWDElkjYq77bt7yrcYJQ==", "requires": { "core-js": "^2.5.7", "regenerator-runtime": "^0.12.0" @@ -141,9 +141,9 @@ "dev": true }, "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", + "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", "dev": true } } @@ -521,9 +521,9 @@ } }, "get-stream": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.0.0.tgz", - "integrity": "sha512-FneLKMENeOR7wOK0/ZXCh+lwqtnPwkeunJjRN28LPqzGvNAhYvrTAhXv6xDm4vsJ0M7lcRbIYHQudKsSy2RtSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -1475,6 +1475,15 @@ "webpack-sources": "^1.1.0", "workbox-webpack-plugin": "^3.0.0-beta.1", "write-file-webpack-plugin": "^4.2.0" + }, + "dependencies": { + "graphql": { + "version": "14.0.2", + "bundled": true, + "requires": { + "iterall": "^1.2.2" + } + } } }, "@mrmlnc/readdir-enhanced": { @@ -1858,9 +1867,9 @@ "optional": true }, "@types/node": { - "version": "10.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.11.2.tgz", - "integrity": "sha512-XubfQDIg88PGJ7netQPf3QOKHF7Xht4WXGtg5W7cGBeQs9ETbYKwfchR9o+tRRA9iLTQ7nAre85M205JbYsjJA==" + "version": "10.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.11.4.tgz", + "integrity": "sha512-ojnbBiKkZFYRfQpmtnnWTMw+rzGp/JiystjluW9jgN3VzRwilXddJ6aGQ9V/7iuDG06SBgn7ozW9k3zcAnYjYQ==" }, "@types/zen-observable": { "version": "0.8.0", @@ -1946,9 +1955,9 @@ } }, "acorn-walk": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.0.1.tgz", - "integrity": "sha512-PqVQ8c6a3kyqdsUZlC7nljp3FFuxipBRHKu+7C1h8QygBFlzTaDX5HD383jej3Peed+1aDG8HwkfB1Z1HMNPkw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.0.tgz", + "integrity": "sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg==", "dev": true }, "address": { @@ -2610,7 +2619,7 @@ }, "async": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "async-each": { @@ -2741,7 +2750,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -5093,7 +5102,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -5150,7 +5159,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -5372,7 +5381,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -5710,14 +5719,14 @@ } }, "caniuse-db": { - "version": "1.0.30000887", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000887.tgz", - "integrity": "sha512-yOScC1WJ6ihxxPNeWSqYc2nKHqeHzXMY382yvC0mZdi+kWBrlEdCFeR/T1s5Abe5n51HoD6IA/Gho2T8vnRT2g==" + "version": "1.0.30000889", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000889.tgz", + "integrity": "sha512-Rf9Sbm2KS7s6Rk8iNeI5zJdquqctXBXAfy/bb1tCCYRds5RAaHNdyt2D4z8TSRToDkYsAwiSBV/bFHR+4IgTiw==" }, "caniuse-lite": { - "version": "1.0.30000887", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000887.tgz", - "integrity": "sha512-AHpONWuGFWO8yY9igdXH94tikM6ERS84286r0cAMAXYFtJBk76lhiMhtCxBJNBZsD6hzlvpWZ2AtbVFEkf4JQA==", + "version": "1.0.30000889", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000889.tgz", + "integrity": "sha512-MFxcQ6x/LEEoaIhO7Zdb7Eg8YyNONN+WBnS5ERJ0li2yRw51+i4xXUNxnLaveTb/4ZoJqsWKEmlomhG2pYzlQA==", "dev": true }, "capture-exit": { @@ -5955,7 +5964,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -6087,7 +6096,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -6211,7 +6220,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -7585,6 +7594,30 @@ } } }, + "cross-fetch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", + "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", + "dev": true, + "requires": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "node-fetch": { + "version": "2.1.2", + "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", + "dev": true + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", + "dev": true + } + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -7626,7 +7659,7 @@ }, "css-in-js-utils": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "resolved": "http://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", "dev": true, "requires": { @@ -7722,7 +7755,7 @@ }, "cssnano": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "requires": { "autoprefixer": "^6.3.1", @@ -7871,7 +7904,7 @@ }, "json5": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { @@ -8326,20 +8359,12 @@ } }, "dom-converter": { - "version": "0.1.4", - "resolved": "http://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", - "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dev": true, "requires": { - "utila": "~0.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } + "utila": "~0.4" } }, "dom-helpers": { @@ -8556,9 +8581,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.71.tgz", - "integrity": "sha512-VjZ6mQbbgF3GZ3eeQOMMgkdP8pWAHoW9UA+CNAVB4qSaOES4usB9RVIW764mYffdT2GOWF10Udt82RIZnTCTMg==" + "version": "1.3.73", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.73.tgz", + "integrity": "sha512-6PIg7v9zRoVGh6EheRF8h6Plti+3Yo/qtHobS4/Htyt53DNHmKKGFqSae1AIk0k1S4gCQvt7I2WgpbuZNcDY+g==" }, "elliptic": { "version": "6.4.1", @@ -9021,16 +9046,16 @@ } }, "eslint": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.0.tgz", - "integrity": "sha512-/eVYs9VVVboX286mBK7bbKnO1yamUy2UCRjiY6MryhQL2PaaXCExsCQ2aO83OeYRhU2eCU/FMFP+tVMoOrzNrA==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.1.tgz", + "integrity": "sha512-hgrDtGWz368b7Wqf+v1Z69O3ZebNR0+GA7PtDdbmuz4rInFVUV9uw7whjZEiWyLzCjVb5Rs5WRN1TAS6eo7AYA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "ajv": "^6.5.3", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", - "debug": "^3.1.0", + "debug": "^4.0.1", "doctrine": "^2.1.0", "eslint-scope": "^4.0.0", "eslint-utils": "^1.3.1", @@ -9105,6 +9130,15 @@ "which": "^1.2.9" } }, + "debug": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.0.1.tgz", + "integrity": "sha512-K23FHJ/Mt404FSlp6gSZCevIbTMLX0j3fmHhUEhQ3Wq0FMODW3+cUSoLdy1Gx4polAf4t/lphhmHH35BB8cLYw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, "eslint-scope": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", @@ -9133,9 +9167,9 @@ } }, "globals": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", - "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", + "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", "dev": true }, "iconv-lite": { @@ -9205,6 +9239,16 @@ "regexpp": "^2.0.0" } }, + "eslint-plugin-graphql": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-graphql/-/eslint-plugin-graphql-2.1.1.tgz", + "integrity": "sha512-JT2paUyu3e9ZDnroSshwUMc6pKcnkfXTsZInX1+/rPotvqOLVLtdrx/cmfb7PTJwjiEAshwcpm3/XPdTpsKJPw==", + "dev": true, + "requires": { + "graphql-config": "^2.0.1", + "lodash": "^4.11.1" + } + }, "eslint-plugin-jsx-a11y": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.1.tgz", @@ -9369,7 +9413,7 @@ }, "events": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, "eventsource": { @@ -9437,9 +9481,9 @@ } }, "get-stream": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.0.0.tgz", - "integrity": "sha512-FneLKMENeOR7wOK0/ZXCh+lwqtnPwkeunJjRN28LPqzGvNAhYvrTAhXv6xDm4vsJ0M7lcRbIYHQudKsSy2RtSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -9754,9 +9798,9 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz", - "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.3.tgz", + "integrity": "sha512-NiX+JXjnx43RzvVFwRWfPKo4U+1BrK5pJPsHQdKMlLoFHrrGktXglQhHliSihWAq+m1z6fHk3uwGHrtRbS9vLA==", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -9974,7 +10018,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", @@ -10384,8 +10428,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -10403,13 +10446,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -10422,18 +10463,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -10536,8 +10574,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -10547,7 +10584,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -10560,20 +10596,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.2.4", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -10590,7 +10623,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -10663,8 +10695,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -10674,7 +10705,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -10750,8 +10780,7 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -10781,7 +10810,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -10799,7 +10827,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -10838,13 +10865,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.2", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -10932,7 +10957,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -11037,7 +11062,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "get-value": { @@ -11803,10 +11828,68 @@ "apollo-utilities": "^1.0.21" } }, + "graphql-config": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.2.1.tgz", + "integrity": "sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ==", + "dev": true, + "requires": { + "graphql-import": "^0.7.1", + "graphql-request": "^1.5.0", + "js-yaml": "^3.10.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } + }, + "graphql-import": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", + "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "graphql-request": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.8.2.tgz", + "integrity": "sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg==", + "dev": true, + "requires": { + "cross-fetch": "2.2.2" + } + }, "graphql-tag": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.9.2.tgz", - "integrity": "sha512-qnNmof9pAqj/LUzs3lStP0Gw1qhdVCUS7Ab7+SUB6KD5aX1uqxWQRwMnOGTkhKuLvLNIs1TvNz+iS9kUGl1MhA==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.0.tgz", + "integrity": "sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w==", "dev": true }, "growl": { @@ -11875,7 +11958,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -12060,7 +12143,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -12963,9 +13046,9 @@ } }, "informed": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/informed/-/informed-1.10.5.tgz", - "integrity": "sha512-3/lF958pr6JFc8GyAw4W+HWDYLLnF8DAjSAiPIyj6QZ4ayP/VYfaEYdM6wJwa5B8IbsQCv3eQCxaN5SeaXvbIw==", + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/informed/-/informed-1.10.6.tgz", + "integrity": "sha512-aJX9w+oIDrSDCvDYPwieshTJe6X1SFi/dpJCp5gbBHYN9u1lAdYU/Fw2dH4lVnTV4vZyUr2Ag4nIKWiN3lW21w==", "requires": { "@babel/runtime-corejs2": "^7.0.0-rc.1" } @@ -13680,8 +13763,7 @@ "iterall": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", - "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==", - "dev": true + "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" }, "jekyll-tasks": { "version": "1.2.1", @@ -14345,11 +14427,12 @@ } }, "jest-junit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-5.1.0.tgz", - "integrity": "sha512-3EVf1puv2ox5wybQDfLX3AEn3IKOgDV4E76y4pO2hBu46DEtAFZZAm//X1pzPQpqKji0zqgMIzqzF/K+uGAX9A==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-5.2.0.tgz", + "integrity": "sha512-Mdg0Qpdh1Xm/FA1B/mcLlmEmlr3XzH5pZg7MvcAwZhjHijPRd1z/UwYwkwNHmCV7o4ZOWCf77nLu7ZkhHHrtJg==", "dev": true, "requires": { + "jest-config": "^23.6.0", "jest-validate": "^23.0.1", "mkdirp": "^0.5.1", "strip-ansi": "^4.0.0", @@ -15112,7 +15195,7 @@ }, "json5": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, "jsonfile": { @@ -15324,9 +15407,9 @@ } }, "get-stream": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.0.0.tgz", - "integrity": "sha512-FneLKMENeOR7wOK0/ZXCh+lwqtnPwkeunJjRN28LPqzGvNAhYvrTAhXv6xDm4vsJ0M7lcRbIYHQudKsSy2RtSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -15550,6 +15633,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.flowright": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/lodash.flowright/-/lodash.flowright-3.5.0.tgz", + "integrity": "sha1-K1//OZcW1+fcVyT+k0n2cGUYTWc=", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -15733,7 +15822,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -16025,7 +16114,7 @@ }, "marked": { "version": "0.3.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz", "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", "dev": true }, @@ -16045,12 +16134,20 @@ "integrity": "sha1-ivoLp7aRp6sSPn8S9l4yu10fgkM=" }, "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "requires": { "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "media-typer": { @@ -16512,9 +16609,9 @@ "dev": true }, "nan": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==" + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" }, "nanomatch": { "version": "1.2.13", @@ -16829,7 +16926,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -16992,7 +17089,7 @@ }, "strip-ansi": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "requires": { "ansi-regex": "^0.2.1" @@ -18026,7 +18123,7 @@ }, "p-is-promise": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", "dev": true }, @@ -18354,7 +18451,7 @@ }, "parse-diff": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.4.2.tgz", + "resolved": "http://registry.npmjs.org/parse-diff/-/parse-diff-0.4.2.tgz", "integrity": "sha512-YYQzII66NqysdPgDVxzbdwNXMv5Ww562JSZSXZ4RIPoolzD7yqA4crgD8swrs+JNcvjoZMKMiT4kGcLYvf6IoA==", "dev": true }, @@ -18725,7 +18822,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -18743,7 +18840,7 @@ }, "postcss-calc": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "requires": { "postcss": "^5.0.2", @@ -18772,7 +18869,7 @@ }, "postcss-discard-comments": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "requires": { "postcss": "^5.0.14" @@ -18788,7 +18885,7 @@ }, "postcss-discard-empty": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "requires": { "postcss": "^5.0.14" @@ -18796,7 +18893,7 @@ }, "postcss-discard-overridden": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "requires": { "postcss": "^5.0.16" @@ -18804,7 +18901,7 @@ }, "postcss-discard-unused": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "requires": { "postcss": "^5.0.14", @@ -18984,7 +19081,7 @@ }, "postcss-merge-idents": { "version": "2.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", "requires": { "has": "^1.0.1", @@ -19019,7 +19116,7 @@ }, "postcss-minify-font-values": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", "requires": { "object-assign": "^4.0.1", @@ -19036,7 +19133,7 @@ }, "postcss-minify-gradients": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "requires": { "postcss": "^5.0.12", @@ -19045,7 +19142,7 @@ }, "postcss-minify-params": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", "requires": { "alphanum-sort": "^1.0.1", @@ -19056,7 +19153,7 @@ }, "postcss-minify-selectors": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", "requires": { "alphanum-sort": "^1.0.2", @@ -19182,7 +19279,7 @@ }, "postcss-normalize-charset": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "requires": { "postcss": "^5.0.5" @@ -19190,7 +19287,7 @@ }, "postcss-normalize-url": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", "requires": { "is-absolute-url": "^2.0.0", @@ -19210,7 +19307,7 @@ }, "postcss-reduce-idents": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "requires": { "postcss": "^5.0.4", @@ -19219,7 +19316,7 @@ }, "postcss-reduce-initial": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "requires": { "postcss": "^5.0.4" @@ -19227,7 +19324,7 @@ }, "postcss-reduce-transforms": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", "requires": { "has": "^1.0.1", @@ -19270,7 +19367,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -19295,7 +19392,7 @@ }, "postcss-svgo": { "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", "requires": { "is-svg": "^2.0.0", @@ -19306,7 +19403,7 @@ }, "postcss-unique-selectors": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", "requires": { "alphanum-sort": "^1.0.1", @@ -19321,7 +19418,7 @@ }, "postcss-zindex": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", "requires": { "has": "^1.0.1", @@ -19580,15 +19677,23 @@ } }, "public-encrypt": { - "version": "4.0.2", - "resolved": "http://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "pump": { @@ -19851,15 +19956,16 @@ } }, "react-apollo": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-apollo/-/react-apollo-2.2.1.tgz", - "integrity": "sha512-M1UY0o66e2rc4xhAtLKXWRx183yHW/ei1XAno8vWyIUQaEAg3rP5Sgw9nzl3wvpvU1lFjlsY50sbh2Ia1NB5+w==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/react-apollo/-/react-apollo-2.2.4.tgz", + "integrity": "sha512-haS5R30Qvteb65ZLfWomUZQh47VU4ld4Kof3zlqdbLOrYPt3/DdVZC8ZFPZSxd5zPeIJtZqpUfAxD1WHVoMPIA==", "dev": true, "requires": { "fbjs": "^1.0.0", "hoist-non-react-statics": "^3.0.0", "invariant": "^2.2.2", - "lodash": "^4.17.10", + "lodash.flowright": "^3.5.0", + "lodash.isequal": "^4.5.0", "prop-types": "^15.6.0" }, "dependencies": { @@ -19970,7 +20076,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -20670,16 +20776,16 @@ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "renderkid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", - "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.2.tgz", + "integrity": "sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==", "dev": true, "requires": { "css-select": "^1.1.0", - "dom-converter": "~0.1", + "dom-converter": "~0.2", "htmlparser2": "~3.3.0", "strip-ansi": "^3.0.0", - "utila": "~0.3" + "utila": "^0.4.0" }, "dependencies": { "ansi-regex": { @@ -20690,18 +20796,12 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } - }, - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true } } }, @@ -21143,7 +21243,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -21921,9 +22021,9 @@ } }, "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" }, "spdx-expression-parse": { "version": "3.0.0", @@ -22923,7 +23023,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -23803,7 +23903,7 @@ }, "uuid": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" }, "v8flags": { @@ -24639,7 +24739,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -24681,18 +24781,18 @@ "dev": true }, "whatwg-encoding": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz", - "integrity": "sha512-vM9KWN6MP2mIHZ86ytcyIv7e8Cj3KTfO2nd2c8PFDqcI4bxFmQp83ibq4wadq7rL9l9sZV6o9B0LTt8ygGAAXg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "dev": true, "requires": { - "iconv-lite": "0.4.23" + "iconv-lite": "0.4.24" }, "dependencies": { "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -24776,25 +24876,25 @@ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" }, "workbox-background-sync": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-3.6.1.tgz", - "integrity": "sha512-lMXwUbZ/FQBWf/jkFwz0ARfMLeIk9q73+fsqGwwUwUcr8NC6GDZlgtH9sPndxU1VbM+bieRM9R9kVStE4s2uVQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-3.6.2.tgz", + "integrity": "sha512-K34wiTM50gSpzJUuRmGRqbd91IpJj0vwMBSHCpixw/jiTg10uytSfnixMNGzeTK0i7LTd/bkA8ptx4HXP+MliA==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-broadcast-cache-update": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-broadcast-cache-update/-/workbox-broadcast-cache-update-3.6.1.tgz", - "integrity": "sha512-wC6LQNNPGLfZ1W+kSA2sP5YrbUl5axYgD0iNU37l4ABaCmjpu2XiFwPH+v4NOj/YWJt+z2563YB4SFM+/rC2mg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-broadcast-cache-update/-/workbox-broadcast-cache-update-3.6.2.tgz", + "integrity": "sha512-wmN3k94Kv3/lYOqRy08ymp8RyTPCpgLI9UW/BrQ1XuZHJyFejWnBoy/pCKk9mRZYZX7EyvnzA4O1PLILgLC43g==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-build": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-3.6.1.tgz", - "integrity": "sha512-1xEaFzVWzcIMwNHIW8WesGL+7MOx7XeHU1et1VWGDbxHV0i2HL8koMxq3g2WpKJy+yEh0hRG+4KuTGMmeuQcMA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-3.6.2.tgz", + "integrity": "sha512-PYw4SRbfbUE/+DDhb89zbspDLBi86hpra+l6SsX7yBqCthw4sHyH8IIQw5MMHI04HPV5ZDYru8A5SNLXVDGMcg==", "requires": { "babel-runtime": "^6.26.0", "common-tags": "^1.4.0", @@ -24805,113 +24905,114 @@ "pretty-bytes": "^4.0.2", "stringify-object": "^3.2.2", "strip-comments": "^1.0.2", - "workbox-background-sync": "^3.6.1", - "workbox-broadcast-cache-update": "^3.6.1", - "workbox-cache-expiration": "^3.6.1", - "workbox-cacheable-response": "^3.6.1", - "workbox-core": "^3.6.1", - "workbox-google-analytics": "^3.6.1", - "workbox-navigation-preload": "^3.6.1", - "workbox-precaching": "^3.6.1", - "workbox-range-requests": "^3.6.1", - "workbox-routing": "^3.6.1", - "workbox-strategies": "^3.6.1", - "workbox-streams": "^3.6.1", - "workbox-sw": "^3.6.1" + "workbox-background-sync": "^3.6.2", + "workbox-broadcast-cache-update": "^3.6.2", + "workbox-cache-expiration": "^3.6.2", + "workbox-cacheable-response": "^3.6.2", + "workbox-core": "^3.6.2", + "workbox-google-analytics": "^3.6.2", + "workbox-navigation-preload": "^3.6.2", + "workbox-precaching": "^3.6.2", + "workbox-range-requests": "^3.6.2", + "workbox-routing": "^3.6.2", + "workbox-strategies": "^3.6.2", + "workbox-streams": "^3.6.2", + "workbox-sw": "^3.6.2" } }, "workbox-cache-expiration": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-cache-expiration/-/workbox-cache-expiration-3.6.1.tgz", - "integrity": "sha512-mOV90D8cJ6S2s1GUGbfTvQ+WWKEMAvbHkH+vjIFdl+hXcToC7toctBI3UzI7vmmFv3TRQcP3TAxBmJgEFjgJew==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-cache-expiration/-/workbox-cache-expiration-3.6.2.tgz", + "integrity": "sha512-LJLYfqG7ItYucppun5I92fcN21kDZFEVqZ8uAOz5t8piOsHh1ThAiiLv/4ubG/d7CUgqW/1bmcX6DM4xqackzg==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-cacheable-response": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-3.6.1.tgz", - "integrity": "sha512-67tsFrpgX5LI3Nu82eVXlqfdq/PegF+agjcrLRDfSlD6cySCZCb0cyFHwLhegw5A6BayRHzYcBM5/imGeaMwjw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-3.6.2.tgz", + "integrity": "sha512-WvICMN3SfEi48C96KEfkLDIqnU0rkQeajdLjYXuzbUID3EX31gzUVlIbqQGrc+9xtIlvxs2+ZoaTR3Rjdtbh/Q==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-core": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-3.6.1.tgz", - "integrity": "sha512-xrrPQ335Cdekihe1jhscXYm4mmhh7ZXqSlZqJhyVmp9lNp5xzz1t0R22AfoaVNsg0zdu6Ouqnn0RsQ53QkZ8tw==" + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-3.6.2.tgz", + "integrity": "sha512-5T5WBFy5nMm7zx+P2RwdzEVu5CK++bqwiEsGF+INwUxsOKpH9oXUlUdJE/KfUaMsKcZtHXEb74mMB6vvE88a/w==" }, "workbox-google-analytics": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-3.6.1.tgz", - "integrity": "sha512-rnAT2RseiQO8DWjjkQkojVHX/6MK/L88+UFKr92xG1fKGD2asOk97AG6i0fAAti6f4KMg2s5UWZthiFR9QH4fQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-3.6.2.tgz", + "integrity": "sha512-NXBbo9xyHQvkHcvYoZkNJw7DB53dJUnmusKdSPg138A6HGt2ilycwTUuXNDWpkXXp3YHxcslrBMdptolwbzidg==", "requires": { - "workbox-background-sync": "^3.6.1", - "workbox-core": "^3.6.1", - "workbox-routing": "^3.6.1", - "workbox-strategies": "^3.6.1" + "workbox-background-sync": "^3.6.2", + "workbox-core": "^3.6.2", + "workbox-routing": "^3.6.2", + "workbox-strategies": "^3.6.2" } }, "workbox-navigation-preload": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-3.6.1.tgz", - "integrity": "sha512-Dzzp0JasGZWHSbZdx+UY0ZFaJu6P1LGIlFw3A+oTHbop9rZY219BNREcpzHT107SP7VFBkz/KIGF7s05FD6tpQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-3.6.2.tgz", + "integrity": "sha512-fN/CWSFZiySQH/OEJQsIizAM4ob6IgZVDfWvA58jAwiyI5QziqfFtL/EiHHNvmIa5jTdcoXfuNNv1WUdpRV18A==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-precaching": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-3.6.1.tgz", - "integrity": "sha512-qKNelNcGGSnKZveZRO+4sFKxr33iNMcP9Pbm8OkdEdAAZem0Ia4hIL87mHvwCvRnuj/vaV2BwRghZnzmLsK8Ng==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-3.6.2.tgz", + "integrity": "sha512-oQmBfvCzCUfLcwTokfbVhIIcyNS9aF692EhdqAz/SB2e40ehUgcctAUhQOezsedZFqBBnwphJQUhs+hD3mu72A==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-range-requests": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-3.6.1.tgz", - "integrity": "sha512-/ZPvMvKUzWBVmmN+fCPslF8RXin0C5WAla9EE0taiAMWdrVfPGghERtZLHumk/yM/M3k+OqWzPxCV0Wg/mjbqg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-3.6.2.tgz", + "integrity": "sha512-y1MFB97ydbT8PxBiihndLzG66sNIRzL0lkyoeaWPGfaPGWTP8ghMe4SkGqqdiY+E54rhd7lTdb7RZdv3Av1lTg==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-routing": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-3.6.1.tgz", - "integrity": "sha512-9LoBs5ck9Rjutno4yfBzqFyiUqj2UvILgYHGFkjHLp7lA4KK9VIuBJjGCLNaWr2r0pe6DVM5tM2OvlAOa2JO3w==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-3.6.2.tgz", + "integrity": "sha512-rhoH1AlETUfffJXJSlc0/T5rBB6vatxpD/8IZgxgHByBnYokV+/HxO7It6wBbxIzdO31UrWVroYm0iVa5sO7Jw==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-strategies": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-3.6.1.tgz", - "integrity": "sha512-OEw1psICNGpL1bqFZGyjl9N9hnmnRvsOA2EWAXxKVlwqmVvGzSeb8S46DPnH2JQgy77DRfNzeHVdfN6XirqdJw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-3.6.2.tgz", + "integrity": "sha512-4jAyL3n0Fl1BLB3QDUoUoBTzBsE8FwH0K7He1JvLzFiDtYp1ewcKjDecYCNZyTsFVgaLL7WClEQCOKSBquBfOg==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-streams": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-3.6.1.tgz", - "integrity": "sha512-SjO8wyUJ72+EXFVn9i9140hxbiN7d56k8gDHTxVoQT7OrCVYWkGFR0GzfnoRONaaHvO+/CGOyS37/Y+IXr7Vdw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-3.6.2.tgz", + "integrity": "sha512-lKTh5fOAf+Qae7GHYXZve40ZXULCf9kxlkrWjTXqGcTh6cxeibuWl6Mnt4aroChNB8jOEbHfGOy0iaG0R159ew==", "requires": { - "workbox-core": "^3.6.1" + "workbox-core": "^3.6.2" } }, "workbox-sw": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-3.6.1.tgz", - "integrity": "sha512-bXKvvjt5Oet87cpuSuVpiFYBohCv9xLmniZwMZPAFQVEtpPCyWv5X+UVZ+BpHVDBcRMYz7lXNIRWa9J54zR2vA==" + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-3.6.2.tgz", + "integrity": "sha512-EwQZaeGB+tEogABMj9FaEDuszaSBQgjAUEqTFiizZWSU8owZrt0BFfi69TMAhILOfWLFh3aASMzQnPMDY7id4w==" }, "workbox-webpack-plugin": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-3.6.1.tgz", - "integrity": "sha512-+rEBX+JxdNIoEtQLifn7+0YO6lhEWW7PGx9tuCesxcMACpbSJ/ihfKhmqK7BfvnvPv9OhhIyuPDLs3IROrPk0A==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-3.6.2.tgz", + "integrity": "sha512-FGSkcaiMDM41uTGkYf7O6hf2W7UvkNc+iUIltfGiRp+qeQfXKOOh5fJCz+a6AFkeuGELSSYROsQRuOqX8LytcQ==", "requires": { + "babel-runtime": "^6.26.0", "json-stable-stringify": "^1.0.1", - "workbox-build": "^3.6.1" + "workbox-build": "^3.6.2" } }, "worker-farm": { @@ -24957,7 +25058,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -24990,9 +25091,9 @@ } }, "write-file-webpack-plugin": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/write-file-webpack-plugin/-/write-file-webpack-plugin-4.4.0.tgz", - "integrity": "sha512-NcfhBlPbG8yb/3eUkYGuAyNj8P7W227HL9cXcGp0jUp+JnL3CgPlPtY30c0yl3CIbJEW7OfBU90bxHO2v9fQoA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/write-file-webpack-plugin/-/write-file-webpack-plugin-4.4.1.tgz", + "integrity": "sha512-PuYlu2TZqF/Rkdk3Ri6hiofz+6HQAVkH55VpJ75axQXU2m6cS5jvbgwcJe+vwbgJTLhiX0O7GAPMbgO5DMZEiA==", "requires": { "chalk": "^2.4.0", "debug": "^3.1.0", @@ -25165,7 +25266,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" diff --git a/package.json b/package.json index db716607a0f..f8dbd8eb172 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "test:ci": "npm run -s test -- -i --json --outputFile=test-results.json", "test:debug": "node --inspect-brk node_modules/.bin/jest -i --watch", "test:dev": "jest --watch", + "validate:venia:gql": "cd packages/venia-concept && npm run -s validate-queries; cd - >/dev/null", "watch:all": "concurrently -c yellow.dim,green.dim,cyan.dim -n ␢,℗,☄︎ 'npm run watch:buildpack' 'npm run watch:peregrine' 'npm run watch:venia-dev-server'", "watch:buildpack": "cd packages/pwa-buildpack && npm run -s watch; cd - >/dev/null", "watch:peregrine": "cd packages/peregrine && npm run -s watch; cd - >/dev/null", @@ -62,6 +63,7 @@ "enzyme-adapter-react-16": "^1.1.1", "eslint": "^5.2.0", "eslint-plugin-babel": "^5.1.0", + "eslint-plugin-graphql": "^2.1.1", "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-node": "^7.0.1", "eslint-plugin-react": "^7.9.1", diff --git a/packages/peregrine/src/List/__tests__/items.spec.js b/packages/peregrine/src/List/__tests__/items.spec.js index 785623ea82b..c63fb5cd638 100644 --- a/packages/peregrine/src/List/__tests__/items.spec.js +++ b/packages/peregrine/src/List/__tests__/items.spec.js @@ -10,7 +10,9 @@ const items = [ { id: '001', name: 'Test Product 1', - small_image: '/test/product/1.png', + small_image: { + path: '/test/product/1.png' + }, price: { regularPrice: { amount: { @@ -22,7 +24,9 @@ const items = [ { id: '002', name: 'Test Product 2', - small_image: '/test/product/2.png', + small_image: { + path: '/test/product/2.png' + }, price: { regularPrice: { amount: { diff --git a/packages/peregrine/src/List/__tests__/list.spec.js b/packages/peregrine/src/List/__tests__/list.spec.js index aadfc68e4e2..cb1833ca3d9 100644 --- a/packages/peregrine/src/List/__tests__/list.spec.js +++ b/packages/peregrine/src/List/__tests__/list.spec.js @@ -14,7 +14,9 @@ const items = [ { id: '001', name: 'Test Product 1', - small_image: '/test/product/1.png', + small_image: { + path: '/test/product/1.png' + }, price: { regularPrice: { amount: { @@ -26,7 +28,9 @@ const items = [ { id: '002', name: 'Test Product 2', - small_image: '/test/product/2.png', + small_image: { + path: '/test/product/2.png' + }, price: { regularPrice: { amount: { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index c23868a0136..dd8d0880209 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -16,6 +16,7 @@ "prepare": "npm-merge-driver install", "start": "webpack-dev-server --progress --color --env.phase development", "start:debug": "node --inspect-brk ./node_modules/.bin/webpack-dev-server --progress --color --env.phase development", + "validate-queries": "node ./validate-queries.js", "watch": "npm run -s start" }, "devDependencies": { diff --git a/packages/venia-concept/src/RootComponents/Category/category.js b/packages/venia-concept/src/RootComponents/Category/category.js index 0c8426bdd5b..3767f6f2655 100644 --- a/packages/venia-concept/src/RootComponents/Category/category.js +++ b/packages/venia-concept/src/RootComponents/Category/category.js @@ -17,7 +17,9 @@ const categoryQuery = gql` items { id name - small_image + small_image { + path + } url_key price { regularPrice { diff --git a/packages/venia-concept/src/components/Gallery/__tests__/gallery.spec.js b/packages/venia-concept/src/components/Gallery/__tests__/gallery.spec.js index e6c7100d7d0..d9b9fdb5454 100644 --- a/packages/venia-concept/src/components/Gallery/__tests__/gallery.spec.js +++ b/packages/venia-concept/src/components/Gallery/__tests__/gallery.spec.js @@ -11,7 +11,9 @@ const items = [ { id: 1, name: 'Test Product 1', - small_image: '/test/product/1.png', + small_image: { + path: '/test/product/1.png' + }, price: { regularPrice: { amount: { @@ -24,7 +26,9 @@ const items = [ { id: 2, name: 'Test Product 2', - small_image: '/test/product/2.png', + small_image: { + path: '/test/product/2.png' + }, price: { regularPrice: { amount: { diff --git a/packages/venia-concept/src/components/Gallery/__tests__/items.spec.js b/packages/venia-concept/src/components/Gallery/__tests__/items.spec.js index 16d26746162..ccf9da687dc 100644 --- a/packages/venia-concept/src/components/Gallery/__tests__/items.spec.js +++ b/packages/venia-concept/src/components/Gallery/__tests__/items.spec.js @@ -10,7 +10,9 @@ const items = [ { id: 1, name: 'Test Product 1', - small_image: '/test/product/1.png', + small_image: { + path: '/test/product/1.png' + }, price: { regularPrice: { amount: { @@ -22,7 +24,9 @@ const items = [ { id: 2, name: 'Test Product 2', - small_image: '/test/product/2.png', + small_image: { + path: '/test/product/2.png' + }, price: { regularPrice: { amount: { diff --git a/packages/venia-concept/src/components/Gallery/gallery.js b/packages/venia-concept/src/components/Gallery/gallery.js index d8900cccd93..4a0486764e7 100644 --- a/packages/venia-concept/src/components/Gallery/gallery.js +++ b/packages/venia-concept/src/components/Gallery/gallery.js @@ -19,7 +19,9 @@ class Gallery extends Component { shape({ id: number.isRequired, name: string.isRequired, - small_image: string.isRequired, + small_image: shape({ + path: string.isRequired + }).isRequired, price: shape({ regularPrice: shape({ amount: shape({ diff --git a/packages/venia-concept/src/components/Gallery/item.js b/packages/venia-concept/src/components/Gallery/item.js index bd88acd589c..38f53b0b4c6 100644 --- a/packages/venia-concept/src/components/Gallery/item.js +++ b/packages/venia-concept/src/components/Gallery/item.js @@ -40,7 +40,9 @@ class GalleryItem extends Component { item: shape({ id: number.isRequired, name: string.isRequired, - small_image: string.isRequired, + small_image: shape({ + path: string.isRequired + }).isRequired, url_key: string.isRequired, price: shape({ regularPrice: shape({ @@ -138,7 +140,7 @@ class GalleryItem extends Component { return ( {name} 0) { + console.error(`Errors found!`); + const formatter = cli.getFormatter(); + process.stderr.write(formatter(report.results)); + console.error( + ` +These errors may indicate: + - an out-of-date Magento 2.3 codebase running at "${magentoDomain}" + - an out-of-date project codebase whose queries need updating + +Use GraphiQL or another schema exploration tool on the Magento store to learn more. + ` + ); + process.exit(1); + } else { + console.log( + `Validation passed! All queries found are valid for schema.` + ); + process.exit(0); + } +} + +validateQueries(); From 0c27d57f7e016c7dc2a8eafbb1fc41bb5374947c Mon Sep 17 00:00:00 2001 From: James Zetlen Date: Thu, 4 Oct 2018 09:18:51 -0500 Subject: [PATCH 02/22] Add UPWARD specification, guide, tests, reference implementation (#248) * doc(upward): UPWARD spec and paper * feat(upward): test suite and reference impl * Merge branch 'integration/2.0' into zetlen/upward * chore: fix merged tests and format * fix: upwardServer resolves on listen * chore: reverting critical css change * chore: Remove theme architecture files and docs * WIP bugfixen * feat(dev): finalize UpwardPlugin for dev mode * fixup: PR feedback * refactor: encapsulate domain gen * feat(stage): add HTTPS to staging server * WIP add buildpack docs * WIP readme improvements * fix circleci env copy * fixup: bugs and test failures --- .circleci/config.yml | 2 +- .editorconfig | 5 +- .eslintignore | 1 - .gitignore | 2 - .prettierignore | 2 - README.md | 48 +- greenkeeper.json | 14 - jest.config.js | 1 + lerna.json | 4 +- package-lock.json | 11755 ++++++++++------ package.json | 11 +- packages/peregrine/CHANGELOG.md | 13 + packages/peregrine/README.md | 2 +- .../src/Router/resolveUnknownRoute.js | 35 +- packages/pwa-buildpack/CHANGELOG.md | 29 +- packages/pwa-buildpack/README.md | 19 +- .../pwa-buildpack/docs/MagentoResolver.md | 4 +- .../docs/MagentoRootComponentsPlugin.md | 4 +- packages/pwa-buildpack/docs/PWADevServer.md | 20 +- .../pwa-buildpack/docs/ServiceWorkerPlugin.md | 4 +- packages/pwa-buildpack/package.json | 7 + .../Utilities/__tests__/setupDomain.spec.js | 221 + packages/pwa-buildpack/src/Utilities/index.js | 3 + .../src/Utilities/setupDomain.js | 148 + .../src/WebpackTools/PWADevServer.js | 187 +- .../__tests__/PWADevServer.spec.js | 248 +- .../__snapshots__/PWADevServer.spec.js.snap | 3 - .../pwa-buildpack/src/WebpackTools/index.js | 3 +- .../src/WebpackTools/middlewares/DevProxy.js | 86 - .../middlewares/OriginSubstitution.js | 66 - .../middlewares/StaticRootRoute.js | 11 - .../__fixtures__/root-available-file.json | 3 - .../middlewares/__tests__/DevProxy.spec.js | 149 - .../__tests__/OriginSubstitution.spec.js | 34 - .../__tests__/StaticRootRoute.spec.js | 30 - .../MagentoRootComponentsPlugin/index.js | 23 +- .../src/WebpackTools/plugins/UpwardPlugin.js | 105 + .../plugins/__tests__/UpwardPlugin.spec.js | 218 + packages/pwa-buildpack/src/index.js | 3 +- .../src/util/__tests__/check-loopback.spec.js | 71 + .../src/util/__tests__/ssl-cert-store.spec.js | 95 - .../pwa-buildpack/src/util/check-loopback.js | 48 + .../pwa-buildpack/src/util/ssl-cert-store.js | 59 - packages/pwa-devdocs/CHANGELOG.md | 12 + packages/pwa-module/Block/Bundle.php | 81 - packages/pwa-module/Controller/Index/Js.php | 81 - .../Index/WebpackConfigEndpoint.php | 52 - packages/pwa-module/Controller/Router.php | 65 - packages/pwa-module/Helper/WebpackConfig.php | 331 - .../pwa-module/Model/Result/JsFileResult.php | 75 - packages/pwa-module/etc/di.xml | 14 - packages/pwa-module/etc/frontend/routes.xml | 8 - packages/pwa-module/etc/module.xml | 9 - packages/pwa-module/package.json | 4 - packages/pwa-module/registration.php | 10 - .../view/frontend/layout/default.xml | 8 - packages/upward-js/README.md | 60 + packages/upward-js/bin/server | 9 + packages/upward-js/jest.config.js | 5 + packages/upward-js/lib/Context.js | 115 + packages/upward-js/lib/ContextPath.js | 104 + packages/upward-js/lib/IOAdapter.js | 59 + packages/upward-js/lib/ResolverVisitor.js | 107 + packages/upward-js/lib/UpwardServerError.js | 11 + .../upward-js/lib/__tests__/Context.test.js | 40 + .../lib/__tests__/ResolverVisitor.test.js | 93 + .../lib/__tests__/buildResponse.test.js | 137 + .../lib/__tests__/envToConfig.test.js | 16 + .../upward-js/lib/__tests__/server.test.js | 35 + packages/upward-js/lib/buildResponse.js | 34 + .../AbstractCompiledResource.js | 33 + .../lib/compiledResources/GraphQLDocument.js | 16 + .../lib/compiledResources/MustacheTemplate.js | 100 + .../AbstractCompiledResource.test.js | 35 + .../__tests__/GraphQLDocument.test.js | 97 + .../__tests__/MustacheTemplate.test.js | 145 + .../__tests__/forFileOfType.test.js | 17 + .../upward-js/lib/compiledResources/index.js | 23 + packages/upward-js/lib/createUpwardServer.js | 91 + packages/upward-js/lib/envToConfig.js | 50 + packages/upward-js/lib/index.js | 6 + packages/upward-js/lib/isPrimitive.js | 4 + packages/upward-js/lib/middleware.js | 98 + .../lib/resolvers/AbstractResolver.js | 17 + .../lib/resolvers/ConditionalResolver.js | 58 + .../lib/resolvers/DirectoryResolver.js | 44 + .../upward-js/lib/resolvers/FileResolver.js | 101 + .../upward-js/lib/resolvers/InlineResolver.js | 33 + .../upward-js/lib/resolvers/ProxyResolver.js | 56 + .../lib/resolvers/ServiceResolver.js | 99 + .../lib/resolvers/TemplateResolver.js | 108 + .../__tests__/AbstractResolver.test.js | 9 + .../__tests__/ConditionalResolver.test.js | 158 + .../resolvers/__tests__/FileResolver.test.js | 253 + .../__tests__/InlineResolver.test.js | 34 + .../__tests__/ServiceResolver.test.js | 260 + .../__tests__/TemplateResolver.test.js | 196 + .../lib/resolvers/__tests__/index.test.js | 22 + packages/upward-js/lib/resolvers/index.js | 17 + packages/upward-js/package.json | 60 + packages/upward-js/test_spec.sh | 5 + .../EXECUTION_SCHEDULING_STRATEGIES.md | 256 + packages/upward-spec/RATIONALE.md | 184 + packages/upward-spec/README.md | 1129 ++ packages/upward-spec/UPWARD_MAGENTO.md | 3 + packages/upward-spec/backing_services.png | Bin 0 -> 19395 bytes packages/upward-spec/bin/upward-spec | 67 + packages/upward-spec/package-lock.json | 1617 +++ packages/upward-spec/package.json | 37 + packages/upward-spec/suite/MockGQLService.js | 19 + .../upward-spec/suite/assertOnResponse.js | 73 + packages/upward-spec/suite/getScenarios.js | 52 + packages/upward-spec/suite/index.js | 6 + packages/upward-spec/suite/runServer.js | 169 + .../001-unknown-config/only-status.yml | 1 + .../scenarios/001-unknown-config/tests.js | 31 + .../001-unknown-config/unparseable.yml | 1 + .../context-is-hello-env-is-world.mst | 1 + .../hello-context-inline-template-json.yml | 15 + .../hello-env-context-file-template.yml | 23 + .../hello-env-inline-template.yml | 10 + .../hello-env-interpolation.yml | 5 + .../hello-file-shortcut.yml | 8 + .../hello-inline-implicit-resolvers.yml | 6 + .../002-static-servers/hello-inline-only.yml | 12 + .../002-static-servers/json-subject.tpt | 1 + .../renders-addressee-alone.mustache | 1 + .../scenarios/002-static-servers/swords.csv | 4 + .../scenarios/002-static-servers/tests.js | 220 + .../cyclic-dependencies.yml | 16 + .../003-request-handling/island-summary.mst | 4 + .../003-request-handling/reflect-request.yml | 32 + .../003-request-handling/route-requests.yml | 64 + .../scenarios/003-request-handling/tests.js | 34 + .../articles-and-authors-schema.graphql | 18 + .../articles-and-authors.yml | 65 + .../scenarios/005-many-resolvers/footer.mst | 1 + .../005-many-resolvers/getArticle.graphql | 10 + .../005-many-resolvers/getAuthor.graphql | 9 + .../scenarios/005-many-resolvers/head.mst | 1 + .../scenarios/005-many-resolvers/header.mst | 2 + .../scenarios/005-many-resolvers/menu.mst | 1 + .../scenarios/005-many-resolvers/notFound.mst | 9 + packages/upward-spec/test_upward_server.sh | 15 + packages/upward-spec/tiered_architecture.png | Bin 0 -> 26508 bytes packages/upward-spec/unified_graph.png | Bin 0 -> 29161 bytes packages/venia-concept/.babelrc | 1 + packages/venia-concept/.env.dist | 14 - packages/venia-concept/CHANGELOG.md | 26 + .../Magento_Theme/templates/root.phtml | 26 - packages/venia-concept/babel.config.js | 3 +- packages/venia-concept/composer.json | 13 - packages/venia-concept/etc/view.xml | 314 - packages/venia-concept/example.env | 73 + packages/venia-concept/media/favicon.ico | Bin 0 -> 15086 bytes packages/venia-concept/media/preview.jpg | Bin 71727 -> 0 bytes packages/venia-concept/package.json | 14 +- packages/venia-concept/registration.php | 13 - packages/venia-concept/server.js | 46 + .../src/RootComponents/Category/category.js | 3 +- .../src/RootComponents/Product/Product.js | 32 +- .../__tests__/createAccount.spec.js | 5 +- .../components/Gallery/__tests__/item.spec.js | 4 +- .../src/queries/getProductDetail.graphql | 26 + .../src/queries/urlResolver.graphql | 6 + .../templates/doctype-and-head-start.mst | 6 + .../venia-concept/templates/generic-shell.mst | 12 + .../templates/notfound-shell.mst | 11 + packages/venia-concept/templates/preloads.mst | 3 + .../venia-concept/templates/product-shell.mst | 17 + packages/venia-concept/templates/scripts.mst | 2 + packages/venia-concept/theme.xml | 14 - packages/venia-concept/venia-upward.yml | 124 + packages/venia-concept/webpack.config.js | 38 +- 174 files changed, 16196 insertions(+), 6498 deletions(-) delete mode 100644 greenkeeper.json create mode 100644 packages/peregrine/CHANGELOG.md create mode 100644 packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js create mode 100644 packages/pwa-buildpack/src/Utilities/index.js create mode 100644 packages/pwa-buildpack/src/Utilities/setupDomain.js delete mode 100644 packages/pwa-buildpack/src/WebpackTools/__tests__/__snapshots__/PWADevServer.spec.js.snap delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/DevProxy.js delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/OriginSubstitution.js delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/StaticRootRoute.js delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/__fixtures__/root-available-file.json delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/DevProxy.spec.js delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/OriginSubstitution.spec.js delete mode 100644 packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/StaticRootRoute.spec.js create mode 100644 packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js create mode 100644 packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js create mode 100644 packages/pwa-buildpack/src/util/__tests__/check-loopback.spec.js delete mode 100644 packages/pwa-buildpack/src/util/__tests__/ssl-cert-store.spec.js create mode 100644 packages/pwa-buildpack/src/util/check-loopback.js delete mode 100644 packages/pwa-buildpack/src/util/ssl-cert-store.js create mode 100644 packages/pwa-devdocs/CHANGELOG.md delete mode 100644 packages/pwa-module/Block/Bundle.php delete mode 100644 packages/pwa-module/Controller/Index/Js.php delete mode 100644 packages/pwa-module/Controller/Index/WebpackConfigEndpoint.php delete mode 100644 packages/pwa-module/Controller/Router.php delete mode 100644 packages/pwa-module/Helper/WebpackConfig.php delete mode 100644 packages/pwa-module/Model/Result/JsFileResult.php delete mode 100644 packages/pwa-module/etc/di.xml delete mode 100644 packages/pwa-module/etc/frontend/routes.xml delete mode 100644 packages/pwa-module/etc/module.xml delete mode 100644 packages/pwa-module/package.json delete mode 100644 packages/pwa-module/registration.php delete mode 100644 packages/pwa-module/view/frontend/layout/default.xml create mode 100644 packages/upward-js/README.md create mode 100755 packages/upward-js/bin/server create mode 100644 packages/upward-js/jest.config.js create mode 100644 packages/upward-js/lib/Context.js create mode 100644 packages/upward-js/lib/ContextPath.js create mode 100644 packages/upward-js/lib/IOAdapter.js create mode 100644 packages/upward-js/lib/ResolverVisitor.js create mode 100644 packages/upward-js/lib/UpwardServerError.js create mode 100644 packages/upward-js/lib/__tests__/Context.test.js create mode 100644 packages/upward-js/lib/__tests__/ResolverVisitor.test.js create mode 100644 packages/upward-js/lib/__tests__/buildResponse.test.js create mode 100644 packages/upward-js/lib/__tests__/envToConfig.test.js create mode 100644 packages/upward-js/lib/__tests__/server.test.js create mode 100644 packages/upward-js/lib/buildResponse.js create mode 100644 packages/upward-js/lib/compiledResources/AbstractCompiledResource.js create mode 100644 packages/upward-js/lib/compiledResources/GraphQLDocument.js create mode 100644 packages/upward-js/lib/compiledResources/MustacheTemplate.js create mode 100644 packages/upward-js/lib/compiledResources/__tests__/AbstractCompiledResource.test.js create mode 100644 packages/upward-js/lib/compiledResources/__tests__/GraphQLDocument.test.js create mode 100644 packages/upward-js/lib/compiledResources/__tests__/MustacheTemplate.test.js create mode 100644 packages/upward-js/lib/compiledResources/__tests__/forFileOfType.test.js create mode 100644 packages/upward-js/lib/compiledResources/index.js create mode 100644 packages/upward-js/lib/createUpwardServer.js create mode 100644 packages/upward-js/lib/envToConfig.js create mode 100644 packages/upward-js/lib/index.js create mode 100644 packages/upward-js/lib/isPrimitive.js create mode 100644 packages/upward-js/lib/middleware.js create mode 100644 packages/upward-js/lib/resolvers/AbstractResolver.js create mode 100644 packages/upward-js/lib/resolvers/ConditionalResolver.js create mode 100644 packages/upward-js/lib/resolvers/DirectoryResolver.js create mode 100644 packages/upward-js/lib/resolvers/FileResolver.js create mode 100644 packages/upward-js/lib/resolvers/InlineResolver.js create mode 100644 packages/upward-js/lib/resolvers/ProxyResolver.js create mode 100644 packages/upward-js/lib/resolvers/ServiceResolver.js create mode 100644 packages/upward-js/lib/resolvers/TemplateResolver.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/AbstractResolver.test.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/ConditionalResolver.test.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/FileResolver.test.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/InlineResolver.test.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/ServiceResolver.test.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/TemplateResolver.test.js create mode 100644 packages/upward-js/lib/resolvers/__tests__/index.test.js create mode 100644 packages/upward-js/lib/resolvers/index.js create mode 100644 packages/upward-js/package.json create mode 100755 packages/upward-js/test_spec.sh create mode 100644 packages/upward-spec/EXECUTION_SCHEDULING_STRATEGIES.md create mode 100644 packages/upward-spec/RATIONALE.md create mode 100644 packages/upward-spec/README.md create mode 100644 packages/upward-spec/UPWARD_MAGENTO.md create mode 100644 packages/upward-spec/backing_services.png create mode 100755 packages/upward-spec/bin/upward-spec create mode 100644 packages/upward-spec/package-lock.json create mode 100644 packages/upward-spec/package.json create mode 100644 packages/upward-spec/suite/MockGQLService.js create mode 100644 packages/upward-spec/suite/assertOnResponse.js create mode 100644 packages/upward-spec/suite/getScenarios.js create mode 100644 packages/upward-spec/suite/index.js create mode 100644 packages/upward-spec/suite/runServer.js create mode 100644 packages/upward-spec/suite/scenarios/001-unknown-config/only-status.yml create mode 100644 packages/upward-spec/suite/scenarios/001-unknown-config/tests.js create mode 100644 packages/upward-spec/suite/scenarios/001-unknown-config/unparseable.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/context-is-hello-env-is-world.mst create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-context-inline-template-json.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-env-context-file-template.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-env-inline-template.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-env-interpolation.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-file-shortcut.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-implicit-resolvers.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-only.yml create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/json-subject.tpt create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/renders-addressee-alone.mustache create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/swords.csv create mode 100644 packages/upward-spec/suite/scenarios/002-static-servers/tests.js create mode 100644 packages/upward-spec/suite/scenarios/003-request-handling/cyclic-dependencies.yml create mode 100644 packages/upward-spec/suite/scenarios/003-request-handling/island-summary.mst create mode 100644 packages/upward-spec/suite/scenarios/003-request-handling/reflect-request.yml create mode 100644 packages/upward-spec/suite/scenarios/003-request-handling/route-requests.yml create mode 100644 packages/upward-spec/suite/scenarios/003-request-handling/tests.js create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors-schema.graphql create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors.yml create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/footer.mst create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/getArticle.graphql create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/getAuthor.graphql create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/head.mst create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/header.mst create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/menu.mst create mode 100644 packages/upward-spec/suite/scenarios/005-many-resolvers/notFound.mst create mode 100644 packages/upward-spec/test_upward_server.sh create mode 100644 packages/upward-spec/tiered_architecture.png create mode 100644 packages/upward-spec/unified_graph.png delete mode 100644 packages/venia-concept/.env.dist create mode 100644 packages/venia-concept/CHANGELOG.md delete mode 100644 packages/venia-concept/Magento_Theme/templates/root.phtml delete mode 100644 packages/venia-concept/composer.json delete mode 100644 packages/venia-concept/etc/view.xml create mode 100644 packages/venia-concept/example.env create mode 100644 packages/venia-concept/media/favicon.ico delete mode 100644 packages/venia-concept/media/preview.jpg delete mode 100644 packages/venia-concept/registration.php create mode 100644 packages/venia-concept/server.js create mode 100644 packages/venia-concept/src/queries/getProductDetail.graphql create mode 100644 packages/venia-concept/src/queries/urlResolver.graphql create mode 100644 packages/venia-concept/templates/doctype-and-head-start.mst create mode 100644 packages/venia-concept/templates/generic-shell.mst create mode 100644 packages/venia-concept/templates/notfound-shell.mst create mode 100644 packages/venia-concept/templates/preloads.mst create mode 100644 packages/venia-concept/templates/product-shell.mst create mode 100644 packages/venia-concept/templates/scripts.mst delete mode 100644 packages/venia-concept/theme.xml create mode 100644 packages/venia-concept/venia-upward.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index b92d5645532..ac168051274 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,7 +36,7 @@ common_settings: full_build: &full_build name: Full Build - command: 'cp packages/venia-concept/.env.dist packages/venia-concept/.env && npm run build && npm run clean:dist' + command: 'cp packages/venia-concept/example.env packages/venia-concept/.env && npm run build && npm run clean:dist' test_result_path: &test_result_path path: "test-results" diff --git a/.editorconfig b/.editorconfig index 3460da026f4..78026e36e90 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,9 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true -[{package.json,*.yml}] +[{package.json,*.yml,*.md}] indent_size = 2 indent_style = space + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore index acfc92aca54..fadcbee55e6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,3 @@ __fixtures__ dist pwa-devdocs -packages/venia-concept/web diff --git a/.gitignore b/.gitignore index 20a1bb52e07..af00b74a593 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,9 @@ npm-debug.log coverage test-results dist -packages/venia-concept/web storybook-dist .idea test-report.xml test-results.json lerna-debug.log .env -packages/venia-concept/web diff --git a/.prettierignore b/.prettierignore index 9d57a7f4b6f..a63528f94fa 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,4 @@ coverage package-lock.json dist -web/js pwa-devdocs -packages/venia-concept/web diff --git a/README.md b/README.md index 6feedd3c52b..5f83fc8ab5d 100644 --- a/README.md +++ b/README.md @@ -44,30 +44,48 @@ All packages are versioned in a single repo, but released to `npm` as independen This repository includes the following packages: -* [venia-concept](packages/venia-concept) - Reference/Concept Theme +* [venia-concept](packages/venia-concept) - Reference/Concept Storefront * [pwa-buildpack](packages/pwa-buildpack/README.md) - Build tooling * [peregrine](packages/peregrine/README.md) - eCommerce Component Library * [pwa-module](packages/pwa-module) * [pwa-devdocs](packages/pwa-devdocs) - Project source for the [documentation site] +* [upward-js](packages/upward-js) - Reference implementation of the UPWARD specification +* [upward-spec](packages/upward-spec) - UPWARD specification and test suite -## Install project dependencies +## Quick Setup + +PWA Studio 2.0 requires much less setup than PWA Studio 1.0. The UPWARD architecture means that the Magento instance does not need to be configured to use your project as a theme. Instead, you connect to your Magento instance by simply specifying its URL in your environment. + +### Obtain Magento 2.3 + +1. Make sure the Magento instance you're using is set to development mode, and has the latest 2.3. + + * You need development mode for GraphQL introspection queries to work. + * The latest codebase will have the most up-to-date GraphQL schema. + +2. Ensure that the Venia sample data is installed on the Magento instance. (**TODO: painless instructions for the Composer commands to do that**) + +### Install Dependencies _**Note**: You must have a version of `node.js` >= `8.0.0`, and a version of `npm` >= `5.0.0`. The latest LTS versions of both are recommended._ Follow these steps to install the dependencies for all the packages in the project: -1. Clone the repository -2. Navigate to the root of the repository from the command line -3. Run `npm install` -4. Watch the bootstrapping take place. -5. To run the Venia theme development experience, run `npm run watch:venia` from package root. -6. To run the full PWA Studio deeloper experience, with Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds, run `npm run watch:all` from package root. +1. Clone the repository. +2. Navigate to the root of the repository from the command line +3. Run `npm install` +4. Watch the bootstrapping take place. +5. Create a `packages/venia-concept/.env` file (or set environment variables manually) +6. Set the environment variable `MAGENTO_BACKEND_DOMAIN` to the URL of the backing Magento instance you are using +7. To run the Venia storefront development experience, run `npm run watch:venia` from package root. +8. To run the full PWA Studio developer experience, with Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds, run `npm run watch:all` from package root. +9. To run the staging environment, which uses more compressed assets and more closely reflects production, run `npm run stage:venia` from package root. (This requires that you first run `npm run build` to generate the artifacts being served.) ## Troubleshooting ### When I run the developer mode, I get validation errors -Make sure you have created a `.env` file in `packages/venia-concept` which specifies variables for your local development environment. You can copy from the template `packages/venia-concept/.env.dist`. +Make sure you have created a `.env` file in `packages/venia-concept` which specifies variables for your local development environment. You can copy from the template `packages/venia-concept/example.env`. ### Venia queries to GraphQL produce validation errors @@ -77,18 +95,18 @@ Venia and its GraphQL queries may be out of sync with the schema of your connect ## Things not to do -When using a monorepo and lerna, it's important that you break some common habits that are common when developing front-end packages. - -* Do _not_ run `npm install` to get `node_modules` up to date within any folder under `packages/`. - Instead, run `npm install` in the root of the repo, which will ensure all package's dependencies are up-to-date. -* When adding a new entry to `devDependencies` in a package's `package.json`, ask yourself whether that dependency will be used across multiple packages. - If the answer is "yes," the dependency should instead be installed in the root `package.json`. This will speed up runs of `lerna bootstrap`. +* Our monorepo is set up so that `npm install` can cross-link dependencies (such as Venia's dependency on Buildpack) without any extra tools. Do not run `lerna bootstrap`. +* All devDependencies are installed in the repository root. This means that **all scripts must be run from repository root**; otherwise, the locally installed CLI commands they use will not be available. +* Production dependencies are sometimes installed in child packages, but for some projects, such as Venia, it makes no sense to have production dependencies, because of bundling. +* Don't check in a big change to `package-lock.json`, and don't check in any `package-lock.json` files but the root one. +* Make sure to run `npm run prettier` and `npm run lint` before any commit you intend to push. You may want to set up a [Git hook] for this. [documentation site]: https://magento-research.github.io/pwa-studio/ [CircleCI]: https://circleci.com/gh/magento-research/pwa-studio.svg?style=svg [Coverage Status]: https://coveralls.io/repos/github/magento-research/pwa-studio/badge.svg?branch=master [Greenkeeper badge]: https://badges.greenkeeper.io/magento-research/pwa-studio.svg [Contribution guide]: .github/CONTRIBUTING.md +[Git hook]: [mage2pratik]: https://github.com/mage2pratik [mage2pratik-image]: https://avatars0.githubusercontent.com/u/33807558?s=120&v=4 diff --git a/greenkeeper.json b/greenkeeper.json deleted file mode 100644 index a85effe1549..00000000000 --- a/greenkeeper.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "groups": { - "default": { - "packages": [ - "package.json", - "packages/peregrine/package.json", - "packages/pwa-buildpack/package.json", - "packages/pwa-devdocs/package.json", - "packages/pwa-module/package.json", - "packages/venia-concept/package.json" - ] - } - } -} diff --git a/jest.config.js b/jest.config.js index 18b7540e6e8..73b22d0824c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,6 +4,7 @@ module.exports = { projects: [ 'packages/peregrine', 'packages/pwa-buildpack', + 'packages/upward-js', 'packages/venia-concept', 'scripts' ], diff --git a/lerna.json b/lerna.json index 69d022657de..5597efdfd18 100644 --- a/lerna.json +++ b/lerna.json @@ -4,6 +4,8 @@ "packages/peregrine", "packages/pwa-buildpack", "packages/pwa-devdocs", + "packages/upward-js", + "packages/upward-spec", "packages/venia-concept" ], "npmClient": "npm", @@ -11,7 +13,7 @@ "publish": { "ignoreChanges": [ "__tests__/**", - "pwa-module" + "pwa-devdocs" ] } } diff --git a/package-lock.json b/package-lock.json index ea1f67bc9b7..07c26b5ad8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,21 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apollographql/apollo-upload-server": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz", + "integrity": "sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0-rc.1", + "busboy": "^0.2.14", + "object-path": "^0.11.4" + } + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz", + "integrity": "sha512-QAZIFrfVRkjvMkUHIQKZXZ3La0V5t12w5PWrhihYEabHwzIZV/txQd/kSYHgYPXC4s5OURxsXZop9f0BzI2QIQ==" + }, "@babel/code-frame": { "version": "7.0.0-beta.44", "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz", @@ -31,6 +46,12 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -72,6 +93,14 @@ "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^3.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + } } }, "@babel/parser": { @@ -160,15 +189,15 @@ } }, "@lerna/add": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.3.2.tgz", - "integrity": "sha512-nKRRRKb4wt/GAywi8P++NY1TUiyhMs2g2KHSb41I4/qiCFQnTj2zkeshPyNmtBGjKzFXnOqrmc/8Wa2vmHHZVg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.4.1.tgz", + "integrity": "sha512-Vf54B42jlD6G52qnv/cAGH70cVQIa+LX//lfsbkxHvzkhIqBl5J4KsnTOPkA9uq3R+zP58ayicCHB9ReiEWGJg==", "dev": true, "requires": { - "@lerna/bootstrap": "^3.3.2", + "@lerna/bootstrap": "^3.4.1", "@lerna/command": "^3.3.0", "@lerna/filter-options": "^3.3.2", - "@lerna/npm-conf": "^3.0.0", + "@lerna/npm-conf": "^3.4.1", "@lerna/validation-error": "^3.0.0", "dedent": "^0.7.0", "npm-package-arg": "^6.0.0", @@ -189,19 +218,19 @@ } }, "@lerna/bootstrap": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.3.2.tgz", - "integrity": "sha512-f0/FZ6iCXHNpHoUiM3wfmiJebHetrquP9mdNT7t//2iTGm1nz8iuKSLhfu9APazDXtqo3aDFx7JvuYKMg+GiXQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.4.1.tgz", + "integrity": "sha512-yZDJgNm/KDoRH2klzmQGmpWMg/XMzWgeWvauXkrfW/mj1wwmufOuh5pN4fBFxVmUUa/RFZdfMeaaJt3+W3PPBw==", "dev": true, "requires": { "@lerna/batch-packages": "^3.1.2", "@lerna/command": "^3.3.0", "@lerna/filter-options": "^3.3.2", "@lerna/has-npm-version": "^3.3.0", - "@lerna/npm-conf": "^3.0.0", + "@lerna/npm-conf": "^3.4.1", "@lerna/npm-install": "^3.3.0", "@lerna/rimraf-dir": "^3.3.0", - "@lerna/run-lifecycle": "^3.3.1", + "@lerna/run-lifecycle": "^3.4.1", "@lerna/run-parallel-batches": "^3.0.0", "@lerna/symlink-binary": "^3.3.0", "@lerna/symlink-dependencies": "^3.3.0", @@ -220,16 +249,16 @@ } }, "@lerna/changed": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.3.2.tgz", - "integrity": "sha512-wLH6RzYPQAryrsJakc9I3k0aFWE/cJyWoUD8dQy186jxwtLgeQdVc0+NegNyab7MIPi7Hsv9A3hx6lM1rPH94A==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.4.1.tgz", + "integrity": "sha512-gT7fhl4zQWyGETDO4Yy5wsFnqNlBSsezncS1nkMW1uO6jwnolwYqcr1KbrMR8HdmsZBn/00Y0mRnbtbpPPey8w==", "dev": true, "requires": { "@lerna/collect-updates": "^3.3.2", "@lerna/command": "^3.3.0", "@lerna/listable": "^3.0.0", "@lerna/output": "^3.0.0", - "@lerna/version": "^3.3.2" + "@lerna/version": "^3.4.1" } }, "@lerna/check-working-tree": { @@ -483,16 +512,15 @@ } }, "@lerna/conventional-commits": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.3.0.tgz", - "integrity": "sha512-nUFardc5G4jG5LI/Jlw0kblzlRLJ08ut6uJjHXTnUE/QJuKYaqBZm6goGG8OSxp/WltklndkQUOtThyZpefviA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.4.1.tgz", + "integrity": "sha512-3NETrA58aUkaEW3RdwdJ766Bg9NVpLzb26mtdlsJQcvB5sQBWH5dJSHIVQH1QsGloBeH2pE/mDUEVY8ZJXuR4w==", "dev": true, "requires": { "@lerna/validation-error": "^3.0.0", - "conventional-changelog-angular": "^1.6.6", - "conventional-changelog-core": "^2.0.5", - "conventional-recommended-bump": "^2.0.6", - "dedent": "^0.7.0", + "conventional-changelog-angular": "^5.0.1", + "conventional-changelog-core": "^3.1.0", + "conventional-recommended-bump": "^4.0.1", "fs-extra": "^7.0.0", "get-stream": "^4.0.0", "npm-package-arg": "^6.0.0", @@ -542,14 +570,14 @@ } }, "@lerna/create": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.3.1.tgz", - "integrity": "sha512-4VASkTLvN66euTcWMPN2vIzEoP07hgutx7V70CXSOc+DiWV8S22z0PjXATi2yli83TC/Qj4gHYtU2futQrdY1A==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.4.1.tgz", + "integrity": "sha512-l+4t2SRO5nvW0MNYY+EWxbaMHsAN8bkWH3nyt7EzhBjs4+TlRAJRIEqd8o9NWznheE3pzwczFz1Qfl3BWbyM5A==", "dev": true, "requires": { "@lerna/child-process": "^3.3.0", "@lerna/command": "^3.3.0", - "@lerna/npm-conf": "^3.0.0", + "@lerna/npm-conf": "^3.4.1", "@lerna/validation-error": "^3.0.0", "camelcase": "^4.1.0", "dedent": "^0.7.0", @@ -825,9 +853,9 @@ } }, "@lerna/npm-conf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.0.0.tgz", - "integrity": "sha512-xXG7qt349t+xzaHTQELmIDjbq8Q49HOMR8Nx/gTDBkMl02Fno91LXFnA4A7ErPiyUSGqNSfLw+zgij0hgpeN7w==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.4.1.tgz", + "integrity": "sha512-i9G6DnbCqiAqxKx2rSXej/n14qxlV/XOebL6QZonxJKzNTB+Q2wglnhTXmfZXTPJfoqimLaY4NfAEtbOXRWOXQ==", "dev": true, "requires": { "config-chain": "^1.1.11", @@ -970,23 +998,6 @@ "write-json-file": "^2.3.0" }, "dependencies": { - "cosmiconfig": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.6.tgz", - "integrity": "sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -1027,16 +1038,6 @@ "is-extglob": "^2.1.0" } }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -1049,16 +1050,6 @@ "strip-bom": "^3.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -1106,6 +1097,15 @@ "tmp": "^0.0.33" } }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1139,9 +1139,9 @@ } }, "@lerna/publish": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.4.0.tgz", - "integrity": "sha512-wcqWDKbkDjyj6F9Mw4/LL2CtpCN61RazNKxYm+fyJ20P2zfcAwLEwxttA6ZWIO8xUiLXkCTFIhwOulHyAPAq3w==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.4.1.tgz", + "integrity": "sha512-Nd5PT2Ksngo1GHqT6ccmGVfMvoA9MplBvqyzPFIjFIJOgODrJ9IGJAMobxgBQ6xXXShflQ/1dHWk8faTOYKLoQ==", "dev": true, "requires": { "@lerna/batch-packages": "^3.1.2", @@ -1151,15 +1151,15 @@ "@lerna/command": "^3.3.0", "@lerna/describe-ref": "^3.3.0", "@lerna/get-npm-exec-opts": "^3.0.0", - "@lerna/npm-conf": "^3.0.0", + "@lerna/npm-conf": "^3.4.1", "@lerna/npm-dist-tag": "^3.3.0", "@lerna/npm-publish": "^3.3.1", "@lerna/output": "^3.0.0", "@lerna/prompt": "^3.3.1", - "@lerna/run-lifecycle": "^3.3.1", + "@lerna/run-lifecycle": "^3.4.1", "@lerna/run-parallel-batches": "^3.0.0", "@lerna/validation-error": "^3.0.0", - "@lerna/version": "^3.3.2", + "@lerna/version": "^3.4.1", "fs-extra": "^7.0.0", "libnpmaccess": "^3.0.0", "npm-package-arg": "^6.0.0", @@ -1246,12 +1246,12 @@ } }, "@lerna/run-lifecycle": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.3.1.tgz", - "integrity": "sha512-xy4K3amlXk0LjSa5d3VqmrW9SsxMyvI7lw2dHDMb5PqjjcjMQgb6+nFbycwyJMhCP8u7MwQIZ4hFYF9XYbWSzQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.4.1.tgz", + "integrity": "sha512-N/hi2srM9A4BWEkXccP7vCEbf4MmIuALF00DTBMvc0A/ccItwUpl3XNuM7+ADDRK0mkwE3hDw89lJ3A7f8oUQw==", "dev": true, "requires": { - "@lerna/npm-conf": "^3.0.0", + "@lerna/npm-conf": "^3.4.1", "npm-lifecycle": "^2.0.0", "npmlog": "^4.1.2" } @@ -1302,16 +1302,6 @@ "strip-bom": "^3.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -1384,9 +1374,9 @@ } }, "@lerna/version": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.3.2.tgz", - "integrity": "sha512-2MHP6mA1f0t3UdzqPpfgAhsT1L64HOedlJxrQUoHrkou/G25Od4wjmKr9OZ0Oc4CLDbXD/sYEmE/9fZi1GGgKg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.4.1.tgz", + "integrity": "sha512-oefNaQLBJSI2WLZXw5XxDXk4NyF5/ct0V9ys/J308NpgZthPgwRPjk9ZR0o1IOxW1ABi6z3E317W/dxHDjvAkg==", "dev": true, "requires": { "@lerna/batch-packages": "^3.1.2", @@ -1394,10 +1384,10 @@ "@lerna/child-process": "^3.3.0", "@lerna/collect-updates": "^3.3.2", "@lerna/command": "^3.3.0", - "@lerna/conventional-commits": "^3.3.0", + "@lerna/conventional-commits": "^3.4.1", "@lerna/output": "^3.0.0", "@lerna/prompt": "^3.3.1", - "@lerna/run-lifecycle": "^3.3.1", + "@lerna/run-lifecycle": "^3.4.1", "@lerna/validation-error": "^3.0.0", "chalk": "^2.3.1", "dedent": "^0.7.0", @@ -1457,20 +1447,27 @@ "@magento/devcert": "^0.7.0", "@magento/directive-parser": "^0.1.1", "ajv": "^6.1.1", + "apollo-boost": "^0.1.15", "babel-helper-module-imports": "^7.0.0-beta.3", "babel-plugin-syntax-dynamic-import": "^6.18.0", "boxen": "^1.3.0", "chalk": "^2.4.1", + "cssnano": "^4.1.0", "debug": "^3.1.0", + "debug-error-middleware": "^1.3.0", "express": "^4.16.2", "flat-file-db": "^1.0.0", + "graphql": "^14.0.2", + "graphql-tag": "^2.9.2", "harmon": "^1.3.2", "hostile": "^1.3.1", "http-proxy-middleware": "^0.18.0", "lodash.get": "^4.4.2", + "node-fetch": "^2.2.0", "one-time": "^0.0.4", "openport": "0.0.5", "post-compile-webpack-plugin": "^0.1.2", + "react-dom": "^16.5.0", "through": "^2.3.8", "webpack-sources": "^1.1.0", "workbox-webpack-plugin": "^3.0.0-beta.1", @@ -1486,205 +1483,1214 @@ } } }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz", - "integrity": "sha512-yprFYuno9FtNsSHVlSWd+nRlmGoAbqbeCwOryP6sC/zoCjhpArcRMYp19EvpSUSizJAlsXEwJv+wcWS9XaXdMw==", - "dev": true - }, - "@octokit/rest": { - "version": "15.12.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.12.1.tgz", - "integrity": "sha512-Nn3o2iVHHWNbw8MSOWTa67/6N1e7muaDWVMWr3FXUDSlMzB3lXlr6EdO1hwfUzpmZAkNc1rFN4y0tuy38gtd+A==", - "dev": true, + "@magento/upward-js": { + "version": "file:packages/upward-js", "requires": { - "before-after-hook": "^1.1.0", - "btoa-lite": "^1.0.0", + "apollo-boost": "^0.1.13", + "apollo-link": "^1.2.2", + "apollo-link-http": "^1.5.4", + "contains-path": "^1.0.0", "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lodash": "^4.17.4", - "node-fetch": "^2.1.1", - "universal-user-agent": "^2.0.0", - "url-template": "^2.0.8" - } - }, - "@storybook/addon-actions": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-3.4.11.tgz", - "integrity": "sha512-vA7KiMg6J3SlI0U9COhyX+nxoNNXsgXTKBA7oVjE+wduNwNc86WcbYGxKIxhCjJMBoAjZYBeRL9DmYWwaHb4xQ==", - "dev": true, - "requires": { - "@storybook/components": "3.4.11", - "babel-runtime": "^6.26.0", - "deep-equal": "^1.0.1", - "glamor": "^2.20.40", - "glamorous": "^4.12.1", - "global": "^4.3.2", - "make-error": "^1.3.4", - "prop-types": "^15.6.1", - "react-inspector": "^2.2.2", - "uuid": "^3.2.1" - }, - "dependencies": { - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true - } - } - }, - "@storybook/addon-links": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-3.4.11.tgz", - "integrity": "sha512-DFTBj359ANqKJBhcSw2zAojlWF4A4+U48sKOhcPZ96qwPPtZwMtUR1TYxP+6ssfEP4tlA9zs4dn0+yRye+ydNQ==", - "dev": true, - "requires": { - "@storybook/components": "3.4.11", - "babel-runtime": "^6.26.0", - "global": "^4.3.2", - "prop-types": "^15.6.1" - } - }, - "@storybook/addons": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-3.4.11.tgz", - "integrity": "sha512-Uf01aZ1arcpG1prrrCrBCUYW63lDaoG+r/i3TNo1iG9ZaNc+2UHWeuiEedLfHg0fi/q7UnqMNWDiyO3AkEwwrA==", - "dev": true - }, - "@storybook/channel-postmessage": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-3.4.11.tgz", - "integrity": "sha512-uzJS3xkx4r9L10j5Tb+rsHOmHh8Xq6hovZYYLhsSxWKysyhDI7vRMhfmZVadXNoncSjSHSG8BtSJexIeeQCBuw==", - "dev": true, - "requires": { - "@storybook/channels": "3.4.11", - "global": "^4.3.2", - "json-stringify-safe": "^5.0.1" - } - }, - "@storybook/channels": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-3.4.11.tgz", - "integrity": "sha512-49A79anI04nhMsNzyk5cF8fa3+HKZkb9RLshtaqvQmM7olQxCrks6cIdE2Y1zMBuyZxX1ARhcBCFVw+PUxkJjA==", - "dev": true - }, - "@storybook/client-logger": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-3.4.11.tgz", - "integrity": "sha512-rQ1f0ItOd8l4JX0cJpP976jU6c1+yOl1DfNcitL+1/dG4wwuvaB3j4rhe8VwTiFjYe6arm3hMeRzu5mUTVbSVg==", - "dev": true - }, - "@storybook/components": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-3.4.11.tgz", - "integrity": "sha512-M3WhGPR4LNB2NabKyLtxDMevB1LAHOrmrII2U19XYIph93k3SReIwLKWEds0/jWwajgQtI3hBftDCu/QA5bTOA==", - "dev": true, - "requires": { - "glamor": "^2.20.40", - "glamorous": "^4.12.1", - "prop-types": "^15.6.1" - } - }, - "@storybook/core": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-3.4.11.tgz", - "integrity": "sha512-WoocDMuvyB2OPnv6h4OuoGqspsdnZRzf1DxkYZHIOxHo3jeSwovvLvf1Y/G8PRWugSoy8ujwMfkN31dITXHGTA==", - "dev": true, - "requires": { - "@storybook/addons": "3.4.11", - "@storybook/channel-postmessage": "3.4.11", - "@storybook/client-logger": "3.4.11", - "@storybook/node-logger": "3.4.11", - "@storybook/ui": "3.4.11", - "autoprefixer": "^7.2.6", - "babel-runtime": "^6.26.0", - "chalk": "^2.3.2", - "commander": "^2.15.0", - "css-loader": "^0.28.11", - "dotenv": "^5.0.1", - "events": "^2.0.0", - "express": "^4.16.3", - "file-loader": "^1.1.11", - "global": "^4.3.2", - "json-loader": "^0.5.7", - "postcss-flexbugs-fixes": "^3.2.0", - "postcss-loader": "^2.1.2", - "prop-types": "^15.6.1", - "qs": "^6.5.1", - "serve-favicon": "^2.4.5", - "shelljs": "^0.8.1", - "style-loader": "^0.20.3", - "url-loader": "^0.6.2", - "webpack": "^3.11.0", - "webpack-dev-middleware": "^1.12.2", - "webpack-hot-middleware": "^2.22.1" + "debug-error-middleware": "^1.3.0", + "dotenv": "^6.0.0", + "graphql": "^0.13.2", + "graphql-tag": "^2.9.2", + "hogan.js": "^3.0.2", + "http-proxy-middleware": "^0.19.0", + "js-yaml": "^3.12.0", + "lodash": "^4.17.10", + "morgan": "^1.9.0", + "mustache": "^2.3.2", + "traverse": "^0.6.6" }, "dependencies": { - "autoprefixer": { - "version": "7.2.6", - "resolved": "http://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", - "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", - "dev": true, - "requires": { - "browserslist": "^2.11.3", - "caniuse-lite": "^1.0.30000805", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^6.0.17", - "postcss-value-parser": "^3.2.3" - } + "arr-diff": { + "version": "4.0.0", + "bundled": true }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" - } + "arr-flatten": { + "version": "1.1.0", + "bundled": true }, - "dotenv": { - "version": "5.0.1", - "resolved": "http://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", - "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==", - "dev": true + "arr-union": { + "version": "3.1.0", + "bundled": true }, - "events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "dev": true + "array-unique": { + "version": "0.3.2", + "bundled": true }, - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, + "assign-symbols": { + "version": "1.0.0", + "bundled": true + }, + "atob": { + "version": "2.1.2", + "bundled": true + }, + "auto-parse": { + "version": "1.5.1", + "bundled": true, + "requires": { + "typpy": "^2.3.10" + } + }, + "base": { + "version": "0.11.2", + "bundled": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "braces": { + "version": "2.3.2", + "bundled": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "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.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "bundled": true, + "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" + } + }, + "class-utils": { + "version": "0.3.6", + "bundled": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "collection-visit": { + "version": "1.0.0", + "bundled": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "component-emitter": { + "version": "1.2.1", + "bundled": true + }, + "copy-descriptor": { + "version": "0.1.1", + "bundled": true + }, + "decode-uri-component": { + "version": "0.2.0", + "bundled": true + }, + "define-property": { + "version": "2.0.2", + "bundled": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "eventemitter3": { + "version": "3.1.0", + "bundled": true + }, + "expand-brackets": { + "version": "2.1.4", + "bundled": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "bundled": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "bundled": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "bundled": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "bundled": true, + "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" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "bundled": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "follow-redirects": { + "version": "1.5.8", + "bundled": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "bundled": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "bundled": true + }, + "fragment-cache": { + "version": "0.2.1", + "bundled": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "function.name": { + "version": "1.0.11", + "bundled": true, + "requires": { + "noop6": "^1.0.1" + } + }, + "get-value": { + "version": "2.0.6", + "bundled": true + }, + "has-value": { + "version": "1.0.0", + "bundled": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "bundled": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "http-proxy": { + "version": "1.17.0", + "bundled": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.0", + "bundled": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.10", + "micromatch": "^3.1.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "bundled": true + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "bundled": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "bundled": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "bundled": true + }, + "is-extglob": { + "version": "2.1.1", + "bundled": true + }, + "is-glob": { + "version": "4.0.0", + "bundled": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "bundled": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "bundled": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "isobject": { + "version": "3.0.1", + "bundled": true + }, + "kind-of": { + "version": "6.0.2", + "bundled": true + }, + "map-cache": { + "version": "0.2.2", + "bundled": true + }, + "map-visit": { + "version": "1.0.0", + "bundled": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "bundled": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mixin-deep": { + "version": "1.3.1", + "bundled": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "ms": { + "version": "2.0.0", + "bundled": true + }, + "nanomatch": { + "version": "1.2.13", + "bundled": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "noop6": { + "version": "1.0.7", + "bundled": true + }, + "object-copy": { + "version": "0.1.0", + "bundled": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "bundled": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "bundled": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "pascalcase": { + "version": "0.1.1", + "bundled": true + }, + "posix-character-classes": { + "version": "0.1.1", + "bundled": true + }, + "regex-not": { + "version": "1.0.2", + "bundled": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "repeat-element": { + "version": "1.1.3", + "bundled": true + }, + "repeat-string": { + "version": "1.6.1", + "bundled": true + }, + "requires-port": { + "version": "1.0.0", + "bundled": true + }, + "resolve-url": { + "version": "0.2.1", + "bundled": true + }, + "ret": { + "version": "0.1.15", + "bundled": true + }, + "safe-regex": { + "version": "1.1.0", + "bundled": true, + "requires": { + "ret": "~0.1.10" + } + }, + "set-value": { + "version": "2.0.0", + "bundled": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon": { + "version": "0.8.2", + "bundled": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "bundled": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "bundled": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "bundled": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "bundled": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "bundled": true + }, + "source-map-resolve": { + "version": "0.5.2", + "bundled": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "bundled": true + }, + "split-string": { + "version": "3.1.0", + "bundled": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "static-extend": { + "version": "0.1.2", + "bundled": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "to-object-path": { + "version": "0.3.0", + "bundled": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "bundled": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "bundled": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "typpy": { + "version": "2.3.10", + "bundled": true, + "requires": { + "function.name": "^1.0.3" + } + }, + "union-value": { + "version": "1.0.0", + "bundled": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "bundled": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "bundled": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "bundled": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "bundled": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "bundled": true + } + } + }, + "urix": { + "version": "0.1.0", + "bundled": true + }, + "use": { + "version": "3.1.1", + "bundled": true + } + } + }, + "@magento/upward-spec": { + "version": "file:packages/upward-spec", + "requires": { + "apollo-server": "^2.0.5", + "chalk": "^2.4.1", + "csv-parse": "^3.0.0", + "death": "^1.1.0", + "graphql": "^0.13.2", + "graphql-tag": "^2.9.2", + "js-yaml": "^3.12.0", + "tap-diff": "^0.1.1", + "tap-xunit": "^2.3.0", + "tape": "^4.9.1" + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz", + "integrity": "sha512-yprFYuno9FtNsSHVlSWd+nRlmGoAbqbeCwOryP6sC/zoCjhpArcRMYp19EvpSUSizJAlsXEwJv+wcWS9XaXdMw==", + "dev": true + }, + "@octokit/rest": { + "version": "15.12.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.12.1.tgz", + "integrity": "sha512-Nn3o2iVHHWNbw8MSOWTa67/6N1e7muaDWVMWr3FXUDSlMzB3lXlr6EdO1hwfUzpmZAkNc1rFN4y0tuy38gtd+A==", + "dev": true, + "requires": { + "before-after-hook": "^1.1.0", + "btoa-lite": "^1.0.0", + "debug": "^3.1.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.0", + "lodash": "^4.17.4", + "node-fetch": "^2.1.1", + "universal-user-agent": "^2.0.0", + "url-template": "^2.0.8" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@storybook/addon-actions": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-3.4.11.tgz", + "integrity": "sha512-vA7KiMg6J3SlI0U9COhyX+nxoNNXsgXTKBA7oVjE+wduNwNc86WcbYGxKIxhCjJMBoAjZYBeRL9DmYWwaHb4xQ==", + "dev": true, + "requires": { + "@storybook/components": "3.4.11", + "babel-runtime": "^6.26.0", + "deep-equal": "^1.0.1", + "glamor": "^2.20.40", + "glamorous": "^4.12.1", + "global": "^4.3.2", + "make-error": "^1.3.4", + "prop-types": "^15.6.1", + "react-inspector": "^2.2.2", + "uuid": "^3.2.1" + } + }, + "@storybook/addon-links": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-3.4.11.tgz", + "integrity": "sha512-DFTBj359ANqKJBhcSw2zAojlWF4A4+U48sKOhcPZ96qwPPtZwMtUR1TYxP+6ssfEP4tlA9zs4dn0+yRye+ydNQ==", + "dev": true, + "requires": { + "@storybook/components": "3.4.11", + "babel-runtime": "^6.26.0", + "global": "^4.3.2", + "prop-types": "^15.6.1" + } + }, + "@storybook/addons": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-3.4.11.tgz", + "integrity": "sha512-Uf01aZ1arcpG1prrrCrBCUYW63lDaoG+r/i3TNo1iG9ZaNc+2UHWeuiEedLfHg0fi/q7UnqMNWDiyO3AkEwwrA==", + "dev": true + }, + "@storybook/channel-postmessage": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-3.4.11.tgz", + "integrity": "sha512-uzJS3xkx4r9L10j5Tb+rsHOmHh8Xq6hovZYYLhsSxWKysyhDI7vRMhfmZVadXNoncSjSHSG8BtSJexIeeQCBuw==", + "dev": true, + "requires": { + "@storybook/channels": "3.4.11", + "global": "^4.3.2", + "json-stringify-safe": "^5.0.1" + } + }, + "@storybook/channels": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-3.4.11.tgz", + "integrity": "sha512-49A79anI04nhMsNzyk5cF8fa3+HKZkb9RLshtaqvQmM7olQxCrks6cIdE2Y1zMBuyZxX1ARhcBCFVw+PUxkJjA==", + "dev": true + }, + "@storybook/client-logger": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-3.4.11.tgz", + "integrity": "sha512-rQ1f0ItOd8l4JX0cJpP976jU6c1+yOl1DfNcitL+1/dG4wwuvaB3j4rhe8VwTiFjYe6arm3hMeRzu5mUTVbSVg==", + "dev": true + }, + "@storybook/components": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-3.4.11.tgz", + "integrity": "sha512-M3WhGPR4LNB2NabKyLtxDMevB1LAHOrmrII2U19XYIph93k3SReIwLKWEds0/jWwajgQtI3hBftDCu/QA5bTOA==", + "dev": true, + "requires": { + "glamor": "^2.20.40", + "glamorous": "^4.12.1", + "prop-types": "^15.6.1" + } + }, + "@storybook/core": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-3.4.11.tgz", + "integrity": "sha512-WoocDMuvyB2OPnv6h4OuoGqspsdnZRzf1DxkYZHIOxHo3jeSwovvLvf1Y/G8PRWugSoy8ujwMfkN31dITXHGTA==", + "dev": true, + "requires": { + "@storybook/addons": "3.4.11", + "@storybook/channel-postmessage": "3.4.11", + "@storybook/client-logger": "3.4.11", + "@storybook/node-logger": "3.4.11", + "@storybook/ui": "3.4.11", + "autoprefixer": "^7.2.6", + "babel-runtime": "^6.26.0", + "chalk": "^2.3.2", + "commander": "^2.15.0", + "css-loader": "^0.28.11", + "dotenv": "^5.0.1", + "events": "^2.0.0", + "express": "^4.16.3", + "file-loader": "^1.1.11", + "global": "^4.3.2", + "json-loader": "^0.5.7", + "postcss-flexbugs-fixes": "^3.2.0", + "postcss-loader": "^2.1.2", + "prop-types": "^15.6.1", + "qs": "^6.5.1", + "serve-favicon": "^2.4.5", + "shelljs": "^0.8.1", + "style-loader": "^0.20.3", + "url-loader": "^0.6.2", + "webpack": "^3.11.0", + "webpack-dev-middleware": "^1.12.2", + "webpack-hot-middleware": "^2.22.1" + }, + "dependencies": { + "autoprefixer": { + "version": "7.2.6", + "resolved": "http://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", + "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", + "dev": true, + "requires": { + "browserslist": "^2.11.3", + "caniuse-lite": "^1.0.30000805", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.17", + "postcss-value-parser": "^3.2.3" + } + }, + "browserslist": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", + "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" + } + }, + "dotenv": { + "version": "5.0.1", + "resolved": "http://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", + "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, "requires": { "chalk": "^2.4.1", "source-map": "^0.6.1", "supports-color": "^5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "style-loader": { "version": "0.20.3", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.20.3.tgz", @@ -1859,23 +2865,112 @@ } } }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "requires": { + "@types/node": "*" + } + }, "@types/async": { "version": "2.0.49", "resolved": "https://registry.npmjs.org/@types/async/-/async-2.0.49.tgz", "integrity": "sha512-Benr3i5odUkvpFkOpzGqrltGdbSs+EVCkEBGXbuR7uT0VzhXKIkhem6PDzHdx5EonA+rfbB3QvP6aDOw5+zp5Q==", - "dev": true, "optional": true }, + "@types/body-parser": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", + "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "requires": { + "@types/node": "*" + } + }, + "@types/cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.4.tgz", + "integrity": "sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw==", + "requires": { + "@types/express": "*" + } + }, + "@types/events": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + }, + "@types/express": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.0.tgz", + "integrity": "sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz", + "integrity": "sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w==", + "requires": { + "@types/events": "*", + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, + "@types/mime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", + "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" + }, "@types/node": { "version": "10.11.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.11.4.tgz", "integrity": "sha512-ojnbBiKkZFYRfQpmtnnWTMw+rzGp/JiystjluW9jgN3VzRwilXddJ6aGQ9V/7iuDG06SBgn7ozW9k3zcAnYjYQ==" }, + "@types/range-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.2.tgz", + "integrity": "sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw==" + }, + "@types/serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "@types/ws": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz", + "integrity": "sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, "@types/zen-observable": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz", - "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==", - "dev": true + "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" }, "JSONStream": { "version": "1.3.4", @@ -2199,7 +3294,6 @@ "version": "0.1.16", "resolved": "https://registry.npmjs.org/apollo-boost/-/apollo-boost-0.1.16.tgz", "integrity": "sha512-ppnQr90n2cn0ZMveEbqxW6NxmskIpThiLziLlRpRLy4keoAICg1NZecxJQmeaBLMtyhf5UholAjpS2SLmEJeHg==", - "dev": true, "requires": { "apollo-cache": "^1.1.17", "apollo-cache-inmemory": "^1.2.10", @@ -2215,16 +3309,23 @@ "version": "1.1.17", "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.1.17.tgz", "integrity": "sha512-7sp24n2HZO4vXgTaKNomLyIfGxG4gDdDkBB0jkRzRi7HhnKmfwhiF/RCiKNbgLdrPX151INdls0KwIVliD0dHQ==", - "dev": true, "requires": { "apollo-utilities": "^1.0.21" } }, + "apollo-cache-control": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz", + "integrity": "sha512-xEDrUvo3U2mQKSzA8NzQmgeqK4ytwFnTGl2YKGKPfG0+r8fZdswKp6CDBue29KLO8KkSuqW/hntveWrAdK51FQ==", + "requires": { + "apollo-server-env": "^2.0.3", + "graphql-extensions": "^0.2.1" + } + }, "apollo-cache-inmemory": { "version": "1.2.10", "resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz", "integrity": "sha512-eBusPFVtYIuo+PIfJdAwUCQ4cs7AJ4mB7sTdXxNQCXToYw8mzE6EfHnV37kdVfBXSaa82BzE2rb/YUq/duuamw==", - "dev": true, "requires": { "apollo-cache": "^1.1.17", "apollo-utilities": "^1.0.21", @@ -2235,7 +3336,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.4.2.tgz", "integrity": "sha512-g1z23umaVSoKLj9xNl0aAnk2KBF4JeBi7MeKFc9CGTixH7TkqeQUQtxcjrC7j2h4KmDbuhOAHOFUGf8YshN+ag==", - "dev": true, "requires": { "@types/async": "2.0.49", "@types/zen-observable": "^0.8.0", @@ -2247,11 +3347,39 @@ "zen-observable": "^0.8.0" } }, + "apollo-datasource": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.1.3.tgz", + "integrity": "sha512-yEGEe5Cjzqqu5ml1VV3O8+C+thzdknZri9Ny0P3daTGNO+45J3vBOMcmaANeeI2+OOeWxdqUNa5aPOx/35kniw==", + "requires": { + "apollo-server-caching": "0.1.2", + "apollo-server-env": "2.0.3" + } + }, + "apollo-engine-reporting": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz", + "integrity": "sha512-JmfNJ9v3QEJQ8ZhLfCKEDiww53n5kj5HarP85p8LreoYNojbvcWN8Qm6RgvSG5N/ZJrAYHeTRQbSxm1vWwGubw==", + "requires": { + "apollo-engine-reporting-protobuf": "^0.0.1", + "apollo-server-env": "^2.0.3", + "async-retry": "^1.2.1", + "graphql-extensions": "^0.2.1", + "lodash": "^4.17.10" + } + }, + "apollo-engine-reporting-protobuf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz", + "integrity": "sha512-AySoDgog2p1Nph44FyyqaU4AfRZOXx8XZxRsVHvYY4dHlrMmDDhhjfF3Jswa7Wr8X/ivvx3xA0jimRn6rsG8Ew==", + "requires": { + "protobufjs": "^6.8.6" + } + }, "apollo-link": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.3.tgz", "integrity": "sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw==", - "dev": true, "requires": { "apollo-utilities": "^1.0.0", "zen-observable-ts": "^0.8.10" @@ -2270,7 +3398,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz", "integrity": "sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w==", - "dev": true, "requires": { "apollo-link": "^1.2.3" } @@ -2279,7 +3406,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.1.1.tgz", "integrity": "sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA==", - "dev": true, "requires": { "apollo-link": "^1.2.3" } @@ -2288,7 +3414,6 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.5.tgz", "integrity": "sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ==", - "dev": true, "requires": { "apollo-link": "^1.2.3", "apollo-link-http-common": "^0.2.5" @@ -2298,7 +3423,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz", "integrity": "sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w==", - "dev": true, "requires": { "apollo-link": "^1.2.3" } @@ -2307,17 +3431,158 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/apollo-link-state/-/apollo-link-state-0.4.2.tgz", "integrity": "sha512-xMPcAfuiPVYXaLwC6oJFIZrKgV3GmdO31Ag2eufRoXpvT0AfJZjdaPB4450Nu9TslHRePN9A3quxNueILlQxlw==", - "dev": true, "requires": { "apollo-utilities": "^1.0.8", "graphql-anywhere": "^4.1.0-alpha.0" } }, + "apollo-server": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.1.0.tgz", + "integrity": "sha512-Uo5RFHGtUPq3OvycLXCll5QgXf2wNVBFYUhapByADBP4E1KRgbyl9Fbf82OgcbbLYwEZTlQMbyBpd6hX8XJKAw==", + "requires": { + "apollo-server-core": "^2.1.0", + "apollo-server-express": "^2.1.0", + "express": "^4.0.0", + "graphql-subscriptions": "^0.5.8", + "graphql-tools": "^3.0.4" + } + }, + "apollo-server-caching": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz", + "integrity": "sha512-jBRnsTgXN0m8yVpumoelaUq9mXR7YpJ3EE+y/alI7zgXY+0qFDqksRApU8dEfg3q6qUnO7rFxRhdG5eyc0+1ig==", + "requires": { + "lru-cache": "^4.1.3" + } + }, + "apollo-server-core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.1.0.tgz", + "integrity": "sha512-D1Tw0o3NzCQ2KGM8EWh9AHELHmn/SE361dtlqJxkbelxXqAkCIGIFywF30h+0ezhMbgbO7eqBBJfvRilF/oJHA==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@types/ws": "^5.1.2", + "apollo-cache-control": "^0.2.5", + "apollo-datasource": "^0.1.3", + "apollo-engine-reporting": "^0.0.6", + "apollo-server-caching": "^0.1.2", + "apollo-server-env": "^2.0.3", + "apollo-server-errors": "^2.0.2", + "apollo-tracing": "^0.2.5", + "graphql-extensions": "^0.2.1", + "graphql-subscriptions": "^0.5.8", + "graphql-tag": "^2.9.2", + "graphql-tools": "^3.0.4", + "hash.js": "^1.1.3", + "lodash": "^4.17.10", + "subscriptions-transport-ws": "^0.9.11", + "ws": "^5.2.0" + } + }, + "apollo-server-env": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.0.3.tgz", + "integrity": "sha512-uIfKFH8n8xKO0eLb9Fa79+s2DdMuVethgznvW6SrOYq5VzgkIIobqKEuZPKa5wObw9CkCyju/+Sr7b7WWMFxUQ==", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-errors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz", + "integrity": "sha512-zyWDqAVDCkj9espVsoUpZr9PwDznM8UW6fBfhV+i1br//s2AQb07N6ektZ9pRIEvkhykDZW+8tQbDwAO0vUROg==" + }, + "apollo-server-express": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.1.0.tgz", + "integrity": "sha512-jLFIz1VLduMA/rme4OAy3IPeoaMEZOPoQXpio8AhfjIqCijRPPfoWJ2QMqz56C/g3vas7rZtgcVOrHpjBKudjw==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@apollographql/graphql-playground-html": "^1.6.0", + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.17.0", + "@types/cors": "^2.8.4", + "@types/express": "4.16.0", + "accepts": "^1.3.5", + "apollo-server-core": "^2.1.0", + "body-parser": "^1.18.3", + "cors": "^2.8.4", + "graphql-subscriptions": "^0.5.8", + "graphql-tools": "^3.0.4", + "type-is": "^1.6.16" + }, + "dependencies": { + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "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" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + } + } + }, + "apollo-tracing": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.2.5.tgz", + "integrity": "sha512-DZO7pfL5LATHeJdVFoTZ/N3HwA+IMf1YnIt5K+uMQW+/MrRgYOtTszUv5tYX2cUIqHYHcbdDaBQUuIXwSpaV2Q==", + "requires": { + "apollo-server-env": "^2.0.3", + "graphql-extensions": "^0.2.1" + } + }, "apollo-utilities": { "version": "1.0.21", "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.0.21.tgz", "integrity": "sha512-ZcxELlEl+sDCYBgEMdNXJAsZtRVm8wk4HIA58bMsqYfd1DSAJQEtZ93F0GZgYNAGy3QyaoBeZtbb0/01++G8JQ==", - "dev": true, "requires": { "fast-json-stable-stringify": "^2.0.0", "fclone": "^1.0.11" @@ -2618,9 +3883,12 @@ "dev": true }, "async": { - "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } }, "async-each": { "version": "1.0.1", @@ -2642,6 +3910,14 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, + "async-retry": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", + "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==", + "requires": { + "retry": "0.12.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2663,6 +3939,83 @@ "num2fraction": "^1.2.2", "postcss": "^5.2.16", "postcss-value-parser": "^3.2.3" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } } }, "aws-sign2": { @@ -2714,6 +4067,14 @@ "slash": "^1.0.0", "source-map": "^0.5.6", "v8flags": "^2.1.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "babel-code-frame": { @@ -2748,6 +4109,11 @@ "supports-color": "^2.0.0" } }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, "strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -2813,6 +4179,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -2876,6 +4247,11 @@ "to-fast-properties": "^1.0.3" } }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -3474,6 +4850,15 @@ } } }, + "babel-plugin-import-graphql": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-import-graphql/-/babel-plugin-import-graphql-2.6.2.tgz", + "integrity": "sha1-D4ijsyEzdlhUJTuLp/k4M2fNNg4=", + "dev": true, + "requires": { + "graphql-tag": "^2.9.2" + } + }, "babel-plugin-istanbul": { "version": "4.1.6", "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", @@ -3513,41 +4898,13 @@ "resolve": "^1.8.1" }, "dependencies": { - "cosmiconfig": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.6.tgz", - "integrity": "sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==", - "dev": true, - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "path-parse": "^1.0.5" } } } @@ -3867,11 +5224,232 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + }, + "dependencies": { + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + }, + "dependencies": { + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + }, + "dependencies": { + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + }, + "dependencies": { + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" }, "dependencies": { "babel-types": { @@ -3892,19 +5470,12 @@ } } }, - "babel-plugin-transform-es2015-classes": { + "babel-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", "babel-types": "^6.24.1" }, "dependencies": { @@ -3926,28 +5497,20 @@ } } }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "requires": { "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-duplicate-keys": { + "babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "requires": { + "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" }, @@ -3970,20 +5533,216 @@ } } }, - "babel-plugin-transform-es2015-for-of": { + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-export-extensions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", + "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "dev": true, + "requires": { + "babel-plugin-syntax-export-extensions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-function-bind": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", + "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", + "dev": true, + "requires": { + "babel-plugin-syntax-function-bind": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-inline-consecutive-adds": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.3.0.tgz", + "integrity": "sha512-iZsYAIjYLLfLK0yN5WVT7Xf7Y3wQ9Z75j9A8q/0IglQSpUt2ppTdHlwl/GeaXnxdaSmsxBu861klbTBbv2n+RA==", + "dev": true + }, + "babel-plugin-transform-member-expression-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", + "integrity": "sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8=", + "dev": true + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz", + "integrity": "sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4=", + "dev": true + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", + "integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=", + "dev": true + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-property-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", + "integrity": "sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk=", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "dev": true, + "requires": { + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.18.tgz", + "integrity": "sha512-azed2nHo8vmOy7EY26KH+om5oOcWRs0r1U8wOmhwta+SBMMnmJ4H6yaBZRCcHBtMeWp9AVhvBTL/lpR1kEx+Xw==", + "dev": true + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-regexp-constructors": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.3.0.tgz", + "integrity": "sha512-h92YHzyl042rb0naKO8frTHntpRFwRgKkfWD8602kFHoQingjJNtbvZzvxqHncJ6XmKVyYvfrBpDOSkCTDIIxw==", + "dev": true + }, + "babel-plugin-transform-remove-console": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", + "integrity": "sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A=", + "dev": true + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", + "integrity": "sha1-QrcnYxyXl44estGZp67IShgznvI=", + "dev": true + }, + "babel-plugin-transform-remove-undefined": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.3.0.tgz", + "integrity": "sha512-TYGQucc8iP3LJwN3kDZLEz5aa/2KuFrqpT+s8f8NnHsBU1sAgR3y8Opns0xhC+smyDYWscqFCKM1gbkWQOhhnw==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.3.0" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, "requires": { "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-function-name": { + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", + "integrity": "sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk=", + "dev": true + }, + "babel-plugin-transform-strict-mode": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "requires": { - "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" }, @@ -4006,93 +5765,256 @@ } } }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "requires": { - "babel-runtime": "^6.22.0" - } + "babel-plugin-transform-undefined-to-void": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", + "integrity": "sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=", + "dev": true }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + } } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" }, "dependencies": { - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" } - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" } } }, - "babel-plugin-transform-es2015-modules-systemjs": { + "babel-preset-es2015": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" } }, - "babel-plugin-transform-es2015-modules-umd": { + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, + "babel-preset-jest": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz", + "integrity": "sha1-jsegOhOPABoaj7HoETZSvxpV2kY=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^23.2.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, + "babel-preset-minify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz", + "integrity": "sha512-+VV2GWEyak3eDOmzT1DDMuqHrw3VbE9nBNkx2LLVs4pH/Me32ND8DRpVDd8IRvk1xX5p75nygyRPtkMh6GIAbQ==", + "dev": true, + "requires": { + "babel-plugin-minify-builtins": "^0.3.0", + "babel-plugin-minify-constant-folding": "^0.3.0", + "babel-plugin-minify-dead-code-elimination": "^0.3.0", + "babel-plugin-minify-flip-comparisons": "^0.3.0", + "babel-plugin-minify-guarded-expressions": "^0.3.0", + "babel-plugin-minify-infinity": "^0.3.0", + "babel-plugin-minify-mangle-names": "^0.3.0", + "babel-plugin-minify-numeric-literals": "^0.3.0", + "babel-plugin-minify-replace": "^0.3.0", + "babel-plugin-minify-simplify": "^0.3.0", + "babel-plugin-minify-type-constructors": "^0.3.0", + "babel-plugin-transform-inline-consecutive-adds": "^0.3.0", + "babel-plugin-transform-member-expression-literals": "^6.9.0", + "babel-plugin-transform-merge-sibling-variables": "^6.9.0", + "babel-plugin-transform-minify-booleans": "^6.9.0", + "babel-plugin-transform-property-literals": "^6.9.0", + "babel-plugin-transform-regexp-constructors": "^0.3.0", + "babel-plugin-transform-remove-console": "^6.9.0", + "babel-plugin-transform-remove-debugger": "^6.9.0", + "babel-plugin-transform-remove-undefined": "^0.3.0", + "babel-plugin-transform-simplify-comparison-operators": "^6.9.0", + "babel-plugin-transform-undefined-to-void": "^6.9.0", + "lodash.isplainobject": "^4.0.6" + } + }, + "babel-preset-react": { "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" + } + }, + "babel-preset-stage-0": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", + "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", + "dev": true, + "requires": { + "babel-plugin-transform-do-expressions": "^6.22.0", + "babel-plugin-transform-function-bind": "^6.22.0", + "babel-preset-stage-1": "^6.24.1" + } + }, + "babel-preset-stage-1": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", + "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "dev": true, + "requires": { + "babel-plugin-transform-class-constructor-call": "^6.24.1", + "babel-plugin-transform-export-extensions": "^6.22.0", + "babel-preset-stage-2": "^6.24.1" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" } }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" }, "dependencies": { "babel-types": { @@ -4113,13 +6035,20 @@ } } }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" }, "dependencies": { "babel-types": { @@ -4133,42 +6062,19 @@ "to-fast-properties": "^1.0.3" } }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - } - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - }, - "dependencies": { - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "ms": "2.0.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -4176,1150 +6082,1221 @@ } } }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-export-extensions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", - "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", - "dev": true, - "requires": { - "babel-plugin-syntax-export-extensions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", - "dev": true, - "requires": { - "babel-plugin-syntax-flow": "^6.18.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-function-bind": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", - "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", - "dev": true, + "babel-types": { + "version": "7.0.0-beta.3", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-7.0.0-beta.3.tgz", + "integrity": "sha512-36k8J+byAe181OmCMawGhw+DtKO7AwexPVtsPXoMfAkjtZgoCX3bEuHWfdE5sYxRM8dojvtG/+O08M0Z/YDC6w==", "requires": { - "babel-plugin-syntax-function-bind": "^6.8.0", - "babel-runtime": "^6.22.0" + "esutils": "^2.0.2", + "lodash": "^4.2.0", + "to-fast-properties": "^2.0.0" } }, - "babel-plugin-transform-inline-consecutive-adds": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.3.0.tgz", - "integrity": "sha512-iZsYAIjYLLfLK0yN5WVT7Xf7Y3wQ9Z75j9A8q/0IglQSpUt2ppTdHlwl/GeaXnxdaSmsxBu861klbTBbv2n+RA==", - "dev": true - }, - "babel-plugin-transform-member-expression-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", - "integrity": "sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8=", - "dev": true - }, - "babel-plugin-transform-merge-sibling-variables": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz", - "integrity": "sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4=", - "dev": true + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, - "babel-plugin-transform-minify-booleans": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", - "integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=", - "dev": true + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "babel-plugin-transform-property-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", - "integrity": "sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk=", - "dev": true, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "requires": { - "esutils": "^2.0.2" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "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.0" + } + }, + "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.0" + } + }, + "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.0" + } + }, + "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" + } + } } }, - "babel-plugin-transform-react-display-name": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", - "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" }, - "babel-plugin-transform-react-jsx": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", - "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", - "dev": true, - "requires": { - "babel-helper-builder-react-jsx": "^6.24.1", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" }, - "babel-plugin-transform-react-jsx-self": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", - "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", - "dev": true, - "requires": { - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" }, - "babel-plugin-transform-react-jsx-source": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", - "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", - "dev": true, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "requires": { - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, - "babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.18.tgz", - "integrity": "sha512-azed2nHo8vmOy7EY26KH+om5oOcWRs0r1U8wOmhwta+SBMMnmJ4H6yaBZRCcHBtMeWp9AVhvBTL/lpR1kEx+Xw==", - "dev": true + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, "requires": { - "regenerator-transform": "^0.10.0" + "tweetnacl": "^0.14.3" } }, - "babel-plugin-transform-regexp-constructors": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.3.0.tgz", - "integrity": "sha512-h92YHzyl042rb0naKO8frTHntpRFwRgKkfWD8602kFHoQingjJNtbvZzvxqHncJ6XmKVyYvfrBpDOSkCTDIIxw==", - "dev": true - }, - "babel-plugin-transform-remove-console": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", - "integrity": "sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A=", - "dev": true + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" }, - "babel-plugin-transform-remove-debugger": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", - "integrity": "sha1-QrcnYxyXl44estGZp67IShgznvI=", + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", "dev": true }, - "babel-plugin-transform-remove-undefined": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.3.0.tgz", - "integrity": "sha512-TYGQucc8iP3LJwN3kDZLEz5aa/2KuFrqpT+s8f8NnHsBU1sAgR3y8Opns0xhC+smyDYWscqFCKM1gbkWQOhhnw==", - "dev": true, - "requires": { - "babel-helper-evaluate-path": "^0.3.0" - } - }, - "babel-plugin-transform-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", - "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", - "dev": true, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", "requires": { - "babel-runtime": "^6.22.0" + "callsite": "1.0.0" } }, - "babel-plugin-transform-simplify-comparison-operators": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", - "integrity": "sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk=", - "dev": true - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "bhttp": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/bhttp/-/bhttp-1.2.4.tgz", + "integrity": "sha1-/tDCT3ZbNa/ElAsIqzIUgT44848=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "bluebird": "^2.8.2", + "concat-stream": "^1.4.7", + "debug": "^2.1.1", + "dev-null": "^0.1.1", + "errors": "^0.2.0", + "extend": "^2.0.0", + "form-data2": "^1.0.0", + "form-fix-array": "^1.0.0", + "lodash": "^2.4.1", + "stream-length": "^1.0.2", + "string": "^3.0.0", + "through2-sink": "^1.0.0", + "through2-spy": "^1.2.0", + "tough-cookie": "^2.3.1" }, "dependencies": { - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "ms": "2.0.0" } }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + "extend": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.2.tgz", + "integrity": "sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ==" + }, + "lodash": { + "version": "2.4.2", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, - "babel-plugin-transform-undefined-to-void": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", - "integrity": "sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=", - "dev": true + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, + "binary-extensions": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==" + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "2.11.0", + "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "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": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" }, "dependencies": { - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } + "array-flatten": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", + "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "dev": true } } }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" - } + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, - "babel-preset-flow": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", - "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", - "dev": true, + "bowser": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz", + "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==", + "dev": true + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "requires": { - "babel-plugin-transform-flow-strip-types": "^6.22.0" + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" } }, - "babel-preset-jest": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz", - "integrity": "sha1-jsegOhOPABoaj7HoETZSvxpV2kY=", - "dev": true, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "babel-plugin-jest-hoist": "^23.2.0", - "babel-plugin-syntax-object-rest-spread": "^6.13.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "babel-preset-minify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz", - "integrity": "sha512-+VV2GWEyak3eDOmzT1DDMuqHrw3VbE9nBNkx2LLVs4pH/Me32ND8DRpVDd8IRvk1xX5p75nygyRPtkMh6GIAbQ==", - "dev": true, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "requires": { - "babel-plugin-minify-builtins": "^0.3.0", - "babel-plugin-minify-constant-folding": "^0.3.0", - "babel-plugin-minify-dead-code-elimination": "^0.3.0", - "babel-plugin-minify-flip-comparisons": "^0.3.0", - "babel-plugin-minify-guarded-expressions": "^0.3.0", - "babel-plugin-minify-infinity": "^0.3.0", - "babel-plugin-minify-mangle-names": "^0.3.0", - "babel-plugin-minify-numeric-literals": "^0.3.0", - "babel-plugin-minify-replace": "^0.3.0", - "babel-plugin-minify-simplify": "^0.3.0", - "babel-plugin-minify-type-constructors": "^0.3.0", - "babel-plugin-transform-inline-consecutive-adds": "^0.3.0", - "babel-plugin-transform-member-expression-literals": "^6.9.0", - "babel-plugin-transform-merge-sibling-variables": "^6.9.0", - "babel-plugin-transform-minify-booleans": "^6.9.0", - "babel-plugin-transform-property-literals": "^6.9.0", - "babel-plugin-transform-regexp-constructors": "^0.3.0", - "babel-plugin-transform-remove-console": "^6.9.0", - "babel-plugin-transform-remove-debugger": "^6.9.0", - "babel-plugin-transform-remove-undefined": "^0.3.0", - "babel-plugin-transform-simplify-comparison-operators": "^6.9.0", - "babel-plugin-transform-undefined-to-void": "^6.9.0", - "lodash.isplainobject": "^4.0.6" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "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.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "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.0" + } + } } }, - "babel-preset-react": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", - "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", - "dev": true, + "brcast": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz", + "integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg==", + "dev": true + }, + "broken-link-checker": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/broken-link-checker/-/broken-link-checker-0.7.8.tgz", + "integrity": "sha512-/zH4/nLMNKDeDH5nVuf/R6WYd0Yjnar1NpcdAO2+VlwjGKzJa6y42C03UO+imBSHwe6BefSkVi82fImE2Rb7yg==", "requires": { - "babel-plugin-syntax-jsx": "^6.3.13", - "babel-plugin-transform-react-display-name": "^6.23.0", - "babel-plugin-transform-react-jsx": "^6.24.1", - "babel-plugin-transform-react-jsx-self": "^6.22.0", - "babel-plugin-transform-react-jsx-source": "^6.22.0", - "babel-preset-flow": "^6.23.0" + "bhttp": "^1.2.1", + "calmcard": "~0.1.1", + "chalk": "^1.1.3", + "char-spinner": "^1.0.1", + "condense-whitespace": "^1.0.0", + "default-user-agent": "^1.0.0", + "errno": "~0.1.4", + "extend": "^3.0.0", + "http-equiv-refresh": "^1.0.0", + "humanize-duration": "^3.9.1", + "is-stream": "^1.0.1", + "is-string": "^1.0.4", + "limited-request-queue": "^2.0.0", + "link-types": "^1.1.0", + "maybe-callback": "^2.1.0", + "nopter": "~0.3.0", + "parse5": "^3.0.2", + "robot-directives": "~0.3.0", + "robots-txt-guard": "~0.1.0", + "robots-txt-parse": "~0.0.4", + "urlcache": "~0.7.0", + "urlobj": "0.0.11" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^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=" + } } }, - "babel-preset-stage-0": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", - "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", - "dev": true, + "broken-link-checker-local": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/broken-link-checker-local/-/broken-link-checker-local-0.2.0.tgz", + "integrity": "sha512-zZNOyEEdwQ7Z3xPeB8wUZCURKphV0icsITq0ZlPxPI7M9ELD6gRIpVedzVq6XnPkbKALVkLjxhC3iZ+k3pAshA==", "requires": { - "babel-plugin-transform-do-expressions": "^6.22.0", - "babel-plugin-transform-function-bind": "^6.22.0", - "babel-preset-stage-1": "^6.24.1" + "broken-link-checker": "^0.7.4", + "chalk": "^1.1.3", + "express": "^4.14.0", + "get-port": "^2.1.0", + "yargs": "^6.6.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "get-port": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", + "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^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=" + } } }, - "babel-preset-stage-1": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", - "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", - "dev": true, - "requires": { - "babel-plugin-transform-class-constructor-call": "^6.24.1", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-preset-stage-2": "^6.24.1" - } + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, - "babel-preset-stage-2": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", - "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", - "dev": true, - "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" - } + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true }, - "babel-preset-stage-3": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", - "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", "dev": true, "requires": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "browser-sync": { + "version": "2.24.7", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.24.7.tgz", + "integrity": "sha512-NqXek0cPNEayQm77VGnD+qrwcVBTKMIQ9bdP6IWDRUTU1Bk7tZeq5QR3OG5Rr36Rao1t+Vx1QnfolHvvr5qsTA==", "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "browser-sync-ui": "v1.0.1", + "bs-recipes": "1.3.4", + "chokidar": "1.7.0", + "connect": "3.6.6", + "connect-history-api-fallback": "^1.5.0", + "dev-ip": "^1.0.1", + "easy-extender": "^2.3.4", + "eazy-logger": "3.0.2", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "fs-extra": "3.0.1", + "http-proxy": "1.15.2", + "immutable": "3.8.2", + "localtunnel": "1.9.0", + "micromatch": "2.3.11", + "opn": "5.3.0", + "portscanner": "2.1.1", + "qs": "6.2.3", + "raw-body": "^2.3.2", + "resp-modifier": "6.0.2", + "rx": "4.1.0", + "serve-index": "1.9.1", + "serve-static": "1.13.2", + "server-destroy": "1.0.1", + "socket.io": "2.1.1", + "ua-parser-js": "0.7.17", + "yargs": "6.4.0" }, "dependencies": { - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=" + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" } }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - } - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "http-proxy": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", + "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "eventemitter3": "1.x.x", + "requires-port": "1.x.x" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "ms": "2.0.0" + "number-is-nan": "^1.0.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - } - } - }, - "babel-types": { - "version": "7.0.0-beta.3", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-7.0.0-beta.3.tgz", - "integrity": "sha512-36k8J+byAe181OmCMawGhw+DtKO7AwexPVtsPXoMfAkjtZgoCX3bEuHWfdE5sYxRM8dojvtG/+O08M0Z/YDC6w==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.2.0", - "to-fast-properties": "^2.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, - "balanced-match": { - "version": "1.0.0", - "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.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", "requires": { - "is-descriptor": "^1.0.0" + "graceful-fs": "^4.1.6" } }, - "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==", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "kind-of": "^6.0.0" + "is-buffer": "^1.1.5" } }, - "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==", + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "requires": { - "kind-of": "^6.0.0" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, - "is-descriptor": { + "qs": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", + "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=" + }, + "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "yargs": { + "version": "6.4.0", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", + "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.1.0" } } } }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + "browser-sync-ui": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-1.0.1.tgz", + "integrity": "sha512-RIxmwVVcUFhRd1zxp7m2FfLnXHf59x4Gtj8HFwTA//3VgYI3AKkaQAuDL8KDJnE59XqCshxZa13JYuIWtZlKQg==", + "requires": { + "async-each-series": "0.1.1", + "connect-history-api-fallback": "^1.1.0", + "immutable": "^3.7.6", + "server-destroy": "1.0.1", + "socket.io-client": "2.0.4", + "stream-throttle": "^0.1.3" + } }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + "browserify-aes": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + "browserify-rsa": { + "version": "4.0.1", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "optional": true, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "requires": { - "tweetnacl": "^0.14.3" + "pako": "~1.0.5" } }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + "browserslist": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.1.2.tgz", + "integrity": "sha512-docXmVcYth9AiW5183dEe2IxnbmpXF4jiM6efGBVRAli/iDSS894Svvjenrv5NPqAJ4dEJULmT4MSvmLG9qoYg==", + "requires": { + "caniuse-lite": "^1.0.30000888", + "electron-to-chromium": "^1.3.73", + "node-releases": "^1.0.0-alpha.12" + } }, - "before-after-hook": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", - "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", - "dev": true + "bs-recipes": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", + "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=" }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, "requires": { - "callsite": "1.0.0" + "node-int64": "^0.4.0" } }, - "bhttp": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/bhttp/-/bhttp-1.2.4.tgz", - "integrity": "sha1-/tDCT3ZbNa/ElAsIqzIUgT44848=", + "btoa-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", + "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=", + "dev": true + }, + "buffer": { + "version": "4.9.1", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "requires": { - "bluebird": "^2.8.2", - "concat-stream": "^1.4.7", - "debug": "^2.1.1", - "dev-null": "^0.1.1", - "errors": "^0.2.0", - "extend": "^2.0.0", - "form-data2": "^1.0.0", - "form-fix-array": "^1.0.0", - "lodash": "^2.4.1", - "stream-length": "^1.0.2", - "string": "^3.0.0", - "through2-sink": "^1.0.0", - "through2-spy": "^1.2.0", - "tough-cookie": "^2.3.1" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^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" - } - }, - "extend": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.2.tgz", - "integrity": "sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ==" - }, - "lodash": { - "version": "2.4.2", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" } } }, - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", + "dev": true }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==" + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, - "bluebird": { - "version": "2.11.0", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", "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": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "dicer": "0.2.5", + "readable-stream": "1.1.x" } }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", + "dev": true + }, + "byte-size": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-4.0.3.tgz", + "integrity": "sha512-JGC3EV2bCzJH/ENSh3afyJrH4vwxbHTuO5ljLoI5+2iJOcEpMgP8T782jH9b5qGxf2mSUIp1lfGnfKNrRHpvVg==", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cacache": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", "dev": true, "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^2.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^5.2.4", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" }, "dependencies": { - "array-flatten": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", - "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "bluebird": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", + "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true } } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true + "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" + } }, - "bowser": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz", - "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==", + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", "dev": true }, - "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" + "callsites": "^0.2.0" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + }, + "calmcard": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/calmcard/-/calmcard-0.1.1.tgz", + "integrity": "sha1-NawrZkkrDtOa0GqJOg/25hEk5Ek=" + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "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.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "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.0" - } - } + "no-case": "^2.2.0", + "upper-case": "^1.1.1" } }, - "brcast": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz", - "integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg==", - "dev": true + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" }, - "broken-link-checker": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/broken-link-checker/-/broken-link-checker-0.7.8.tgz", - "integrity": "sha512-/zH4/nLMNKDeDH5nVuf/R6WYd0Yjnar1NpcdAO2+VlwjGKzJa6y42C03UO+imBSHwe6BefSkVi82fImE2Rb7yg==", + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "requires": { - "bhttp": "^1.2.1", - "calmcard": "~0.1.1", - "chalk": "^1.1.3", - "char-spinner": "^1.0.1", - "condense-whitespace": "^1.0.0", - "default-user-agent": "^1.0.0", - "errno": "~0.1.4", - "extend": "^3.0.0", - "http-equiv-refresh": "^1.0.0", - "humanize-duration": "^3.9.1", - "is-stream": "^1.0.1", - "is-string": "^1.0.4", - "limited-request-queue": "^2.0.0", - "link-types": "^1.1.0", - "maybe-callback": "^2.1.0", - "nopter": "~0.3.0", - "parse5": "^3.0.2", - "robot-directives": "~0.3.0", - "robots-txt-guard": "~0.1.0", - "robots-txt-parse": "~0.0.4", - "urlcache": "~0.7.0", - "urlobj": "0.0.11" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" }, "dependencies": { - "ansi-regex": { + "camelcase": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^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=" + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" } } }, - "broken-link-checker-local": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/broken-link-checker-local/-/broken-link-checker-local-0.2.0.tgz", - "integrity": "sha512-zZNOyEEdwQ7Z3xPeB8wUZCURKphV0icsITq0ZlPxPI7M9ELD6gRIpVedzVq6XnPkbKALVkLjxhC3iZ+k3pAshA==", + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "requires": { - "broken-link-checker": "^0.7.4", - "chalk": "^1.1.3", - "express": "^4.14.0", - "get-port": "^2.1.0", - "yargs": "^6.6.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "get-port": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", - "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^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=" - } + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-db": { + "version": "1.0.30000889", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000889.tgz", + "integrity": "sha512-Rf9Sbm2KS7s6Rk8iNeI5zJdquqctXBXAfy/bb1tCCYRds5RAaHNdyt2D4z8TSRToDkYsAwiSBV/bFHR+4IgTiw==" + }, + "caniuse-lite": { + "version": "1.0.30000889", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000889.tgz", + "integrity": "sha512-MFxcQ6x/LEEoaIhO7Zdb7Eg8YyNONN+WBnS5ERJ0li2yRw51+i4xXUNxnLaveTb/4ZoJqsWKEmlomhG2pYzlQA==" + }, + "capture-exit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", + "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", + "dev": true, + "requires": { + "rsvp": "^3.3.3" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true }, - "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "case-sensitive-paths-webpack-plugin": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.2.tgz", + "integrity": "sha512-oEZgAFfEvKtjSRCu6VgYkuGxwrWXMnQzyBmlLPP7r6PWQVtHxP5Z5N6XsuJvtoVax78am/r7lr46bwo3IVEBOg==", "dev": true }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" } }, - "browser-sync": { - "version": "2.24.7", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.24.7.tgz", - "integrity": "sha512-NqXek0cPNEayQm77VGnD+qrwcVBTKMIQ9bdP6IWDRUTU1Bk7tZeq5QR3OG5Rr36Rao1t+Vx1QnfolHvvr5qsTA==", + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "browser-sync-ui": "v1.0.1", - "bs-recipes": "1.3.4", - "chokidar": "1.7.0", - "connect": "3.6.6", - "connect-history-api-fallback": "^1.5.0", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "3.0.2", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "1.15.2", - "immutable": "3.8.2", - "localtunnel": "1.9.0", - "micromatch": "2.3.11", - "opn": "5.3.0", - "portscanner": "2.1.1", - "qs": "6.2.3", - "raw-body": "^2.3.2", - "resp-modifier": "6.0.2", - "rx": "4.1.0", - "serve-index": "1.9.1", - "serve-static": "1.13.2", - "server-destroy": "1.0.1", - "socket.io": "2.1.1", - "ua-parser-js": "0.7.17", - "yargs": "6.4.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "char-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz", + "integrity": "sha1-5upnvSR+EHESmDt6sEee02KAAIE=" + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cheerio": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", + "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", + "dev": true, + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" } }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "domelementtype": "1" } }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=" - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "dom-serializer": "0", + "domelementtype": "1" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "dev": true, "requires": { - "is-extglob": "^1.0.0" + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" } }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "http-proxy": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", - "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "requires": { - "eventemitter3": "1.x.x", - "requires-port": "1.x.x" + "safe-buffer": "~5.1.0" } - }, + } + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "dependencies": { "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -5327,56 +7304,64 @@ "requires": { "is-extglob": "^1.0.0" } + } + } + }, + "chownr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "requires": { + "chalk": "^1.1.3" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "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" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=" + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "strip-ansi": { @@ -5387,472 +7372,445 @@ "ansi-regex": "^2.0.0" } }, - "yargs": { - "version": "6.4.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", - "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.1.0" - } + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } }, - "browser-sync-ui": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-1.0.1.tgz", - "integrity": "sha512-RIxmwVVcUFhRd1zxp7m2FfLnXHf59x4Gtj8HFwTA//3VgYI3AKkaQAuDL8KDJnE59XqCshxZa13JYuIWtZlKQg==", - "requires": { - "async-each-series": "0.1.1", - "connect-history-api-fallback": "^1.1.0", - "immutable": "^3.7.6", - "server-destroy": "1.0.1", - "socket.io-client": "2.0.4", - "stream-throttle": "^0.1.3" - } - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "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": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "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.0" + } } } }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==", + "dev": true }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "dev": true, "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "source-map": "~0.6.0" } }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, "requires": { - "pako": "~1.0.5" + "restore-cursor": "^2.0.0" } }, - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", "requires": { - "caniuse-db": "^1.0.30000639", - "electron-to-chromium": "^1.2.7" + "colors": "1.0.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + } } }, - "bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=" + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true }, - "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "clipboard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.1.tgz", + "integrity": "sha512-7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ==", "dev": true, + "optional": true, "requires": { - "node-int64": "^0.4.0" + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" } }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=", - "dev": true - }, - "buffer": { - "version": "4.9.1", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" }, "dependencies": { - "isarray": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } } } }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + "cmd-shim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", + "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true + "coa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.1.tgz", + "integrity": "sha512-5wfTTO8E2/ja4jFSxePXlG5nRu5bBtL/r1HCIpJW/lzT6yDtKl0u0Z4o/Vpz32IpKmBn7HerheEZQgA9N2DarQ==", + "requires": { + "q": "^1.1.2" + } }, - "byline": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", - "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", - "dev": true + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, - "byte-size": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-4.0.3.tgz", - "integrity": "sha512-JGC3EV2bCzJH/ENSh3afyJrH4vwxbHTuO5ljLoI5+2iJOcEpMgP8T782jH9b5qGxf2mSUIp1lfGnfKNrRHpvVg==", - "dev": true + "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.0" + } }, - "bytes": { + "color": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "cacache": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", - "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", - "dev": true, + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^2.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^5.2.4", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" - }, - "dependencies": { - "bluebird": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - } + "color-convert": "^1.9.1", + "color-string": "^1.5.2" } }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "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" + "color-name": "1.1.3" } }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", "requires": { - "callsites": "^0.2.0" + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "requires": { + "color": "^0.11.0", + "css-color-names": "0.0.4", + "has": "^1.0.1" + }, + "dependencies": { + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "requires": { + "clone": "^1.0.2", + "color-convert": "^1.3.0", + "color-string": "^0.3.0" + } + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "requires": { + "color-name": "^1.0.0" + } + } + } }, - "calmcard": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/calmcard/-/calmcard-0.1.1.tgz", - "integrity": "sha1-NawrZkkrDtOa0GqJOg/25hEk5Ek=" + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "combined-stream2": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/combined-stream2/-/combined-stream2-1.1.2.tgz", + "integrity": "sha1-9uFLegFWZvjHsKH6xQYkAWSsNXA=", "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "bluebird": "^2.8.1", + "debug": "^2.1.1", + "stream-length": "^1.0.1" }, "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, - "caniuse-api": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", - "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", - "requires": { - "browserslist": "^1.3.6", - "caniuse-db": "^1.0.30000529", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } + "command-exists": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.7.tgz", + "integrity": "sha512-doWDvhXCcW5LK0cIUWrOQ8oMFXJv3lEQCkJpGVjM8v9SV0uhqYXB943538tEA2CiaWqSyuYUGAm5ezDwEx9xlw==" }, - "caniuse-db": { - "version": "1.0.30000889", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000889.tgz", - "integrity": "sha512-Rf9Sbm2KS7s6Rk8iNeI5zJdquqctXBXAfy/bb1tCCYRds5RAaHNdyt2D4z8TSRToDkYsAwiSBV/bFHR+4IgTiw==" + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" }, - "caniuse-lite": { - "version": "1.0.30000889", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000889.tgz", - "integrity": "sha512-MFxcQ6x/LEEoaIhO7Zdb7Eg8YyNONN+WBnS5ERJ0li2yRw51+i4xXUNxnLaveTb/4ZoJqsWKEmlomhG2pYzlQA==", - "dev": true + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" }, - "capture-exit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", - "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "compare-func": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", + "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", "dev": true, "requires": { - "rsvp": "^3.3.3" + "array-ify": "^1.0.0", + "dot-prop": "^3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + } } }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true - }, - "case-sensitive-paths-webpack-plugin": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.2.tgz", - "integrity": "sha512-oEZgAFfEvKtjSRCu6VgYkuGxwrWXMnQzyBmlLPP7r6PWQVtHxP5Z5N6XsuJvtoVax78am/r7lr46bwo3IVEBOg==", - "dev": true + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "compressible": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", + "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", "dev": true, "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" + "mime-db": ">= 1.36.0 < 2" } }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "compression": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", + "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.14", + "debug": "2.6.9", + "on-headers": "~1.0.1", + "safe-buffer": "5.1.2", + "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==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, - "char-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz", - "integrity": "sha1-5upnvSR+EHESmDt6sEee02KAAIE=" - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "cheerio": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", - "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", - "dev": true, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "requires": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.0", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash": "^4.15.0", - "parse5": "^3.0.1" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" }, "dependencies": { - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "htmlparser2": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", - "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", - "dev": true, - "requires": { - "domelementtype": "^1.3.0", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5867,529 +7825,778 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } } } }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "concurrently": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-4.0.1.tgz", + "integrity": "sha512-D8UI+mlI/bfvrA57SeKOht6sEpb01dKk+8Yee4fbnkk1Ue8r3S+JXoEdFZIpzQlXJGtnxo47Wvvg/kG4ba3U6Q==", + "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "chalk": "^2.4.1", + "date-fns": "^1.23.0", + "lodash": "^4.17.10", + "read-pkg": "^4.0.1", + "rxjs": "6.2.2", + "spawn-command": "^0.0.2-1", + "supports-color": "^4.5.0", + "tree-kill": "^1.1.0", + "yargs": "^12.0.1" }, "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, "requires": { - "is-extglob": "^1.0.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } - } - } - }, - "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true - }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "clap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", - "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", - "requires": { - "chalk": "^1.1.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "decamelize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", + "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "dev": true, + "requires": { + "xregexp": "4.0.0" + } }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", + "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "os-locale": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz", + "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==", + "dev": true, + "requires": { + "execa": "^0.10.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", + "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "has-flag": "^2.0.0" } }, - "supports-color": { + "which-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "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.0", - "static-extend": "^0.1.1" - }, - "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=", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", + "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", + "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "cliui": "^4.0.0", + "decamelize": "^2.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^10.1.0" + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" } } } }, - "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==", - "dev": true - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "cli-boxes": { + "condense-whitespace": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + "resolved": "https://registry.npmjs.org/condense-whitespace/-/condense-whitespace-1.0.0.tgz", + "integrity": "sha1-g3bZjvAo5sss0kaOKM5CxcZasak=" }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", - "requires": { - "colors": "1.0.3" + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "clipboard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.1.tgz", - "integrity": "sha512-7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ==", + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", "dev": true, - "optional": true, "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "number-is-nan": "^1.0.0" + "ms": "2.0.0" } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "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" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" } } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" - }, - "cmd-shim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", - "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=" }, - "coa": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", - "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "requires": { - "q": "^1.1.2" + "date-now": "^0.1.4" } }, - "code-point-at": { + "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" }, - "collection-visit": { + "contains-path": { "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.0" - } - }, - "color": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", - "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-1.0.0.tgz", + "integrity": "sha1-NFizMhhWA+ju0Y9RjUoQiIo6vJE=", "requires": { - "clone": "^1.0.2", - "color-convert": "^1.3.0", - "color-string": "^0.3.0" + "normalize-path": "^2.1.1", + "path-starts-with": "^1.0.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, - "color-string": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", - "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "conventional-changelog-angular": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.1.tgz", + "integrity": "sha512-q4ylJ68fWZDdrFC9z4zKcf97HW6hp7Mo2YlqD4owfXhecFKy/PJCU/1oVFF4TqochchChqmZ0Vb0e0g8/MKNlA==", + "dev": true, "requires": { - "color-name": "^1.0.0" + "compare-func": "^1.3.1", + "q": "^1.5.1" } }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, - "colormin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", - "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "conventional-changelog-core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.1.0.tgz", + "integrity": "sha512-bcZkcFXkqVgG2W8m/1wjlp2wn/BKDcrPgw3/mvSEQtzs8Pax8JbAPFpEQReHY92+EKNNXC67wLA8y2xcNx0rDA==", + "dev": true, "requires": { - "color": "^0.11.0", - "css-color-names": "0.0.4", - "has": "^1.0.1" + "conventional-changelog-writer": "^4.0.0", + "conventional-commits-parser": "^3.0.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^1.0.0", + "git-raw-commits": "^2.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^2.0.0", + "lodash": "^4.2.1", + "normalize-package-data": "^2.3.5", + "q": "^1.5.1", + "read-pkg": "^1.1.0", + "read-pkg-up": "^1.0.1", + "through2": "^2.0.0" + }, + "dependencies": { + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + } } }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + "conventional-changelog-preset-loader": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.1.tgz", + "integrity": "sha512-HiSfhXNzAzG9klIqJaA97MMiNBR4js+53g4Px0k7tgKeCNVXmrDrm+CY+nIqcmG5NVngEPf8rAr7iji1TWW7zg==", + "dev": true }, - "columnify": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", - "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "conventional-changelog-writer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.0.tgz", + "integrity": "sha512-hMZPe0AQ6Bi05epeK/7hz80xxk59nPA5z/b63TOHq2wigM0/akreOc8N4Jam5b9nFgKWX1e9PdPv2ewgW6bcfg==", "dev": true, "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" + "compare-func": "^1.3.1", + "conventional-commits-filter": "^2.0.0", + "dateformat": "^3.0.0", + "handlebars": "^4.0.2", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "semver": "^5.5.0", + "split": "^1.0.0", + "through2": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" } - } - } - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "combined-stream2": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/combined-stream2/-/combined-stream2-1.1.2.tgz", - "integrity": "sha1-9uFLegFWZvjHsKH6xQYkAWSsNXA=", - "requires": { - "bluebird": "^2.8.1", - "debug": "^2.1.1", - "stream-length": "^1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, "requires": { - "ms": "2.0.0" + "through": "2" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "command-exists": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.7.tgz", - "integrity": "sha512-doWDvhXCcW5LK0cIUWrOQ8oMFXJv3lEQCkJpGVjM8v9SV0uhqYXB943538tEA2CiaWqSyuYUGAm5ezDwEx9xlw==" - }, - "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" - }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "compare-func": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", - "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^3.0.0" - }, - "dependencies": { - "dot-prop": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", - "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "is-obj": "^1.0.0" + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" } + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true } } }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" - }, - "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "conventional-commits-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.0.tgz", + "integrity": "sha512-Cfl0j1/NquB/TMVx7Wrmyq7uRM+/rPQbtVVGwzfkhZ6/yH6fcMmP0Q/9044TBZPTNdGzm46vXFXL14wbET0/Mg==", "dev": true, "requires": { - "mime-db": ">= 1.36.0 < 2" + "is-subset": "^0.1.1", + "modify-values": "^1.0.0" } }, - "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "conventional-commits-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.0.tgz", + "integrity": "sha512-GWh71U26BLWgMykCp+VghZ4s64wVbtseECcKQ/PvcPZR2cUnz+FUc2J9KjxNl7/ZbCxST8R03c9fc+Vi0umS9Q==", "dev": true, "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.0", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0", + "trim-off-newlines": "^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==", + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { - "ms": "2.0.0" + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6400,183 +8607,147 @@ "util-deprecate": "~1.0.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concurrently": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-4.0.1.tgz", - "integrity": "sha512-D8UI+mlI/bfvrA57SeKOht6sEpb01dKk+8Yee4fbnkk1Ue8r3S+JXoEdFZIpzQlXJGtnxo47Wvvg/kG4ba3U6Q==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "date-fns": "^1.23.0", - "lodash": "^4.17.10", - "read-pkg": "^4.0.1", - "rxjs": "6.2.2", - "spawn-command": "^0.0.2-1", - "supports-color": "^4.5.0", - "tree-kill": "^1.1.0", - "yargs": "^12.0.1" - }, - "dependencies": { - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "decamelize": { + "redent": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", "dev": true, "requires": { - "xregexp": "4.0.0" + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" } }, - "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "safe-buffer": "~5.1.0" } }, - "find-up": { + "strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "invert-kv": { + "strip-indent": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", "dev": true }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "invert-kv": "^2.0.0" + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + } + } + }, + "conventional-recommended-bump": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-4.0.1.tgz", + "integrity": "sha512-9waJvW01TUs4HQJ3khwGSSlTlKsY+5u7OrxHL+oWEoGNvaNO/0qL6qqnhS3J0Fq9fNKA9bmlf5cOXjCQoW+I4Q==", + "dev": true, + "requires": { + "concat-stream": "^1.6.0", + "conventional-changelog-preset-loader": "^2.0.1", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.0", + "git-raw-commits": "^2.0.0", + "git-semver-tags": "^2.0.0", + "meow": "^4.0.0", + "q": "^1.5.1" + }, + "dependencies": { + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" } }, - "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" + "locate-path": "^2.0.0" } }, - "os-locale": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz", - "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==", + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { - "execa": "^0.10.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" } }, - "p-limit": { + "map-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", - "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" } }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "pify": "^3.0.0" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -6584,1131 +8755,760 @@ "dev": true }, "read-pkg": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", - "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0" + "path-type": "^3.0.0" } }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { - "has-flag": "^2.0.0" + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" } }, - "which-module": { + "redent": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "yargs": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", - "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^2.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^10.1.0" + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" } }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true } } }, - "condense-whitespace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/condense-whitespace/-/condense-whitespace-1.0.0.tgz", - "integrity": "sha1-g3bZjvAo5sss0kaOKM5CxcZasak=" + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "requires": { + "safe-buffer": "~5.1.1" + } }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", "dev": true, "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" } }, - "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", - "dev": true, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "object-assign": "^4", + "vary": "^1" } }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "cosmiconfig": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.6.tgz", + "integrity": "sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==", "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0" + } + }, + "coveralls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", + "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", + "dev": true, + "requires": { + "growl": "~> 1.10.0", + "js-yaml": "^3.11.0", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.85.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" - } - }, - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true } } }, - "connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=" - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "requires": { - "date-now": "^0.1.4" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + "create-hash": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "create-hmac": { + "version": "1.1.7", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } }, - "conventional-changelog-angular": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", - "integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==", + "create-react-class": { + "version": "15.6.3", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", + "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", "dev": true, "requires": { - "compare-func": "^1.3.1", - "q": "^1.5.1" + "fbjs": "^0.8.9", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, - "conventional-changelog-core": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.11.tgz", - "integrity": "sha512-HvTE6RlqeEZ/NFPtQeFLsIDOLrGP3bXYr7lFLMhCVsbduF1MXIe8OODkwMFyo1i9ku9NWBwVnVn0jDmIFXjDRg==", + "cross-fetch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", + "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", "dev": true, "requires": { - "conventional-changelog-writer": "^3.0.9", - "conventional-commits-parser": "^2.1.7", - "dateformat": "^3.0.0", - "get-pkg-repo": "^1.0.0", - "git-raw-commits": "^1.3.6", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^1.3.6", - "lodash": "^4.2.1", - "normalize-package-data": "^2.3.5", - "q": "^1.5.1", - "read-pkg": "^1.1.0", - "read-pkg-up": "^1.0.1", - "through2": "^2.0.0" + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" }, "dependencies": { - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "node-fetch": { + "version": "2.1.2", + "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } } } }, - "conventional-changelog-preset-loader": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.8.tgz", - "integrity": "sha512-MkksM4G4YdrMlT2MbTsV2F6LXu/hZR0Tc/yenRrDIKRwBl/SP7ER4ZDlglqJsCzLJi4UonBc52Bkm5hzrOVCcw==", + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, - "conventional-changelog-writer": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-3.0.9.tgz", - "integrity": "sha512-n9KbsxlJxRQsUnK6wIBRnARacvNnN4C/nxnxCkH+B/R1JS2Fa+DiP1dU4I59mEDEjgnFaN2+9wr1P1s7GYB5/Q==", + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-in-js-utils": { + "version": "2.0.1", + "resolved": "http://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", "dev": true, "requires": { - "compare-func": "^1.3.1", - "conventional-commits-filter": "^1.1.6", - "dateformat": "^3.0.0", - "handlebars": "^4.0.2", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.2.1", - "meow": "^4.0.0", - "semver": "^5.5.0", - "split": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "hyphenate-style-name": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "css-loader": { + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", + "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "cssnano": "^3.10.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash.camelcase": "^4.3.0", + "object-assign": "^4.1.1", + "postcss": "^5.0.6", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "browserslist": "^1.3.6", + "caniuse-db": "^1.0.30000529", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" } }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", "dev": true, "requires": { - "through": "2" + "q": "^1.1.2" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "cssnano": { + "version": "3.10.0", + "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "autoprefixer": "^6.3.1", + "decamelize": "^1.1.2", + "defined": "^1.0.0", + "has": "^1.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.14", + "postcss-calc": "^5.2.0", + "postcss-colormin": "^2.1.8", + "postcss-convert-values": "^2.3.4", + "postcss-discard-comments": "^2.0.4", + "postcss-discard-duplicates": "^2.0.1", + "postcss-discard-empty": "^2.0.1", + "postcss-discard-overridden": "^0.1.1", + "postcss-discard-unused": "^2.2.1", + "postcss-filter-plugins": "^2.0.0", + "postcss-merge-idents": "^2.1.5", + "postcss-merge-longhand": "^2.0.1", + "postcss-merge-rules": "^2.0.3", + "postcss-minify-font-values": "^1.0.2", + "postcss-minify-gradients": "^1.0.1", + "postcss-minify-params": "^1.0.4", + "postcss-minify-selectors": "^2.0.4", + "postcss-normalize-charset": "^1.1.0", + "postcss-normalize-url": "^3.0.7", + "postcss-ordered-values": "^2.1.0", + "postcss-reduce-idents": "^2.2.2", + "postcss-reduce-initial": "^1.0.0", + "postcss-reduce-transforms": "^1.0.3", + "postcss-svgo": "^2.1.1", + "postcss-unique-selectors": "^2.0.2", + "postcss-value-parser": "^3.2.3", + "postcss-zindex": "^2.0.1" + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "requires": { + "clap": "^1.0.9", + "source-map": "^0.5.3" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "html-comment-regex": "^1.1.0" } }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - } - } - }, - "conventional-commits-filter": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.6.tgz", - "integrity": "sha512-KcDgtCRKJCQhyk6VLT7zR+ZOyCnerfemE/CsR3iQpzRRFbLEs0Y6rwk3mpDvtOh04X223z+1xyJ582Stfct/0Q==", - "dev": true, - "requires": { - "is-subset": "^0.1.1", - "modify-values": "^1.0.0" - } - }, - "conventional-commits-parser": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz", - "integrity": "sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==", - "dev": true, - "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.0", - "lodash": "^4.2.1", - "meow": "^4.0.0", - "split2": "^2.0.0", - "through2": "^2.0.0", - "trim-off-newlines": "^1.0.0" - }, - "dependencies": { - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "argparse": "^1.0.7", + "esprima": "^2.6.0" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", "dev": true, "requires": { - "locate-path": "^2.0.0" + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" } }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" } }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "postcss-calc": { + "version": "5.3.1", + "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" + "postcss": "^5.0.2", + "postcss-message-helpers": "^2.0.0", + "reduce-css-calc": "^1.2.6" } }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "colormin": "^1.0.5", + "postcss": "^5.0.13", + "postcss-value-parser": "^3.2.3" } }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", "dev": true, "requires": { - "pify": "^3.0.0" + "postcss": "^5.0.11", + "postcss-value-parser": "^3.1.2" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "postcss": "^5.0.14" } }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "postcss": "^5.0.4" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "postcss": "^5.0.14" } }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "postcss": "^5.0.16" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "postcss": "^5.0.4" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "browserslist": "^1.5.2", + "caniuse-api": "^1.5.2", + "postcss": "^5.0.4", + "postcss-selector-parser": "^2.2.2", + "vendors": "^1.0.0" } }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - } - } - }, - "conventional-recommended-bump": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-2.0.9.tgz", - "integrity": "sha512-YE6/o+648qkX3fTNvfBsvPW3tSnbZ6ec3gF0aBahCPgyoVHU2Mw0nUAZ1h1UN65GazpORngrgRC8QCltNYHPpQ==", - "dev": true, - "requires": { - "concat-stream": "^1.6.0", - "conventional-changelog-preset-loader": "^1.1.8", - "conventional-commits-filter": "^1.1.6", - "conventional-commits-parser": "^2.1.7", - "git-raw-commits": "^1.3.6", - "git-semver-tags": "^1.3.6", - "meow": "^4.0.0", - "q": "^1.5.1" - }, - "dependencies": { - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "object-assign": "^4.0.1", + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { - "locate-path": "^2.0.0" + "postcss": "^5.0.12", + "postcss-value-parser": "^3.3.0" } }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.2", + "postcss-value-parser": "^3.0.2", + "uniqs": "^2.0.0" } }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" + "alphanum-sort": "^1.0.2", + "has": "^1.0.1", + "postcss": "^5.0.14", + "postcss-selector-parser": "^2.0.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "postcss": "^5.0.5" } }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", "dev": true, "requires": { - "pify": "^3.0.0" + "is-absolute-url": "^2.0.0", + "normalize-url": "^1.4.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.1" } }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "postcss": "^5.0.4" } }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "has": "^1.0.1", + "postcss": "^5.0.8", + "postcss-value-parser": "^3.0.1" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "postcss-svgo": { + "version": "2.1.6", + "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, + "requires": { + "is-svg": "^2.0.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3", + "svgo": "^0.7.0" + } }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + } }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - } - } - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", - "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", - "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.4.3", - "minimist": "^1.2.0", - "object-assign": "^4.1.0", - "os-homedir": "^1.0.1", - "parse-json": "^2.2.0", - "require-from-string": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, + "requires": { + "balanced-match": "^0.4.2", + "math-expression-evaluator": "^1.2.14", + "reduce-function-call": "^1.0.1" + } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } - } - }, - "coveralls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", - "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", - "dev": true, - "requires": { - "growl": "~> 1.10.0", - "js-yaml": "^3.11.0", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.85.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "ansi-regex": "^2.0.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "create-react-class": { - "version": "15.6.3", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", - "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", - "dev": true, - "requires": { - "fbjs": "^0.8.9", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "cross-fetch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", - "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", - "dev": true, - "requires": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - }, - "dependencies": { - "node-fetch": { - "version": "2.1.2", - "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", - "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", - "dev": true + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } }, - "whatwg-fetch": { - "version": "2.0.4", - "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", - "dev": true - } - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" - }, - "css-in-js-utils": { - "version": "2.0.1", - "resolved": "http://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", - "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", - "dev": true, - "requires": { - "hyphenate-style-name": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "css-loader": { - "version": "0.28.11", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", - "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "css-selector-tokenizer": "^0.7.0", - "cssnano": "^3.10.0", - "icss-utils": "^2.1.0", - "loader-utils": "^1.0.2", - "lodash.camelcase": "^4.3.0", - "object-assign": "^4.1.1", - "postcss": "^5.0.6", - "postcss-modules-extract-imports": "^1.2.0", - "postcss-modules-local-by-default": "^1.2.0", - "postcss-modules-scope": "^1.1.0", - "postcss-modules-values": "^1.3.0", - "postcss-value-parser": "^3.3.0", - "source-list-map": "^2.0.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true, + "requires": { + "coa": "~1.0.1", + "colors": "~1.1.2", + "csso": "~2.3.1", + "js-yaml": "~3.7.0", + "mkdirp": "~0.5.1", + "sax": "~1.2.1", + "whet.extend": "~0.9.9" + } } } }, "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.0.tgz", + "integrity": "sha512-MGhoq1S9EyPgZIGnts8Yz5WwUOyHmPMdlqeifsYs/xFX7AAm3hY0RJe1dqVlXtYPI66Nsk39R/sa5/ree6L2qg==", "requires": { - "boolbase": "~1.0.0", + "boolbase": "^1.0.0", "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "domutils": "^1.7.0", + "nth-check": "^1.0.1" } }, + "css-select-base-adapter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.0.tgz", + "integrity": "sha1-AQKz0UYw34bD65+p9UVicBBs+ZA=" + }, "css-selector-tokenizer": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", @@ -7733,11 +9533,36 @@ } } }, + "css-tree": { + "version": "1.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", + "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" + }, + "css-url-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", + "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=" + }, "css-what": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", - "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", - "dev": true + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" }, "cssauron": { "version": "1.4.0", @@ -7754,58 +9579,98 @@ "dev": true }, "cssnano": { - "version": "3.10.0", - "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", - "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.4.tgz", + "integrity": "sha512-wP0wbOM9oqsek14CiNRYrK9N3w3jgadtGZKHXysgC/OMVpy0KZgWVPdNqODSZbz7txO9Gekr9taOfcCgL0pOOw==", "requires": { - "autoprefixer": "^6.3.1", - "decamelize": "^1.1.2", - "defined": "^1.0.0", - "has": "^1.0.1", - "object-assign": "^4.0.1", - "postcss": "^5.0.14", - "postcss-calc": "^5.2.0", - "postcss-colormin": "^2.1.8", - "postcss-convert-values": "^2.3.4", - "postcss-discard-comments": "^2.0.4", - "postcss-discard-duplicates": "^2.0.1", - "postcss-discard-empty": "^2.0.1", - "postcss-discard-overridden": "^0.1.1", - "postcss-discard-unused": "^2.2.1", - "postcss-filter-plugins": "^2.0.0", - "postcss-merge-idents": "^2.1.5", - "postcss-merge-longhand": "^2.0.1", - "postcss-merge-rules": "^2.0.3", - "postcss-minify-font-values": "^1.0.2", - "postcss-minify-gradients": "^1.0.1", - "postcss-minify-params": "^1.0.4", - "postcss-minify-selectors": "^2.0.4", - "postcss-normalize-charset": "^1.1.0", - "postcss-normalize-url": "^3.0.7", - "postcss-ordered-values": "^2.1.0", - "postcss-reduce-idents": "^2.2.2", - "postcss-reduce-initial": "^1.0.0", - "postcss-reduce-transforms": "^1.0.3", - "postcss-svgo": "^2.1.1", - "postcss-unique-selectors": "^2.0.2", - "postcss-value-parser": "^3.2.3", - "postcss-zindex": "^2.0.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.2", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.2.tgz", + "integrity": "sha512-zO9PeP84l1E4kbrdyF7NSLtA/JrJY1paX5FHy5+w/ziIXO2kDqDMfJ/mosXkaHHSa3RPiIY3eB6aEgwx3IiGqA==", + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^6.0.2", + "postcss-colormin": "^4.0.2", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.1", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.6", + "postcss-merge-rules": "^4.0.2", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.1", + "postcss-minify-params": "^4.0.1", + "postcss-minify-selectors": "^4.0.1", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.1", + "postcss-normalize-positions": "^4.0.1", + "postcss-normalize-repeat-style": "^4.0.1", + "postcss-normalize-string": "^4.0.1", + "postcss-normalize-timing-functions": "^4.0.1", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.1", + "postcss-ordered-values": "^4.1.1", + "postcss-reduce-initial": "^4.0.2", + "postcss-reduce-transforms": "^4.0.1", + "postcss-svgo": "^4.0.1", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "requires": { + "postcss": "^7.0.0" } }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" + }, "csso": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", - "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", "requires": { - "clap": "^1.0.9", - "source-map": "^0.5.3" + "css-tree": "1.0.0-alpha.29" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "cssom": { @@ -7829,6 +9694,11 @@ "integrity": "sha512-Nt5VDyOTIIV4/nRFswoCKps1R5CD1hkiyjBE9/thNaNZILLEviVw9yWQw15+O+CpNjQKB/uvdcxFFOrSflY3Yw==", "dev": true }, + "csv-parse": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-3.1.2.tgz", + "integrity": "sha512-NtcS4h3rLcwawpJJDRolYeuQW/2RvutpHpzbokbk5xMCNEDSyvAK3SmuCtd6tKOftKiMa2wn4viOU32A/5VDTQ==" + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -7988,6 +9858,11 @@ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=" + }, "debug": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", @@ -7996,6 +9871,22 @@ "ms": "^2.1.1" } }, + "debug-error-middleware": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/debug-error-middleware/-/debug-error-middleware-1.3.0.tgz", + "integrity": "sha1-w/1bhO+2kUqm2VixUX+FOIg1nRY=", + "requires": { + "handlebars": "^4.0.10", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "debuglog": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", @@ -8040,8 +9931,7 @@ "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" }, "deep-extend": { "version": "0.6.0", @@ -8084,17 +9974,8 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" - }, - "dependencies": { - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - } } }, "define-property": { @@ -8152,14 +10033,6 @@ "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "rimraf": "^2.2.8" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "delayed-stream": { @@ -8189,6 +10062,11 @@ "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" }, + "deprecated-decorator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", + "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" + }, "des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", @@ -8275,11 +10153,19 @@ "wrappy": "1" } }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + } + }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", + "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=" }, "diffie-hellman": { "version": "5.0.3", @@ -8377,7 +10263,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, "requires": { "domelementtype": "~1.1.1", "entities": "~1.1.1" @@ -8386,8 +10271,7 @@ "domelementtype": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" } } }, @@ -8405,8 +10289,7 @@ "domelementtype": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", - "dev": true + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" }, "domexception": { "version": "1.0.1", @@ -8427,10 +10310,9 @@ } }, "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "requires": { "dom-serializer": "0", "domelementtype": "1" @@ -8440,7 +10322,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, "requires": { "is-obj": "^1.0.0" } @@ -8448,8 +10329,7 @@ "dotenv": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.0.0.tgz", - "integrity": "sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg==", - "dev": true + "integrity": "sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg==" }, "dotenv-webpack": { "version": "1.5.7", @@ -8667,6 +10547,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } } } }, @@ -8700,6 +10590,16 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } } } }, @@ -8724,20 +10624,12 @@ "memory-fs": "^0.4.0", "object-assign": "^4.0.1", "tapable": "^0.2.7" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } } }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", - "dev": true + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, "enzyme": { "version": "3.6.0", @@ -8790,9 +10682,9 @@ } }, "enzyme-adapter-utils": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.8.0.tgz", - "integrity": "sha512-K9U2RGr1pvWPGEAIRQRVH4UdlqzpfLsKonuHyAK6lxu46yfGsMDVlO3+YvQwQpVjVw8eviEVIOmlFAnMbIhv/w==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.8.1.tgz", + "integrity": "sha512-s3QB3xQAowaDS2sHhmEqrT13GJC4+n5bG015ZkLv60n9k5vhxxHTQRIneZmQ4hmdCZEBrvUJ89PG6fRI5OEeuQ==", "dev": true, "requires": { "function.prototype.name": "^1.1.0", @@ -8836,7 +10728,6 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, "requires": { "es-to-primitive": "^1.1.1", "function-bind": "^1.1.1", @@ -8854,7 +10745,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -8980,6 +10870,12 @@ "private": "~0.1.5", "source-map": "~0.5.0" } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -9023,13 +10919,6 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true } } }, @@ -9149,12 +11038,6 @@ "estraverse": "^4.1.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "external-editor": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", @@ -9166,6 +11049,15 @@ "tmp": "^0.0.33" } }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "globals": { "version": "11.8.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", @@ -9201,22 +11093,6 @@ "strip-ansi": "^4.0.0", "through": "^2.3.6" } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } } } }, @@ -9277,6 +11153,17 @@ "minimatch": "^3.0.4", "resolve": "^1.8.1", "semver": "^5.5.0" + }, + "dependencies": { + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } } }, "eslint-plugin-react": { @@ -9331,9 +11218,9 @@ } }, "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.0.1", @@ -9416,6 +11303,11 @@ "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, + "events-to-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", + "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=" + }, "eventsource": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", @@ -9896,12 +11788,6 @@ "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "ua-parser-js": { "version": "0.7.18", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz", @@ -9919,8 +11805,7 @@ "fclone": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=", - "dev": true + "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" }, "feather-icons": { "version": "4.7.3", @@ -9939,12 +11824,12 @@ "dev": true }, "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "requires": { - "escape-string-regexp": "^1.0.5" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "file-entry-cache": { @@ -9955,14 +11840,6 @@ "requires": { "flat-cache": "^1.2.1", "object-assign": "^4.0.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "file-loader": { @@ -10215,6 +12092,14 @@ } } }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -10283,6 +12168,11 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "uuid": { + "version": "2.0.3", + "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" } } }, @@ -10940,11 +12830,6 @@ "number-is-nan": "^1.0.0" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -11101,9 +12986,9 @@ } }, "git-raw-commits": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz", - "integrity": "sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", + "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", "dev": true, "requires": { "dargs": "^4.0.1", @@ -11186,16 +13071,6 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -11307,9 +13182,9 @@ } }, "git-semver-tags": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.3.6.tgz", - "integrity": "sha512-2jHlJnln4D/ECk9FxGEBh3k44wgYdWjWDtMmJPaecjoRmxKo3Y1Lh8GMYuOPu04CHw86NTAODchYjC5pnpMQig==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.0.tgz", + "integrity": "sha512-lSgFc3zQTul31nFje2Q8XdNcTOI6B4I3mJRPCgFzHQQLfxfqdWTYzdtCaynkK5Xmb2wQlSJoKolhXJ1VhKROnQ==", "dev": true, "requires": { "meow": "^4.0.0", @@ -11383,16 +13258,6 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -11479,14 +13344,6 @@ "object-assign": "^4.1.1", "prop-types": "^15.5.10", "through": "^2.3.8" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "glamorous": { @@ -11707,14 +13564,6 @@ "object-assign": "^4.0.1", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "globule": { @@ -11814,7 +13663,6 @@ "version": "0.13.2", "resolved": "http://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz", "integrity": "sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog==", - "dev": true, "requires": { "iterall": "^1.2.1" } @@ -11823,7 +13671,6 @@ "version": "4.1.19", "resolved": "https://registry.npmjs.org/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz", "integrity": "sha512-mQlvbECzYPBcgBC9JsdM4v+DSvNmcIP+8Vwr+ij3gktbaLSE0Iza30mztuz40Jlf7ooMs+0emBZucNjLzqz7tA==", - "dev": true, "requires": { "apollo-utilities": "^1.0.21" } @@ -11839,24 +13686,14 @@ "js-yaml": "^3.10.0", "lodash": "^4.17.4", "minimatch": "^3.0.4" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } + } + }, + "graphql-extensions": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.2.1.tgz", + "integrity": "sha512-/1FTPSWSffDjlRyMAV2UwQhojLmca9aQD0ieo1IYiqT5SE+uOWi4r83QF1CoER0sREIsH3s+nTmdH3cvQVG3MA==", + "requires": { + "apollo-server-env": "^2.0.3" } }, "graphql-import": { @@ -11886,11 +13723,30 @@ "cross-fetch": "2.2.2" } }, + "graphql-subscriptions": { + "version": "0.5.8", + "resolved": "http://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz", + "integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==", + "requires": { + "iterall": "^1.2.1" + } + }, "graphql-tag": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.0.tgz", - "integrity": "sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w==", - "dev": true + "integrity": "sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w==" + }, + "graphql-tools": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-3.1.1.tgz", + "integrity": "sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg==", + "requires": { + "apollo-link": "^1.2.2", + "apollo-utilities": "^1.0.1", + "deprecated-decorator": "^0.1.6", + "iterall": "^1.1.3", + "uuid": "^3.1.0" + } }, "growl": { "version": "1.10.5", @@ -11980,6 +13836,74 @@ "postcss": "^5.2.12", "postcss-load-config": "^1.2.0", "vinyl-sourcemaps-apply": "^0.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } } }, "gulp-sass": { @@ -12192,47 +14116,11 @@ "version": "4.0.12", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", - "dev": true, "requires": { "async": "^2.5.0", "optimist": "^0.6.1", "source-map": "^0.6.1", "uglify-js": "^3.1.4" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - } - } } }, "har-schema": { @@ -12345,8 +14233,7 @@ "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, "has-unicode": { "version": "2.0.1", @@ -12406,6 +14293,11 @@ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + }, "history": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz", @@ -12434,6 +14326,22 @@ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" }, + "hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha1-TNnhq9QpQUbnZ55B14mHMrAse/0=", + "requires": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.0", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" + } + } + }, "hoist-non-react-statics": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", @@ -12533,6 +14441,16 @@ } } }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" + }, "html-comment-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", @@ -12568,16 +14486,8 @@ "es6-templates": "^0.2.3", "fastparse": "^1.1.1", "html-minifier": "^3.5.8", - "loader-utils": "^1.1.0", - "object-assign": "^4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } + "loader-utils": "^1.1.0", + "object-assign": "^4.1.1" } }, "html-minifier": { @@ -12593,30 +14503,6 @@ "param-case": "2.1.x", "relateurl": "0.2.x", "uglify-js": "3.4.x" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - } - } } }, "html-select": { @@ -12651,6 +14537,11 @@ "through2": "~0.4.1" }, "dependencies": { + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", @@ -12712,12 +14603,6 @@ "json5": "^0.5.0", "object-assign": "^4.0.1" } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true } } }, @@ -12919,12 +14804,6 @@ "source-map": "^0.6.1", "supports-color": "^5.4.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -13049,6 +14928,7 @@ "version": "1.10.6", "resolved": "https://registry.npmjs.org/informed/-/informed-1.10.6.tgz", "integrity": "sha512-aJX9w+oIDrSDCvDYPwieshTJe6X1SFi/dpJCp5gbBHYN9u1lAdYU/Fw2dH4lVnTV4vZyUr2Ag4nIKWiN3lW21w==", + "dev": true, "requires": { "@babel/runtime-corejs2": "^7.0.0-rc.1" } @@ -13109,6 +14989,17 @@ "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + } } }, "internal-ip": { @@ -13227,8 +15118,7 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, "is-ci": { "version": "1.2.1", @@ -13239,6 +15129,19 @@ "ci-info": "^1.5.0" } }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -13260,8 +15163,7 @@ "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=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", @@ -13468,7 +15370,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -13489,8 +15390,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" }, "is-retry-allowed": { "version": "1.1.0", @@ -13521,9 +15421,9 @@ "dev": true }, "is-svg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", - "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", "requires": { "html-comment-regex": "^1.1.0" } @@ -13532,7 +15432,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, "requires": { "has-symbols": "^1.0.0" } @@ -13646,17 +15545,6 @@ "js-yaml": "^3.7.0", "mkdirp": "^0.5.1", "once": "^1.4.0" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - } } }, "istanbul-lib-coverage": { @@ -13749,6 +15637,14 @@ "mkdirp": "^0.5.1", "rimraf": "^2.6.1", "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "istanbul-reports": { @@ -13798,14 +15694,136 @@ "json-stable-stringify": "^1.0.1" } }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "requires": { + "browserslist": "^1.3.6", + "caniuse-db": "^1.0.30000529", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "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.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "requires": { + "q": "^1.1.2" + } + }, + "cssnano": { + "version": "3.10.0", + "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "requires": { - "lodash": "^4.17.10" + "autoprefixer": "^6.3.1", + "decamelize": "^1.1.2", + "defined": "^1.0.0", + "has": "^1.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.14", + "postcss-calc": "^5.2.0", + "postcss-colormin": "^2.1.8", + "postcss-convert-values": "^2.3.4", + "postcss-discard-comments": "^2.0.4", + "postcss-discard-duplicates": "^2.0.1", + "postcss-discard-empty": "^2.0.1", + "postcss-discard-overridden": "^0.1.1", + "postcss-discard-unused": "^2.2.1", + "postcss-filter-plugins": "^2.0.0", + "postcss-merge-idents": "^2.1.5", + "postcss-merge-longhand": "^2.0.1", + "postcss-merge-rules": "^2.0.3", + "postcss-minify-font-values": "^1.0.2", + "postcss-minify-gradients": "^1.0.1", + "postcss-minify-params": "^1.0.4", + "postcss-minify-selectors": "^2.0.4", + "postcss-normalize-charset": "^1.1.0", + "postcss-normalize-url": "^3.0.7", + "postcss-ordered-values": "^2.1.0", + "postcss-reduce-idents": "^2.2.2", + "postcss-reduce-initial": "^1.0.0", + "postcss-reduce-transforms": "^1.0.3", + "postcss-svgo": "^2.1.1", + "postcss-unique-selectors": "^2.0.2", + "postcss-value-parser": "^3.2.3", + "postcss-zindex": "^2.0.1" + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "requires": { + "clap": "^1.0.9", + "source-map": "^0.5.3" } }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + }, "fs-extra": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", @@ -13821,6 +15839,23 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "requires": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + } + }, "jsonfile": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", @@ -13840,10 +15875,239 @@ "object-assign": "^4.0.1" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "requires": { + "postcss": "^5.0.2", + "postcss-message-helpers": "^2.0.0", + "reduce-css-calc": "^1.2.6" + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "requires": { + "colormin": "^1.0.5", + "postcss": "^5.0.13", + "postcss-value-parser": "^3.2.3" + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "requires": { + "postcss": "^5.0.11", + "postcss-value-parser": "^3.1.2" + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "requires": { + "postcss": "^5.0.14" + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "requires": { + "postcss": "^5.0.4" + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "requires": { + "postcss": "^5.0.14" + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "requires": { + "postcss": "^5.0.16" + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "requires": { + "postcss": "^5.0.4" + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "requires": { + "browserslist": "^1.5.2", + "caniuse-api": "^1.5.2", + "postcss": "^5.0.4", + "postcss-selector-parser": "^2.2.2", + "vendors": "^1.0.0" + } + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "requires": { + "object-assign": "^4.0.1", + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "requires": { + "postcss": "^5.0.12", + "postcss-value-parser": "^3.3.0" + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "requires": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.2", + "postcss-value-parser": "^3.0.2", + "uniqs": "^2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "requires": { + "alphanum-sort": "^1.0.2", + "has": "^1.0.1", + "postcss": "^5.0.14", + "postcss-selector-parser": "^2.0.0" + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "requires": { + "postcss": "^5.0.5" + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^1.4.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3" + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "requires": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.1" + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "requires": { + "postcss": "^5.0.4" + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "requires": { + "has": "^1.0.1", + "postcss": "^5.0.8", + "postcss-value-parser": "^3.0.1" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "requires": { + "is-svg": "^2.0.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3", + "svgo": "^0.7.0" + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "requires": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "requires": { + "balanced-match": "^0.4.2", + "math-expression-evaluator": "^1.2.14", + "reduce-function-call": "^1.0.1" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } }, "supports-color": { "version": "3.2.3", @@ -13853,6 +16117,43 @@ "has-flag": "^1.0.0" } }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "requires": { + "coa": "~1.0.1", + "colors": "~1.1.2", + "csso": "~2.3.1", + "js-yaml": "~3.7.0", + "mkdirp": "~0.5.1", + "sax": "~1.2.1", + "whet.extend": "~0.9.9" + } + }, + "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.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, "webpack": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.7.0.tgz", @@ -13880,6 +16181,16 @@ "webpack-sources": "^1.0.1", "yargs": "^6.0.0" } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" } } }, @@ -14241,6 +16552,14 @@ "diff": "^3.2.0", "jest-get-type": "^22.1.0", "pretty-format": "^23.6.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + } } }, "jest-docblock": { @@ -14625,13 +16944,7 @@ "source-map-support": "^0.5.6", "throat": "^4.0.0" }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, + "dependencies": { "source-map-support": { "version": "0.5.9", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", @@ -14916,12 +17229,6 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -14978,17 +17285,17 @@ "integrity": "sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ==" }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", - "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "requires": { "argparse": "^1.0.7", - "esprima": "^2.6.0" + "esprima": "^4.0.0" } }, "jsbn": { @@ -15036,15 +17343,6 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } } } }, @@ -15155,8 +17453,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-schema": { "version": "0.2.3", @@ -15339,26 +17636,26 @@ "dev": true }, "lerna": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.4.0.tgz", - "integrity": "sha512-RCLm0gMi8PESEF8PzMxo35foA2NGGC/NKnKiUmJyRrhLybOIUfVPdPStSAWCjW1c+DYCgLZCbxu57/KWt4ZWZA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.4.1.tgz", + "integrity": "sha512-00X2mYuwJk/bvxdjJceUxTjUgUg7MIMWllo2zGfDVGPijLadrg8QCtJASZqVE7HDQbBLDxLGPjswk29HF5JS2Q==", "dev": true, "requires": { - "@lerna/add": "^3.3.2", - "@lerna/bootstrap": "^3.3.2", - "@lerna/changed": "^3.3.2", + "@lerna/add": "^3.4.1", + "@lerna/bootstrap": "^3.4.1", + "@lerna/changed": "^3.4.1", "@lerna/clean": "^3.3.2", "@lerna/cli": "^3.2.0", - "@lerna/create": "^3.3.1", + "@lerna/create": "^3.4.1", "@lerna/diff": "^3.3.0", "@lerna/exec": "^3.3.2", "@lerna/import": "^3.3.1", "@lerna/init": "^3.3.0", "@lerna/link": "^3.3.0", "@lerna/list": "^3.3.2", - "@lerna/publish": "^3.4.0", + "@lerna/publish": "^3.4.1", "@lerna/run": "^3.3.2", - "@lerna/version": "^3.3.2", + "@lerna/version": "^3.4.1", "import-local": "^1.0.0", "npmlog": "^4.1.2" } @@ -15471,6 +17768,16 @@ "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + } } }, "loader-runner": { @@ -15841,6 +18148,11 @@ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", "dev": true }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -16150,6 +18462,11 @@ } } }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -16235,11 +18552,6 @@ "version": "1.2.0", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" } } }, @@ -16547,6 +18859,33 @@ "integrity": "sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw==", "dev": true }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -16602,6 +18941,11 @@ "duplexer2": "0.0.2" } }, + "mustache": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz", + "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==" + }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", @@ -16721,8 +19065,7 @@ "node-fetch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", - "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==", - "dev": true + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" }, "node-fetch-npm": { "version": "2.0.2", @@ -16760,6 +19103,14 @@ "which": "1" }, "dependencies": { + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", @@ -16849,6 +19200,14 @@ "which": "^1.3.0" } }, + "node-releases": { + "version": "1.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.0-alpha.12.tgz", + "integrity": "sha512-VPB4rTPqpVyWKBHbSa4YPFme3+8WHsOSpvbp0Mfj0bWsC8TEjt4HQrLl1hsBDELlp1nB4lflSgSuGTYiuyaP7Q==", + "requires": { + "semver": "^5.3.0" + } + }, "node-sass": { "version": "4.9.3", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.3.tgz", @@ -17030,9 +19389,9 @@ } }, "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "requires": { "abbrev": "1" } @@ -17087,6 +19446,19 @@ "ansi-regex": "^0.2.0" } }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + }, "strip-ansi": { "version": "0.3.0", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", @@ -17127,22 +19499,9 @@ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" }, "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } - } + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" }, "npm-bundled": { "version": "1.0.5", @@ -17645,16 +20004,6 @@ "strip-bom": "^3.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -17712,7 +20061,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", - "dev": true, "requires": { "boolbase": "~1.0.0" } @@ -17739,9 +20087,9 @@ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" }, "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-component": { "version": "0.0.3", @@ -17779,8 +20127,7 @@ "object-inspect": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" }, "object-is": { "version": "1.0.1", @@ -17789,14 +20136,14 @@ "dev": true }, "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" }, "object-path": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", - "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=" + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" }, "object-visit": { "version": "1.0.1", @@ -17816,14 +20163,6 @@ "function-bind": "^1.1.1", "has-symbols": "^1.0.0", "object-keys": "^1.0.11" - }, - "dependencies": { - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - } } }, "object.defaults": { @@ -17865,7 +20204,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.1" @@ -17911,7 +20249,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.0.4.tgz", "integrity": "sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.6.1", @@ -17936,8 +20273,7 @@ "on-headers": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "dev": true + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" }, "once": { "version": "1.4.0", @@ -17983,7 +20319,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" @@ -18100,14 +20435,6 @@ "graceful-fs": "^4.1.4", "mkdirp": "^0.5.1", "object-assign": "^4.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "p-defer": { @@ -18520,11 +20847,12 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse-link-header": { @@ -18536,6 +20864,11 @@ "xtend": "~4.0.1" } }, + "parse-ms": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", + "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=" + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -18627,6 +20960,14 @@ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" }, + "path-starts-with": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-starts-with/-/path-starts-with-1.0.0.tgz", + "integrity": "sha1-soJDAV6LE43lcmgqxS2kLmRq2E4=", + "requires": { + "normalize-path": "^2.1.1" + } + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -18716,6 +21057,11 @@ } } }, + "plur": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=" + }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", @@ -18739,6 +21085,12 @@ "mkdirp": "0.5.x" }, "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -18756,34 +21108,189 @@ } } }, - "portscanner": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", - "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", - "requires": { - "async": "1.5.2", - "is-number-like": "^1.0.3" - } - }, - "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=" - }, - "post-compile-webpack-plugin": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/post-compile-webpack-plugin/-/post-compile-webpack-plugin-0.1.2.tgz", - "integrity": "sha1-D254Ck3/Ll9Z8gf5A6jV8EdshC4=" - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "portscanner": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", + "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", + "requires": { + "async": "1.5.2", + "is-number-like": "^1.0.3" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + } + } + }, + "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=" + }, + "post-compile-webpack-plugin": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/post-compile-webpack-plugin/-/post-compile-webpack-plugin-0.1.2.tgz", + "integrity": "sha1-D254Ck3/Ll9Z8gf5A6jV8EdshC4=" + }, + "postcss": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.5.tgz", + "integrity": "sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.5.0" + } + }, + "postcss-calc": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-6.0.2.tgz", + "integrity": "sha512-fiznXjEN5T42Qm7qqMCVJXS3roaj9r4xsSi+meaBVe7CJBl8t/QLOXu02Z2E6oWAMWIvCuF6JrvzFekmVEbOKA==", + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.2", + "postcss-selector-parser": "^2.2.2", + "reduce-css-calc": "^2.0.0" + } + }, + "postcss-colormin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.2.tgz", + "integrity": "sha512-1QJc2coIehnVFsz0otges8kQLsryi4lo19WD+U5xCWvXd0uw/Z+KKYnbiNDCnO9GP+PvErPHCG0jNvWTngk9Rw==", + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-discard-comments": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.1.tgz", + "integrity": "sha512-Ay+rZu1Sz6g8IdzRjUgG2NafSNpp2MSMOQUb+9kkzzzP+kh07fP0yNbhtFejURnyVXSX3FYy2nVNW1QTnNjgBQ==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "requires": { + "postcss": "^5.0.14", + "uniqs": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-filter-plugins": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", + "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" + "postcss": "^5.0.4" }, "dependencies": { "ansi-regex": { @@ -18820,6 +21327,22 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, "strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -18838,84 +21361,6 @@ } } }, - "postcss-calc": { - "version": "5.3.1", - "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", - "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", - "requires": { - "postcss": "^5.0.2", - "postcss-message-helpers": "^2.0.0", - "reduce-css-calc": "^1.2.6" - } - }, - "postcss-colormin": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", - "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", - "requires": { - "colormin": "^1.0.5", - "postcss": "^5.0.13", - "postcss-value-parser": "^3.2.3" - } - }, - "postcss-convert-values": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", - "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", - "requires": { - "postcss": "^5.0.11", - "postcss-value-parser": "^3.1.2" - } - }, - "postcss-discard-comments": { - "version": "2.0.4", - "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", - "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", - "requires": { - "postcss": "^5.0.14" - } - }, - "postcss-discard-duplicates": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", - "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", - "requires": { - "postcss": "^5.0.4" - } - }, - "postcss-discard-empty": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", - "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", - "requires": { - "postcss": "^5.0.14" - } - }, - "postcss-discard-overridden": { - "version": "0.1.1", - "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", - "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", - "requires": { - "postcss": "^5.0.16" - } - }, - "postcss-discard-unused": { - "version": "2.2.3", - "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", - "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", - "requires": { - "postcss": "^5.0.14", - "uniqs": "^2.0.0" - } - }, - "postcss-filter-plugins": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", - "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", - "requires": { - "postcss": "^5.0.4" - } - }, "postcss-flexbugs-fixes": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-3.3.1.tgz", @@ -18935,12 +21380,6 @@ "source-map": "^0.6.1", "supports-color": "^5.4.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -18955,10 +21394,32 @@ "postcss-load-plugins": "^2.3.0" }, "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.4.3", + "minimist": "^1.2.0", + "object-assign": "^4.1.0", + "os-homedir": "^1.0.1", + "parse-json": "^2.2.0", + "require-from-string": "^1.1.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } } } }, @@ -18971,10 +21432,32 @@ "object-assign": "^4.1.0" }, "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.4.3", + "minimist": "^1.2.0", + "object-assign": "^4.1.0", + "os-homedir": "^1.0.1", + "parse-json": "^2.2.0", + "require-from-string": "^1.1.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } } } }, @@ -18987,10 +21470,32 @@ "object-assign": "^4.1.0" }, "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.4.3", + "minimist": "^1.2.0", + "object-assign": "^4.1.0", + "os-homedir": "^1.0.1", + "parse-json": "^2.2.0", + "require-from-string": "^1.1.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } } } }, @@ -19018,32 +21523,6 @@ "require-from-string": "^2.0.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "postcss": { "version": "6.0.23", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", @@ -19070,12 +21549,6 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -19087,26 +21560,110 @@ "has": "^1.0.1", "postcss": "^5.0.10", "postcss-value-parser": "^3.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } } }, "postcss-merge-longhand": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", - "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.6.tgz", + "integrity": "sha512-JavnI+V4IHWsaUAfOoKeMEiJQGXTraEy1nHM0ILlE6NIQPEZrJDAnPh3lNGZ5HAk2mSSrwp66JoGhvjp6SqShA==", "requires": { - "postcss": "^5.0.4" + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" } }, "postcss-merge-rules": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", - "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", - "requires": { - "browserslist": "^1.5.2", - "caniuse-api": "^1.5.2", - "postcss": "^5.0.4", - "postcss-selector-parser": "^2.2.2", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.2.tgz", + "integrity": "sha512-UiuXwCCJtQy9tAIxsnurfF0mrNHKc4NnNx6NxqmzNNjXpQwLSukUxELHTRF0Rg1pAmcoKLih8PwvZbiordchag==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } } }, "postcss-message-helpers": { @@ -19115,51 +21672,59 @@ "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" }, "postcss-minify-font-values": { - "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", - "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", "requires": { - "object-assign": "^4.0.1", - "postcss": "^5.0.4", - "postcss-value-parser": "^3.0.2" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-minify-gradients": { - "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", - "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.1.tgz", + "integrity": "sha512-pySEW3E6Ly5mHm18rekbWiAjVi/Wj8KKt2vwSfVFAWdW6wOIekgqxKxLU7vJfb107o3FDNPkaYFCxGAJBFyogA==", "requires": { - "postcss": "^5.0.12", - "postcss-value-parser": "^3.3.0" + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-minify-params": { - "version": "1.2.2", - "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", - "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", - "requires": { - "alphanum-sort": "^1.0.1", - "postcss": "^5.0.2", - "postcss-value-parser": "^3.0.2", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.1.tgz", + "integrity": "sha512-h4W0FEMEzBLxpxIVelRtMheskOKKp52ND6rJv+nBS33G1twu2tCyurYj/YtgU76+UDCvWeNs0hs8HFAWE2OUFg==", + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", "uniqs": "^2.0.0" } }, "postcss-minify-selectors": { - "version": "2.1.1", - "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", - "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.1.tgz", + "integrity": "sha512-8+plQkomve3G+CodLCgbhAKrb5lekAnLYuL1d7Nz+/7RANpBEVdgBkPNwljfSKvZ9xkkZTZITd04KP+zeJTJqg==", "requires": { - "alphanum-sort": "^1.0.2", - "has": "^1.0.1", - "postcss": "^5.0.14", - "postcss-selector-parser": "^2.0.0" + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } } }, "postcss-modules-extract-imports": { @@ -19181,12 +21746,6 @@ "source-map": "^0.6.1", "supports-color": "^5.4.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -19210,12 +21769,6 @@ "source-map": "^0.6.1", "supports-color": "^5.4.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -19239,12 +21792,6 @@ "source-map": "^0.6.1", "supports-color": "^5.4.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -19268,41 +21815,107 @@ "source-map": "^0.6.1", "supports-color": "^5.4.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, "postcss-normalize-charset": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", - "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.1.tgz", + "integrity": "sha512-R5mC4vaDdvsrku96yXP7zak+O3Mm9Y8IslUobk7IMP+u/g+lXvcN4jngmHY5zeJnrQvE13dfAg5ViU05ZFDwdg==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-positions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.1.tgz", + "integrity": "sha512-GNoOaLRBM0gvH+ZRb2vKCIujzz4aclli64MBwDuYGU2EY53LwiP7MxOZGE46UGtotrSnmarPPZ69l2S/uxdaWA==", "requires": { - "postcss": "^5.0.5" + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.1.tgz", + "integrity": "sha512-fFHPGIjBUyUiswY2rd9rsFcC0t3oRta4wxE1h3lpwfQZwFeFjXFSiDtdJ7APCmHQOnUZnqYBADNRPKPwFAONgA==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-string": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.1.tgz", + "integrity": "sha512-IJoexFTkAvAq5UZVxWXAGE0yLoNN/012v7TQh5nDo6imZJl2Fwgbhy3J2qnIoaDBrtUP0H7JrXlX1jjn2YcvCQ==", + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.1.tgz", + "integrity": "sha512-1nOtk7ze36+63ONWD8RCaRDYsnzorrj+Q6fxkQV+mlY5+471Qx9kspqv0O/qQNMeApg8KNrRf496zHwJ3tBZ7w==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-normalize-url": { - "version": "3.0.8", - "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", - "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", "requires": { "is-absolute-url": "^2.0.0", - "normalize-url": "^1.4.0", - "postcss": "^5.0.14", - "postcss-value-parser": "^3.2.3" + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.1.tgz", + "integrity": "sha512-U8MBODMB2L+nStzOk6VvWWjZgi5kQNShCyjRhMT3s+W9Jw93yIjOnrEkKYD3Ul7ChWbEcjDWmXq0qOL9MIAnAw==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-ordered-values": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", - "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.1.tgz", + "integrity": "sha512-PeJiLgJWPzkVF8JuKSBcylaU+hDJ/TX3zqAMIjlghgn1JBi6QwQaDZoDIlqWRcCAI8SxKrt3FCPSRmOgKRB97Q==", "requires": { - "postcss": "^5.0.4", - "postcss-value-parser": "^3.0.1" + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-reduce-idents": { @@ -19312,24 +21925,96 @@ "requires": { "postcss": "^5.0.4", "postcss-value-parser": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } } }, "postcss-reduce-initial": { - "version": "1.0.1", - "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", - "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.2.tgz", + "integrity": "sha512-epUiC39NonKUKG+P3eAOKKZtm5OtAtQJL7Ye0CBN1f+UQTHzqotudp+hki7zxXm7tT0ZAKDMBj1uihpPjP25ug==", "requires": { - "postcss": "^5.0.4" + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" } }, "postcss-reduce-transforms": { - "version": "1.0.4", - "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", - "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.1.tgz", + "integrity": "sha512-sZVr3QlGs0pjh6JAIe6DzWvBaqYw05V1t3d9Tp+VnFRT5j+rsqoWsysh/iSD7YNsULjq9IAylCznIwVd5oU/zA==", "requires": { - "has": "^1.0.1", - "postcss": "^5.0.8", - "postcss-value-parser": "^3.0.1" + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" } }, "postcss-reporter": { @@ -19365,6 +22050,37 @@ "supports-color": "^2.0.0" } }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, "strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -19391,23 +22107,23 @@ } }, "postcss-svgo": { - "version": "2.1.6", - "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", - "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.1.tgz", + "integrity": "sha512-YD5uIk5NDRySy0hcI+ZJHwqemv2WiqqzDgtvgMzO8EGSkK5aONyX8HMVFRFJSdO8wUWTuisUFn/d7yRRbBr5Qw==", "requires": { - "is-svg": "^2.0.0", - "postcss": "^5.0.14", - "postcss-value-parser": "^3.2.3", - "svgo": "^0.7.0" + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" } }, "postcss-unique-selectors": { - "version": "2.0.2", - "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", - "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", "requires": { - "alphanum-sort": "^1.0.1", - "postcss": "^5.0.4", + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", "uniqs": "^2.0.0" } }, @@ -19424,6 +22140,74 @@ "has": "^1.0.1", "postcss": "^5.0.4", "uniqs": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } } }, "prelude-ls": { @@ -19504,6 +22288,16 @@ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, + "pretty-ms": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", + "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", + "requires": { + "is-finite": "^1.0.1", + "parse-ms": "^1.0.0", + "plur": "^1.0.0" + } + }, "prismjs": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz", @@ -19563,6 +22357,14 @@ "requires": { "err-code": "^1.0.0", "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + } } }, "promise.prototype.finally": { @@ -19599,18 +22401,9 @@ "version": "15.6.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", - "dev": true, "requires": { "loose-envify": "^1.3.1", "object-assign": "^4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "propagate": { @@ -19625,6 +22418,26 @@ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", "dev": true }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, "protoduck": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.0.tgz", @@ -19742,9 +22555,6 @@ "jquery": "^3.3.1" } }, - "pwa-module": { - "version": "file:packages/pwa-module" - }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -19762,13 +22572,6 @@ "requires": { "object-assign": "^4.1.0", "strict-uri-encode": "^1.0.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } } }, "querystring": { @@ -19945,14 +22748,6 @@ "object-assign": "^4.1.1", "prop-types": "^15.6.2", "schedule": "^0.5.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "react-apollo": { @@ -19994,12 +22789,6 @@ "react-is": "^16.3.2" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "ua-parser-js": { "version": "0.7.18", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz", @@ -20097,44 +22886,24 @@ "integrity": "sha512-jOnu9qEqNlBx5Jrgx8mcHmG6FQcrBIpdZ5HTcZqW5hOkYsmCAPID0vEm66mkVbh3anli9+WWK2wL3AKK1ivNBA==", "dev": true, "requires": { - "@babel/parser": "7.0.0-beta.53", - "async": "^2.1.4", - "babel-runtime": "^6.9.2", - "commander": "^2.9.0", - "doctrine": "^2.0.0", - "node-dir": "^0.1.10", - "recast": "^0.15.0" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - } + "@babel/parser": "7.0.0-beta.53", + "async": "^2.1.4", + "babel-runtime": "^6.9.2", + "commander": "^2.9.0", + "doctrine": "^2.0.0", + "node-dir": "^0.1.10", + "recast": "^0.15.0" } }, "react-dom": { "version": "16.5.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.5.2.tgz", "integrity": "sha512-RC8LDw8feuZOHVgzEf7f+cxBr/DnKdqp56VU0lAs1f4UfKc4cU8wU4fTq/mgnvynLQo8OtlPC19NUFh/zjZPuA==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "schedule": "^0.5.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "react-error-overlay": { @@ -20332,14 +23101,6 @@ "prop-types": "^15.6.2", "react-is": "^16.5.2", "schedule": "^0.5.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "react-transition-group": { @@ -20526,20 +23287,6 @@ "esprima": "~4.0.0", "private": "~0.1.5", "source-map": "~0.6.1" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "rechoir": { @@ -20580,20 +23327,12 @@ } }, "reduce-css-calc": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", - "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.5.tgz", + "integrity": "sha512-AybiBU03FKbjYzyvJvwkJZY6NLN+80Ufc2EqEs+41yQH+8wqBEslD6eGiS0oIeq5TNLA5PrhBeYHXWdn8gtW7A==", "requires": { - "balanced-match": "^0.4.2", - "math-expression-evaluator": "^1.2.14", - "reduce-function-call": "^1.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" - } + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" } }, "reduce-function-call": { @@ -20794,6 +23533,28 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -20867,11 +23628,6 @@ "requires": { "punycode": "^1.4.1" } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" } } }, @@ -20934,9 +23690,9 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "requires": { "path-parse": "^1.0.5" } @@ -21010,16 +23766,23 @@ "signal-exit": "^3.0.2" } }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "requires": { + "through": "~2.3.4" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" }, "rfc6902": { "version": "2.4.0", @@ -21027,6 +23790,16 @@ "integrity": "sha512-Oof0+ZGIey7+U2kIU51Ao2YUjgkik6iFwyKNIRzNnl9DD/WnaxQnp21iUwBlkbqrRkxuE/DGPRroLzYjj/ngMA==", "dev": true }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -21288,17 +24061,8 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/schedule/-/schedule-0.5.0.tgz", "integrity": "sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw==", - "dev": true, "requires": { "object-assign": "^4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } } }, "schema-utils": { @@ -21584,6 +24348,21 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sisteransi": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-0.1.1.tgz", @@ -21659,6 +24438,11 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -21805,6 +24589,16 @@ "debug": "~3.1.0", "isarray": "2.0.1" } + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } } } }, @@ -21897,12 +24691,6 @@ "requires": { "websocket-driver": ">=0.5.1" } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true } } }, @@ -21971,9 +24759,9 @@ "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { "version": "0.5.2", @@ -21993,6 +24781,13 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "requires": { "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "source-map-url": { @@ -22234,6 +25029,11 @@ "safe-buffer": "^5.1.1" } }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + }, "stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", @@ -22469,6 +25269,11 @@ "limiter": "^1.0.5" } }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -22543,7 +25348,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.0", @@ -22639,6 +25443,40 @@ "schema-utils": "^0.4.5" } }, + "stylehacks": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.1.tgz", + "integrity": "sha512-TK5zEPeD9NyC1uPIdjikzsgWxdQQN/ry1X3d1iOz1UkYDCmcr928gWD1KHgyC27F50UnE0xCTrBOO1l6KR8M4w==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "subscriptions-transport-ws": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz", + "integrity": "sha512-f9eBfWdHsePQV67QIX+VRhf++dn1adyC/PZHP6XI5AfKnZ4n0FW+v5omxwdHVpd4xq2ZijaHEcmlQrhBY79ZWQ==", + "requires": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0" + } + }, "superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -22732,31 +25570,30 @@ "dev": true }, "svgo": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", - "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.1.1.tgz", + "integrity": "sha512-GBkJbnTuFpM4jFbiERHDWhZc/S/kpHToqmZag3aEBjPYK44JAN2QBjvrGIxLOoCyMZjuFQIfTO2eJd8uwLY/9g==", "requires": { - "coa": "~1.0.1", + "coa": "~2.0.1", "colors": "~1.1.2", - "csso": "~2.3.1", - "js-yaml": "~3.7.0", + "css-select": "^2.0.0", + "css-select-base-adapter": "~0.1.0", + "css-tree": "1.0.0-alpha.28", + "css-url-regex": "^1.1.0", + "csso": "^3.5.0", + "js-yaml": "^3.12.0", "mkdirp": "~0.5.1", - "sax": "~1.2.1", - "whet.extend": "~0.9.9" - }, - "dependencies": { - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" - } + "object.values": "^1.0.4", + "sax": "~1.2.4", + "stable": "~0.1.6", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" } }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "symbol-tree": { "version": "3.2.2", @@ -22773,25 +25610,222 @@ "has-symbols": "^1.0.0" } }, - "table": { - "version": "4.0.3", - "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", - "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", - "dev": true, + "table": { + "version": "4.0.3", + "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "dev": true, + "requires": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + } + } + }, + "tap-diff": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tap-diff/-/tap-diff-0.1.1.tgz", + "integrity": "sha1-j78zM9hWQ/7qG/F1m5CCCwSjfd8=", + "requires": { + "chalk": "^1.1.1", + "diff": "^2.2.1", + "duplexer": "^0.1.1", + "figures": "^1.4.0", + "pretty-ms": "^2.1.0", + "tap-parser": "^1.2.2", + "through2": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^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=" + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + } + } + }, + "tap-parser": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.3.2.tgz", + "integrity": "sha1-EgxQiciMPIp5PvKIhn3jIeGPjCI=", + "requires": { + "events-to-array": "^1.0.1", + "inherits": "~2.0.1", + "js-yaml": "^3.2.7", + "readable-stream": "^2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "tap-xunit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tap-xunit/-/tap-xunit-2.3.0.tgz", + "integrity": "sha512-YVsURNvn1wfVUWb5wjansxhfbfeo2hOBTUbVgZoaMO8lyZzpiSi9IiZTZ7JG56m6A49LeWjfJIx/SnAre41V/A==", "requires": { - "ajv": "^6.0.1", - "ajv-keywords": "^3.0.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "duplexer": "~0.1.1", + "minimist": "~1.2.0", + "tap-parser": "~1.2.2", + "through2": "~2.0.0", + "xmlbuilder": "~4.2.0", + "xtend": "~4.0.0" }, "dependencies": { - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "tap-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.2.2.tgz", + "integrity": "sha1-Xi9pcGEfB5x8+FfeHceqG0gN56U=", + "requires": { + "events-to-array": "^1.0.1", + "inherits": "~2.0.1", + "js-yaml": "^3.2.7", + "readable-stream": "^2" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } } } }, @@ -22800,6 +25834,33 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=" }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, "tar": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", @@ -22835,12 +25896,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true } } }, @@ -22969,12 +26024,6 @@ "parse-glob": "^3.0.4", "regex-cache": "^0.4.2" } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true } } }, @@ -23021,6 +26070,11 @@ "supports-color": "^2.0.0" } }, + "object-path": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", + "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=" + }, "strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -23036,9 +26090,6 @@ } } }, - "theme-frontend-venia": { - "version": "file:packages/venia-concept" - }, "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", @@ -23164,6 +26215,11 @@ "setimmediate": "^1.0.4" } }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, "tiny-emitter": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", @@ -23259,17 +26315,6 @@ "dev": true, "requires": { "nopt": "~1.0.10" - }, - "dependencies": { - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - } } }, "tough-cookie": { @@ -23297,6 +26342,11 @@ "punycode": "^2.1.0" } }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" + }, "tree-kill": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", @@ -23400,46 +26450,12 @@ "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" }, "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "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.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" - }, - "yargs": { - "version": "3.10.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } + "commander": "~2.17.1", + "source-map": "~0.6.1" } }, "uglify-to-browserify": { @@ -23470,12 +26486,6 @@ "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -23647,6 +26657,11 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -23839,13 +26854,6 @@ "is-object": "^1.0.1", "is-string": "^1.0.4", "object-assign": "^4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - } } }, "use": { @@ -23884,7 +26892,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "object.getownpropertydescriptors": "^2.0.3" @@ -23902,9 +26909,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "2.0.3", - "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8flags": { "version": "2.1.1", @@ -24060,6 +27067,13 @@ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "requires": { "source-map": "^0.5.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "vm-browserify": { @@ -24247,13 +27261,27 @@ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", "dev": true }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "lodash": "^4.17.10" + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" } }, "execa": { @@ -24286,6 +27314,15 @@ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, "load-json-file": { "version": "2.0.0", "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -24309,6 +27346,15 @@ "mem": "^1.1.0" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -24339,6 +27385,21 @@ "read-pkg": "^2.0.0" } }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -24354,6 +27415,31 @@ "has-flag": "^2.0.0" } }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, "uglifyjs-webpack-plugin": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", @@ -24371,6 +27457,18 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, "yargs": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", @@ -24390,6 +27488,38 @@ "which-module": "^2.0.0", "y18n": "^3.2.1", "yargs-parser": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + } } }, "yargs-parser": { @@ -24399,6 +27529,14 @@ "dev": true, "requires": { "camelcase": "^4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } } } } @@ -24680,12 +27818,6 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -24755,13 +27887,6 @@ "requires": { "source-list-map": "^2.0.0", "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==" - } } }, "websocket-driver": { @@ -24871,9 +27996,9 @@ "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" }, "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "workbox-background-sync": { "version": "3.6.2", @@ -25163,13 +28288,11 @@ } }, "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "async-limiter": "~1.0.0" } }, "xdg-basedir": { @@ -25190,6 +28313,14 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "xmlbuilder": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", + "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", + "requires": { + "lodash": "^4.0.0" + } + }, "xmlhttprequest-ssl": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", @@ -25297,14 +28428,12 @@ "zen-observable": { "version": "0.8.9", "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.9.tgz", - "integrity": "sha512-Y9kPzjGvIZ5jchSlqlCpBW3I82zBBL4z+ulXDRVA1NwsKzjt5kwAi+gOYIy0htNkfuehGZZtP5mRXHRV6TjDWw==", - "dev": true + "integrity": "sha512-Y9kPzjGvIZ5jchSlqlCpBW3I82zBBL4z+ulXDRVA1NwsKzjt5kwAi+gOYIy0htNkfuehGZZtP5mRXHRV6TjDWw==" }, "zen-observable-ts": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz", "integrity": "sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ==", - "dev": true, "requires": { "zen-observable": "^0.8.0" } diff --git a/package.json b/package.json index f8dbd8eb172..ce276f97cee 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "node": ">=8.0.0" }, "scripts": { - "build": "lerna --stream --scope '{@magento/pwa-buildpack,@magento/peregrine,theme-frontend-venia}' exec -- npm run build", + "build": "lerna --stream --scope '{@magento/pwa-buildpack,@magento/peregrine,@magento/venia-concept}' exec -- npm run build", "clean:all": "lerna run clean && lerna clean --yes && rimraf ./node_modules", "clean:dist": "lerna run clean", "coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", @@ -20,9 +20,10 @@ "lint": "eslint '@(packages|scripts)/**/*.js' --ignore-pattern node_modules --ignore-pattern storybook-dist", "prettier": "prettier --write '@(packages|scripts)/**/*.@(js|css)' '*.js'", "prettier:check": "prettier --list-different '@(packages|scripts)/**/*.@(js|css)' '*.js'", + "stage:venia": "cd packages/venia-concept && npm start; cd - >/dev/null", "test": "jest", "test:ci": "npm run -s test -- -i --json --outputFile=test-results.json", - "test:debug": "node --inspect-brk node_modules/.bin/jest -i --watch", + "test:debug": "node --inspect-brk node_modules/.bin/jest -i", "test:dev": "jest --watch", "validate:venia:gql": "cd packages/venia-concept && npm run -s validate-queries; cd - >/dev/null", "watch:all": "concurrently -c yellow.dim,green.dim,cyan.dim -n ␢,℗,☄︎ 'npm run watch:buildpack' 'npm run watch:peregrine' 'npm run watch:venia-dev-server'", @@ -43,6 +44,7 @@ "babel-eslint": "^8.2.3", "babel-loader": "^7.1.2", "babel-plugin-graphql-tag": "^1.6.0", + "babel-plugin-import-graphql": "^2.6.2", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-class-properties": "^6.24.1", @@ -113,9 +115,8 @@ "dependencies": { "@magento/peregrine": "file:packages/peregrine", "@magento/pwa-buildpack": "file:packages/pwa-buildpack", - "informed": "^1.10.5", "pwa-devdocs": "file:packages/pwa-devdocs", - "pwa-module": "file:packages/pwa-module", - "theme-frontend-venia": "file:packages/venia-concept" + "@magento/upward-js": "file:packages/upward-js", + "@magento/upward-spec": "file:packages/upward-spec" } } diff --git a/packages/peregrine/CHANGELOG.md b/packages/peregrine/CHANGELOG.md new file mode 100644 index 00000000000..9eec12082cd --- /dev/null +++ b/packages/peregrine/CHANGELOG.md @@ -0,0 +1,13 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +# 0.5.0 (2018-08-13) + + +### Features + +* multicasting REST API client ([#164](https://github.com/magento-research/pwa-studio/issues/164)) ([2852e14](https://github.com/magento-research/pwa-studio/commit/2852e14)), closes [#140](https://github.com/magento-research/pwa-studio/issues/140) +* Simulators for async testing ([#24](https://github.com/magento-research/pwa-studio/issues/24)) ([a380da9](https://github.com/magento-research/pwa-studio/commit/a380da9)) diff --git a/packages/peregrine/README.md b/packages/peregrine/README.md index a9d1eb4d6a9..6e8d1935d3d 100644 --- a/packages/peregrine/README.md +++ b/packages/peregrine/README.md @@ -1,7 +1,7 @@ # Peregrine The Peregrine project is a collection of UI components for Magento PWA projects. -Use, extend, or remix these components to create a unique Magento PWA theme. +Use, extend, or remix these components to create a unique Magento PWA storefront. See [Peregrine documentation] diff --git a/packages/peregrine/src/Router/resolveUnknownRoute.js b/packages/peregrine/src/Router/resolveUnknownRoute.js index 7957f81f7c4..65c0230d302 100644 --- a/packages/peregrine/src/Router/resolveUnknownRoute.js +++ b/packages/peregrine/src/Router/resolveUnknownRoute.js @@ -4,13 +4,11 @@ * @param {{ route: string, apiBase: string, __tmp_webpack_public_path__: string}} opts * @returns {Promise<{matched: boolean, rootChunkID: number | undefined, rootModuleID: number | undefined, id: number }>} */ +let preloadDone = false; export default function resolveUnknownRoute(opts) { const { route, apiBase, __tmp_webpack_public_path__ } = opts; - return remotelyResolveRoute({ - route, - apiBase - }).then(res => { + function handleResolverResponse(res) { if (!(res && res.type)) { return { matched: false }; } @@ -23,7 +21,34 @@ export default function resolveUnknownRoute(opts) { id: res.id, matched: true })); - }); + } + + if (!preloadDone) { + const preloaded = document.getElementById('url-resolver'); + if (preloaded) { + const rejectPreload = e => + console.error( + 'Unable to read preload!', + preloaded.textContent, + e + ); + try { + return handleResolverResponse( + JSON.parse(preloaded.textContent) + ).then(x => { + preloadDone = true; + return x; + }, rejectPreload); + } catch (e) { + rejectPreload(e); + } + } + } + + return remotelyResolveRoute({ + route, + apiBase + }).then(handleResolverResponse); } /** diff --git a/packages/pwa-buildpack/CHANGELOG.md b/packages/pwa-buildpack/CHANGELOG.md index 0515344a795..c3409869a60 100644 --- a/packages/pwa-buildpack/CHANGELOG.md +++ b/packages/pwa-buildpack/CHANGELOG.md @@ -1,6 +1,33 @@ # Change Log -All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +# 0.9.0 (2018-08-13) + + +### Bug Fixes + +* disable buggy origin sub by default ([#23](https://github.com/magento-research/pwa-studio/issues/23)) ([fde4036](https://github.com/magento-research/pwa-studio/commit/fde4036)) +* remove buggy sudo-prompt until fallback works ([#39](https://github.com/magento-research/pwa-studio/issues/39)) ([1a1da3e](https://github.com/magento-research/pwa-studio/commit/1a1da3e)), closes [#35](https://github.com/magento-research/pwa-studio/issues/35) +* update devcert dependency ([68c7cca](https://github.com/magento-research/pwa-studio/commit/68c7cca)) +* **dev:** MagentoRootComponentsPlugin dedupe fix ([bb8b152](https://github.com/magento-research/pwa-studio/commit/bb8b152)) +* **dev:** merge 'assets' and 'output' paths ([36d8157](https://github.com/magento-research/pwa-studio/commit/36d8157)) +* **DevProxy:** put proxy after other middlewares ([#33](https://github.com/magento-research/pwa-studio/issues/33)) ([7fa577c](https://github.com/magento-research/pwa-studio/commit/7fa577c)), closes [#32](https://github.com/magento-research/pwa-studio/issues/32) +* **util:** fix run-as-root await rm bug ([#28](https://github.com/magento-research/pwa-studio/issues/28)) ([e6f0754](https://github.com/magento-research/pwa-studio/commit/e6f0754)), closes [magento-research/venia-pwa-concept#51](https://github.com/magento-research/venia-pwa-concept/issues/51) + + +### Features + +* add protocol error detection to devproxy ([#22](https://github.com/magento-research/pwa-studio/issues/22)) ([7ff4aaa](https://github.com/magento-research/pwa-studio/commit/7ff4aaa)) +* **data:** Add live GraphQL data to product detail page ([#90](https://github.com/magento-research/pwa-studio/issues/90)) ([77b6bd6](https://github.com/magento-research/pwa-studio/commit/77b6bd6)), closes [#52](https://github.com/magento-research/pwa-studio/issues/52) [#87](https://github.com/magento-research/pwa-studio/issues/87) +* **dev:** app shell detects env from proxy header ([ac5b0b0](https://github.com/magento-research/pwa-studio/commit/ac5b0b0)) +* **dev:** log dev URL prominently after build ([#114](https://github.com/magento-research/pwa-studio/issues/114)) ([84fadde](https://github.com/magento-research/pwa-studio/commit/84fadde)), closes [#4](https://github.com/magento-research/pwa-studio/issues/4) + + + + ## [0.8.2](https://github.com/magento-research/pwa-buildpack/compare/v0.8.1...v0.8.2) (2018-05-26) diff --git a/packages/pwa-buildpack/README.md b/packages/pwa-buildpack/README.md index ef41a706a60..4cc32216ee7 100644 --- a/packages/pwa-buildpack/README.md +++ b/packages/pwa-buildpack/README.md @@ -422,18 +422,13 @@ or energy setting up their own services layer. ### Elements -- [`magento-layout-loader`](docs/magento-layout-loader.md) -- Gives Magento - modules/extensions the ability to inject or remove content blocks in a layout - without modifying theme source files -- [`MagentoRootComponentsPlugin`](docs/MagentoRootComponentsPlugin.md) -- - Divides static assets into bundled "chunks" based on components registered - with the Magento PWA `RootComponent` interface -- [`PWADevServer`](docs/PWADevServer.md) -- Autoconfigures local system and - theme configuration for local PWA-optimized theme development -- [`ServiceWorkerPlugin`](docs/ServiceWorkerPlugin.md) -- Creates - a ServiceWorker with different settings based on dev scenarios -- [`MagentoResolver`](docs/MagentoResolver.md) -- Configures Webpack to resolve - modules and assets in Magento PWA themes. +- [`PWADevServer`](docs/PWADevServer.md) -- Autoconfigures local system and theme configuration for local PWA-optimized theme development +- [`MagentoResolver`](docs/MagentoResolver.md) -- Configures Webpack to resolve modules and assets in PWA Studio projects. +- [`UpwardPlugin`](docs/UpwardPlugin.md) -- Attaches a hot reloading UPWARD server, powered by [upward-js](../upward-js), to the Webpack dev server +- [`ServiceWorkerPlugin`](docs/ServiceWorkerPlugin.md) -- Creates a ServiceWorker with different settings based on dev scenarios +- [`DevServerReadyNotifierPlugin`](docs/DevServerReadyNotifierPlugin.md) -- Displays a prominent link in the console to a running dev environment once it is launched +- [`MagentoRootComponentsPlugin`](docs/MagentoRootComponentsPlugin.md) -- Divides static assets into bundled "chunks" based on components registered with the Magento PWA `RootComponent` interface +- [`magento-layout-loader`](docs/magento-layout-loader.md) -- Gives Magento modules/extensions the ability to inject or remove content blocks in a layout without modifying theme source files ## Afterword diff --git a/packages/pwa-buildpack/docs/MagentoResolver.md b/packages/pwa-buildpack/docs/MagentoResolver.md index f74a2a16c2b..f1944e9c700 100644 --- a/packages/pwa-buildpack/docs/MagentoResolver.md +++ b/packages/pwa-buildpack/docs/MagentoResolver.md @@ -54,5 +54,5 @@ module.exports = async env => { #### `options` -- `paths: object`: **Required.** Local absolute paths to theme folders. -- `root`: Absolute path to the root directory of the theme. +- `paths: object`: **Required.** Local absolute paths to project folders. +- `root`: Absolute path to the root directory of the project. diff --git a/packages/pwa-buildpack/docs/MagentoRootComponentsPlugin.md b/packages/pwa-buildpack/docs/MagentoRootComponentsPlugin.md index 7fb363807a1..725c4e7be53 100644 --- a/packages/pwa-buildpack/docs/MagentoRootComponentsPlugin.md +++ b/packages/pwa-buildpack/docs/MagentoRootComponentsPlugin.md @@ -2,9 +2,9 @@ Automagically creates [unique chunks](https://webpack.js.org/guides/code-splitting/) for each Root Component -in a Magento PWA theme and extensions. +in a Magento PWA project and extensions. -Given a `RootComponents` directory in a theme with the following structure: +Given a `RootComponents` directory in a project with the following structure: ```sh ├── Page1 diff --git a/packages/pwa-buildpack/docs/PWADevServer.md b/packages/pwa-buildpack/docs/PWADevServer.md index cc34bf1561c..b726fa74bab 100644 --- a/packages/pwa-buildpack/docs/PWADevServer.md +++ b/packages/pwa-buildpack/docs/PWADevServer.md @@ -17,11 +17,11 @@ module.exports = async env => { /* webpack entry, output, rules, etc */ devServer: await PWADevServer.configure({ - publicPath: '/pub/static/frontend/Vendor/theme/en_US/', + publicPath: '/pub/static/frontend/Vendor/project/en_US/', backendDomain: 'https://magento2.localdomain', serviceWorkerFileName: 'sw.js', paths: { - output: path.resolve(__dirname, 'web/'), + output: path.resolve(__dirname, 'dist/'), }, id: 'magento-venia' }) @@ -56,7 +56,7 @@ they need to proxy backend requests to the backing store in a customized way. PWADevServer` handles all these needs: -- Creates and caches a custom local hostname for the current theme +- Creates and caches a custom local hostname for the current project - Adds the custom local hostname to `/etc/hosts` 🔐 - Creates and caches an SSL certificate for the custom local hostname - Adds the certificate to the OS-level keychain so browsers trust it 🔐 @@ -79,19 +79,17 @@ configuration. #### `options` -- `id: string`: **Required.** A unique ID for this project. Theme name is +- `id: string`: **Required.** A unique ID for this project. Project name is recommended, but you can use any domain-name-safe string. If you're - developing several copies of a theme simultaneously, you can use this ID to + developing several copies of a project simultaneously, you can use this ID to distinguish them in the internal tooling; for example, this id will be used to create your dev domain name. -- `publicPath: string`: **Required.** The public path of theme assets in the - backend server, e.g. `'/pub/static/frontend/Vendor/themename/en_US'`. -- `backendDomain: string`: **Required.** The URL of the backing store. -- `paths: object`: **Required.** Local absolute paths to theme folders. +- `publicPath: string`: **Required.** The public path of project assets in the + backend server, e.g. `'/'`: **Required.** The URL of the backing store. +- `paths: object`: **Required.** Local absolute paths to project folders. - `output`: Directory for built JavaScript files. - - `assets`: Directory for other public static assets. - `serviceWorkerFileName: string`: **Required.** The name of the ServiceWorker - file this theme creates, e.g. `'sw.js'`. + file this project generates, e.g. `'sw.js'`. - `changeOrigin: boolean`: ⚠️ **(experimental)** Try to parse any HTML responses from the proxied Magento backend, and replace its domain name with the dev server domain name. Default `false`. diff --git a/packages/pwa-buildpack/docs/ServiceWorkerPlugin.md b/packages/pwa-buildpack/docs/ServiceWorkerPlugin.md index 30b34b61e0a..dc0037cba0f 100644 --- a/packages/pwa-buildpack/docs/ServiceWorkerPlugin.md +++ b/packages/pwa-buildpack/docs/ServiceWorkerPlugin.md @@ -60,7 +60,7 @@ Plugin constructor for the `ServiceWorkerPlugin` class. Must be either `'development'` or `'production'`. `paths: Object` **(Required)** -The local absolute paths to theme folders. +The local absolute paths to project folders. - `paths.output: String` @@ -71,7 +71,7 @@ When `true`, hot reloading is enabled and the ServiceWorker is active in the doc When `false`, the ServiceWorker is disabled to prevent cache interruptions when hot reloading assets. `serviceWorkerFileName: String` **(Required)** -The name of the ServiceWorker file this theme creates. +The name of the ServiceWorker file this project creates. Example: `'sw.js'` `runtimeCacheAssetPath: String` diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index 1974c11ebe2..6d4f651e279 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -36,20 +36,27 @@ "@magento/devcert": "^0.7.0", "@magento/directive-parser": "^0.1.1", "ajv": "^6.1.1", + "apollo-boost": "^0.1.15", "babel-helper-module-imports": "^7.0.0-beta.3", "babel-plugin-syntax-dynamic-import": "^6.18.0", "boxen": "^1.3.0", "chalk": "^2.4.1", + "cssnano": "^4.1.0", "debug": "^3.1.0", + "debug-error-middleware": "^1.3.0", "express": "^4.16.2", "flat-file-db": "^1.0.0", + "graphql": "^14.0.2", + "graphql-tag": "^2.9.2", "harmon": "^1.3.2", "hostile": "^1.3.1", "http-proxy-middleware": "^0.18.0", "lodash.get": "^4.4.2", + "node-fetch": "^2.2.0", "one-time": "^0.0.4", "openport": "0.0.5", "post-compile-webpack-plugin": "^0.1.2", + "react-dom": "^16.5.0", "through": "^2.3.8", "webpack-sources": "^1.1.0", "workbox-webpack-plugin": "^3.0.0-beta.1", diff --git a/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js b/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js new file mode 100644 index 00000000000..4822c35123c --- /dev/null +++ b/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js @@ -0,0 +1,221 @@ +jest.mock('../../util/promisified/child_process'); +jest.mock('../../util/run-as-root'); +jest.mock('../../util/global-config'); +jest.mock('../../util/check-loopback'); + +const { exec } = require('../../util/promisified/child_process'); +const runAsRoot = require('../../util/run-as-root'); +const GlobalConfig = require('../../util/global-config'); +const checkLoopback = require('../../util/check-loopback'); + +const pkgLocTest = process.cwd() + '/package.json'; +const pkg = jest.fn(); +jest.doMock(pkgLocTest, pkg, { virtual: true }); +let setupDomain; + +const simulate = { + loopsBack() { + checkLoopback.mockImplementationOnce(domains => new Set(domains)); + return simulate; + }, + certExists(pair = { key: 'fake', cert: 'fake' }) { + setupDomain.userCerts.get.mockResolvedValueOnce(pair); + return simulate; + }, + certCreated(pair = { key: 'fake', cert: 'fake' }) { + runAsRoot.mockResolvedValueOnce(JSON.stringify([pair])); + return simulate; + }, + noPackageFound() { + jest.resetModuleRegistry(); + pkg.mockImplementationOnce(() => { + const error = new Error(process.cwd() + '/package.json not found'); + error.code = error.errno = 'ENOTFOUND'; + throw error; + }); + return simulate; + }, + packageNameIs(name) { + jest.resetModuleRegistry(); + pkg.mockImplementationOnce(() => ({ name })); + return simulate; + } +}; + +beforeAll(() => { + GlobalConfig.mockImplementation(({ key }) => ({ + set: jest.fn((...args) => { + const keyParts = args.slice(0, -1); + expect(typeof key(...keyParts)).toBe('string'); + }), + get: jest.fn(), + values: jest.fn(), + del: jest.fn() + })); + exec.mockResolvedValue(''); + checkLoopback.mockResolvedValue(new Set()); + ({ setupDomain } = require('../')); +}); +afterAll(() => GlobalConfig.mockRestore()); + +test('produces a secure domain and ssl cert from default name', async () => { + jest.spyOn(console, 'warn').mockImplementation(); + simulate.noPackageFound().certCreated({ + cert: 'fakeCert', + key: 'fakeKey' + }); + const { hostname, certPair } = await setupDomain(); + expect(hostname).toMatch( + new RegExp( + `${setupDomain.DEFAULT_NAME}\\-\\w{4,5}\\.${ + setupDomain.DEV_DOMAIN + }$` + ) + ); + expect(certPair).toMatchObject({ + cert: 'fakeCert', + key: 'fakeKey' + }); + expect(console.warn.mock.calls[0]).toMatchObject([ + expect.stringContaining('Could not autodetect'), + expect.any(Error) + ]); + expect(runAsRoot).toHaveBeenCalledTimes(1); + expect(runAsRoot).toHaveBeenCalledWith( + expect.stringMatching(/./), + expect.any(Function), + expect.arrayContaining([hostname]), + expect.arrayContaining([hostname]) + ); + console.warn.mockRestore(); +}); + +test('produces a secure domain with default name if package name is unusable', async () => { + jest.spyOn(console, 'warn').mockImplementation(); + simulate + .packageNameIs(undefined) + .loopsBack() + .certCreated(); + const { hostname } = await setupDomain(); + expect(hostname).toMatch( + new RegExp( + `${setupDomain.DEFAULT_NAME}\\-\\w{4,5}\\.${ + setupDomain.DEV_DOMAIN + }$` + ) + ); + + expect(console.warn.mock.calls[0]).toMatchObject([ + expect.stringContaining('Could not autodetect'), + expect.any(Error) + ]); + + console.warn.mockRestore(); +}); + +test('produces a secure domain from package name', async () => { + jest.spyOn(console, 'warn').mockImplementation(); + simulate + .packageNameIs('package-name-yay') + .loopsBack() + .certCreated(); + const { hostname } = await setupDomain(); + expect(hostname).toMatch( + new RegExp(`package-name-yay-\\w{4,5}\\.${setupDomain.DEV_DOMAIN}$`) + ); +}); + +test('produces a secure domain from custom name', async () => { + simulate + .packageNameIs('package-name-yay') + .loopsBack() + .certCreated(); + const { hostname } = await setupDomain('custom-912'); + expect(hostname).toMatch( + new RegExp(`custom-912-\\w{4,5}\\.${setupDomain.DEV_DOMAIN}$`) + ); +}); + +test('produces a secure domain without unique autogen', async () => { + simulate.loopsBack().certCreated(); + const { hostname } = await setupDomain('custom-823', { unique: false }); + expect(hostname).toMatch( + new RegExp(`custom-823\\.${setupDomain.DEV_DOMAIN}$`) + ); +}); + +test('produces an unsecure domain', async () => { + simulate.loopsBack(); + const { certPair } = await setupDomain('custom-823', { secure: false }); + expect(certPair).toBeFalsy(); + expect(setupDomain.userCerts.get).not.toHaveBeenCalled(); +}); + +test('returns an already-set-up secure domain', async () => { + simulate.loopsBack().certExists({ + key: 'no', + cert: 'diggity' + }); + const { certPair } = await setupDomain('custom-823', { unique: false }); + expect(certPair).toMatchObject({ + key: 'no', + cert: 'diggity' + }); + expect(runAsRoot).not.toHaveBeenCalled(); +}); + +test('refreshes an expired cert', async () => { + exec.mockRejectedValueOnce({ stdout: 'Certificate will expire' }); + simulate + .loopsBack() + .certExists({ + key: 'no', + cert: 'diggity' + }) + .certCreated({ + key: 'yes', + cert: 'diggity' + }); + const { certPair } = await setupDomain('custom-823', { unique: false }); + expect(certPair).toMatchObject({ + key: 'yes', + cert: 'diggity' + }); +}); + +test('passes errors from denied root or bad parse', async () => { + runAsRoot.mockRejectedValueOnce(new Error('Denied!')); + await expect(setupDomain('blurg')).rejects.toThrowError('Denied!'); +}); + +test('does a dry run to indicate readiness', async () => { + simulate.loopsBack().certExists(); + expect(await setupDomain('woo', { dryRun: true })).toMatchObject({ + makeCerts: [], + setLoopbacks: [], + ready: true + }); + + simulate.loopsBack(); + expect(await setupDomain('woo', { dryRun: true })).toMatchObject({ + makeCerts: [expect.stringContaining('woo')], + setLoopbacks: [], + ready: false + }); + + simulate.certExists(); + expect(await setupDomain('woo', { dryRun: true })).toMatchObject({ + makeCerts: [], + setLoopbacks: [expect.stringContaining('woo')], + ready: false + }); + + simulate.loopsBack(); + expect( + await setupDomain('woo', { dryRun: true, secure: false }) + ).toMatchObject({ + makeCerts: [], + setLoopbacks: [], + ready: true + }); +}); diff --git a/packages/pwa-buildpack/src/Utilities/index.js b/packages/pwa-buildpack/src/Utilities/index.js new file mode 100644 index 00000000000..a4a018fb7d4 --- /dev/null +++ b/packages/pwa-buildpack/src/Utilities/index.js @@ -0,0 +1,3 @@ +module.exports = { + setupDomain: require('./setupDomain') +}; diff --git a/packages/pwa-buildpack/src/Utilities/setupDomain.js b/packages/pwa-buildpack/src/Utilities/setupDomain.js new file mode 100644 index 00000000000..68ea02cc109 --- /dev/null +++ b/packages/pwa-buildpack/src/Utilities/setupDomain.js @@ -0,0 +1,148 @@ +const debug = require('../util/debug').makeFileLogger(__filename); +const GlobalConfig = require('../util/global-config'); +const { exec } = require('../util/promisified/child_process'); +const { join } = require('path'); +const { createHash } = require('crypto'); +const checkLoopback = require('../util/check-loopback'); +const runAsRoot = require('../util/run-as-root'); + +const DEFAULT_NAME = 'my-pwa'; +const DEV_DOMAIN = 'local.pwadev'; + +const userCerts = new GlobalConfig({ + prefix: 'devcert', + key: x => x +}); + +function certIsExpired(cert) { + return exec(`openssl x509 -checkend 0 <<< "${cert}"`) + .then(() => false) + .catch(({ stdout }) => stdout.trim() === 'Certificate will expire'); +} + +async function getCert(commonName) { + let certPair = await userCerts.get(commonName); + if (certPair && (await certIsExpired(certPair.cert))) { + certPair = null; + await userCerts.del(commonName); + } + return certPair || null; +} + +function getUniqueSubdomain(customName) { + let name = DEFAULT_NAME; + if (typeof customName === 'string') { + name = customName; + } else { + const pkgLoc = join(process.cwd(), 'package.json'); + try { + // eslint-disable-next-line node/no-missing-require + const pkg = require(pkgLoc); + if (!pkg.name || typeof pkg.name !== 'string') { + throw new Error( + `package.json does not have a usable "name" field!` + ); + } + name = pkg.name; + } catch (e) { + console.warn( + debug.errorMsg( + `getUniqueSubdomain(): Using default "${name}" prefix. Could not autodetect project name from package.json: ` + ), + e + ); + } + } + const dirHash = createHash('md4'); + // Using a hash of the current directory is a natural way of preserving + // the same "unique" ID for each project, and changing it only when its + // location on disk has changed. + dirHash.update(process.cwd()); + const digest = dirHash.digest('base64'); + // Base64 truncated to 5 characters, stripped of special characters, + // and lowercased to be a valid domain, is about 36^5 unique values. + // There is therefore a chance of a duplicate ID and host collision, + // specifically a 1 in 60466176 chance. + return `${name}-${digest.slice(0, 5)}` + .toLowerCase() + .replace(/[^a-zA-Z0-9]/g, '-') + .replace(/^-+/, ''); +} + +/* istanbul ignore next: runs in sub-process */ +const sudoTask = async (setLoopbacks, makeCerts) => { + if (setLoopbacks.length > 0) { + var hostile = require('hostile'); + setLoopbacks.forEach(name => hostile.set('127.0.0.1', name)); + } + if (makeCerts.length > 0) { + const devcert = require('@magento/devcert'); + const certs = Promise.all(makeCerts.map(name => devcert(name))); + process.stdout.write(JSON.stringify(certs)); + } +}; + +const defaultOpts = { + secure: true, + unique: true, + dryRun: false +}; +async function setupDomain(customName, opts) { + const { secure, unique, dryRun } = Object.assign({}, defaultOpts, opts); + const setLoopbacks = []; + const makeCerts = []; + const subdomain = unique ? getUniqueSubdomain(customName) : customName; + const hostname = subdomain + '.' + DEV_DOMAIN; + const loopbacks = await checkLoopback([hostname]); + if (!loopbacks.has(hostname)) { + setLoopbacks.push(hostname); + } + let certPair; + if (secure) { + certPair = await getCert(hostname); + if (!certPair) { + makeCerts.push(hostname); + } + } + + const ready = setLoopbacks.length === 0 && makeCerts.length === 0; + if (dryRun) { + return { + setLoopbacks, + makeCerts, + ready + }; + } + if (!ready) { + try { + const output = await runAsRoot( + 'Creating a local development domain requires temporary administrative privileges.\n Enter password for %u on %H: ', + sudoTask, + setLoopbacks, + makeCerts + ); + if (secure && !certPair) { + certPair = JSON.parse(output)[0]; + } + } catch (e) { + throw Error( + debug.errorMsg( + `Error setting up development domain: ${e.message} ${ + e.stack + }` + ) + ); + } + } + return { + hostname, + certPair + }; +} + +setupDomain.userCerts = userCerts; +setupDomain.getUniqueSubdomain = getUniqueSubdomain; +setupDomain.DEFAULT_NAME = DEFAULT_NAME; +setupDomain.DEV_DOMAIN = DEV_DOMAIN; + +module.exports = setupDomain; diff --git a/packages/pwa-buildpack/src/WebpackTools/PWADevServer.js b/packages/pwa-buildpack/src/WebpackTools/PWADevServer.js index e2f252d3f13..3487fca18da 100644 --- a/packages/pwa-buildpack/src/WebpackTools/PWADevServer.js +++ b/packages/pwa-buildpack/src/WebpackTools/PWADevServer.js @@ -1,68 +1,26 @@ const debug = require('../util/debug').makeFileLogger(__filename); -const { join } = require('path'); -const { createHash } = require('crypto'); +const debugErrorMiddleware = require('debug-error-middleware').express; const url = require('url'); -const express = require('express'); const GlobalConfig = require('../util/global-config'); -const SSLCertStore = require('../util/ssl-cert-store'); const optionsValidator = require('../util/options-validator'); -const middlewares = { - originSubstitution: require('./middlewares/OriginSubstitution'), - devProxy: require('./middlewares/DevProxy'), - staticRootRoute: require('./middlewares/StaticRootRoute') -}; -const { lookup } = require('../util/promisified/dns'); +const setupDomain = require('../Utilities/setupDomain'); const { find: findPort } = require('../util/promisified/openport'); -const runAsRoot = require('../util/run-as-root'); const PWADevServer = { - DEFAULT_NAME: 'my-pwa', - DEV_DOMAIN: 'local.pwadev', validateConfig: optionsValidator('PWADevServer', { publicPath: 'string', backendDomain: 'string', - 'paths.output': 'string', - serviceWorkerFileName: 'string' + 'paths.output': 'string' }), portsByHostname: new GlobalConfig({ prefix: 'devport-byhostname', key: x => x }), - async setLoopback(hostname) { - debug(`checking if ${hostname} is loopback`); - let ip; - try { - ip = await lookup(hostname); - } catch (e) { - if (e.code !== 'ENOTFOUND') { - throw Error( - debug.errorMsg( - `Error trying to check that ${hostname} is loopback: ${ - e.message - }` - ) - ); - } - } - if (ip && (ip.address === '127.0.0.1' || ip.address === '::1')) { - debug(`${hostname} already resolves to ${ip.address}!`); - } else { - debug( - `setting ${hostname} loopback in /etc/hosts, may require password...` - ); - return runAsRoot( - `Resolving ${hostname} to localhost and editing the hostfile requires temporary administrative privileges.\n Enter password for %u on %H: `, - /* istanbul ignore next: never runs in process */ - d => require('hostile').set('127.0.0.1', d), - hostname - ); - } - }, async findFreePort() { const reserved = await PWADevServer.portsByHostname.values(Number); debug(`findFreePort(): these ports already reserved`, reserved); return findPort({ startingPort: 8000, - endingPort: 9999, + endingPort: 8999, avoid: reserved }).catch(e => { throw Error( @@ -72,55 +30,7 @@ const PWADevServer = { ); }); }, - getUniqueSubdomain(customName) { - let name = PWADevServer.DEFAULT_NAME; - if (typeof customName === 'string') { - name = customName; - } else { - const pkgLoc = join(process.cwd(), 'package.json'); - try { - // eslint-disable-next-line node/no-missing-require - const pkg = require(pkgLoc); - if (!pkg.name || typeof pkg.name !== 'string') { - throw new Error( - `package.json does not have a usable "name" field!` - ); - } - name = pkg.name; - } catch (e) { - console.warn( - debug.errorMsg( - `getUniqueSubdomain(): Using default "${name}" prefix. Could not autodetect theme name from package.json: ` - ), - e - ); - } - } - const dirHash = createHash('md4'); - // Using a hash of the current directory is a natural way of preserving - // the same "unique" ID for each project, and changing it only when its - // location on disk has changed. - dirHash.update(process.cwd()); - const digest = dirHash.digest('base64'); - // Base64 truncated to 5 characters, stripped of special characters, - // and lowercased to be a valid domain, is about 36^5 unique values. - // There is therefore a chance of a duplicate ID and host collision, - // specifically a 1 in 60466176 chance. - return `${name}-${digest.slice(0, 5)}` - .toLowerCase() - .replace(/[^a-zA-Z0-9]/g, '-') - .replace(/^-+/, ''); - }, - async provideUniqueHost(prefix) { - debug(`provideUniqueHost ${prefix}`); - return PWADevServer.provideCustomHost( - PWADevServer.getUniqueSubdomain(prefix) - ); - }, - async provideCustomHost(subdomain) { - debug(`provideUniqueHost ${subdomain}`); - const hostname = subdomain + '.' + PWADevServer.DEV_DOMAIN; - + async getPersistentDevPort(hostname) { const [usualPort, freePort] = await Promise.all([ PWADevServer.portsByHostname.get(hostname), PWADevServer.findFreePort() @@ -137,13 +47,7 @@ const PWADevServer = { ); } - PWADevServer.setLoopback(hostname); - - return { - protocol: 'https:', - hostname, - port - }; + return port; }, async configure(config) { debug('configure() invoked', config); @@ -152,7 +56,7 @@ const PWADevServer = { contentBase: false, compress: true, hot: true, - host: 'localhost', + host: '0.0.0.0', stats: { all: false, builtAt: true, @@ -164,59 +68,44 @@ const PWADevServer = { version: true, warnings: true }, - before(app) { - if (config.changeOrigin) { - // replace origins in links in returned html - app.use( - middlewares.originSubstitution( - new url.URL(config.backendDomain), - { - hostname: devServerConfig.host, - port: devServerConfig.port - } - ) - ); - } - // serviceworker root route - app.use( - middlewares.staticRootRoute( - join(config.paths.output, config.serviceWorkerFileName) - ) - ); - }, after(app) { - // set static server to load and serve from different paths - app.use(config.publicPath, express.static(config.paths.output)); - - // proxy to backend - app.use( - middlewares.devProxy({ - target: config.backendDomain - }) - ); + app.use(debugErrorMiddleware()); } }; - let devHost; - if (config.id) { - devHost = await PWADevServer.provideCustomHost(config.id); - } else if (config.provideUniqueHost) { - devHost = await PWADevServer.provideUniqueHost( - config.provideUniqueHost + const { id, provideUniqueHost, provideSSLCert } = config; + let uniqueName; + if (id || provideUniqueHost) { + const domainCustomName = + id || + (typeof provideUniqueHost === 'string' + ? provideUniqueHost + : null); + const domainSetupConfig = { + secure: provideSSLCert, + unique: !id + }; + const { hostname, certPair } = await setupDomain( + domainCustomName, + domainSetupConfig ); - } - if (devHost) { - devServerConfig.host = devHost.hostname; - devServerConfig.port = devHost.port; + uniqueName = devServerConfig.host = hostname; + devServerConfig.https = certPair; + // workaround for https://github.com/webpack/webpack-dev-server/issues/1491 + if (devServerConfig.https) { + devServerConfig.https.spdy = { + protocols: ['http/1.1'] + }; + } } else { - devServerConfig.port = await PWADevServer.findFreePort(); - } - if (config.provideSSLCert) { - devServerConfig.https = await SSLCertStore.provide( - devServerConfig.host - ); + uniqueName = setupDomain.getUniqueSubdomain(); } + + devServerConfig.port = await PWADevServer.getPersistentDevPort( + uniqueName + ); + devServerConfig.publicPath = url.format({ - protocol: config.provideSSLCert ? 'https:' : 'http:', + protocol: provideSSLCert ? 'https:' : 'http:', hostname: devServerConfig.host, port: devServerConfig.port, pathname: config.publicPath diff --git a/packages/pwa-buildpack/src/WebpackTools/__tests__/PWADevServer.spec.js b/packages/pwa-buildpack/src/WebpackTools/__tests__/PWADevServer.spec.js index e9356cd5d44..f4f1c56f31f 100644 --- a/packages/pwa-buildpack/src/WebpackTools/__tests__/PWADevServer.spec.js +++ b/packages/pwa-buildpack/src/WebpackTools/__tests__/PWADevServer.spec.js @@ -1,34 +1,21 @@ jest.mock('../../util/promisified/dns'); jest.mock('../../util/promisified/openport'); jest.mock('../../util/global-config'); -jest.mock('../../util/ssl-cert-store'); jest.mock('../../util/run-as-root'); -jest.mock('../middlewares/DevProxy'); -jest.mock('../middlewares/OriginSubstitution'); -jest.mock('../middlewares/StaticRootRoute'); const { lookup } = require('../../util/promisified/dns'); const openport = require('../../util/promisified/openport'); -const runAsRoot = require('../../util/run-as-root'); const GlobalConfig = require('../../util/global-config'); -const SSLCertStore = require('../../util/ssl-cert-store'); -const middlewares = { - DevProxy: require('../middlewares/DevProxy'), - OriginSubstitution: require('../middlewares/OriginSubstitution'), - StaticRootRoute: require('../middlewares/StaticRootRoute') -}; -// Mocking a variable path requires the `.doMock` -const pkgLocTest = process.cwd() + '/package.json'; -const pkg = jest.fn(); -jest.doMock(pkgLocTest, pkg, { virtual: true }); let PWADevServer; +let setupDomain; beforeAll(() => { GlobalConfig.mockImplementation(({ key }) => ({ set: jest.fn(key), get: jest.fn(), values: jest.fn() })); + setupDomain = require('../../Utilities/setupDomain'); PWADevServer = require('../').PWADevServer; }); @@ -61,52 +48,10 @@ const simulate = { return simulate; }, certExistsForNextHostname(pair) { - SSLCertStore.provide.mockResolvedValueOnce(pair); - }, - noPackageFound() { - jest.resetModuleRegistry(); - pkg.mockImplementationOnce(() => { - const error = new Error(process.cwd() + '/package.json not found'); - error.code = error.errno = 'ENOTFOUND'; - throw error; - }); - return simulate; - }, - packageNameIs(name) { - jest.resetModuleRegistry(); - pkg.mockImplementationOnce(() => ({ name })); - return simulate; + setupDomain.userCerts.get.mockResolvedValueOnce(pair); } }; -test('.setLoopback() checks if hostname resolves local, ipv4 or 6', async () => { - simulate.hostResolvesLoopback(); - await PWADevServer.setLoopback('excelsior.com'); - expect(lookup).toHaveBeenCalledWith('excelsior.com'); - expect(runAsRoot).not.toHaveBeenCalled(); - - simulate.hostResolvesLoopback({ family: 6 }); - await PWADevServer.setLoopback('excelsior.com'); - expect(runAsRoot).not.toHaveBeenCalled(); -}); - -test('.setLoopback() updates /etc/hosts to make hostname local', async () => { - lookup.mockRejectedValueOnce({ code: 'ENOTFOUND' }); - await PWADevServer.setLoopback('excelsior.com'); - expect(runAsRoot).toHaveBeenCalledWith( - expect.any(String), - expect.any(Function), - 'excelsior.com' - ); -}); - -test('.setLoopback() dies under mysterious circumstances', async () => { - lookup.mockRejectedValueOnce({ code: 'UNKNOWN' }); - await expect(PWADevServer.setLoopback('excelsior.com')).rejects.toThrow( - 'Error trying to check' - ); -}); - test('.findFreePort() uses openPort to get a free port', async () => { simulate.savedPortsAre(8543, 9002, 8765).aFreePortWasFound(); @@ -126,94 +71,6 @@ test('.findFreePort() passes formatted errors from port lookup', async () => { ); }); -test('.getUniqueSubdomain() makes a new hostname for an identifier', async () => { - const hostname = await PWADevServer.getUniqueSubdomain('bar'); - expect(hostname).toMatch(/bar\-(\w){4,5}/); -}); - -test('.getUniqueSubdomain() makes a new hostname from the local package name', async () => { - simulate.packageNameIs('lorax'); - - const hostname = await PWADevServer.getUniqueSubdomain(); - expect(hostname).toMatch(/lorax\-(\w){4,5}/); -}); - -test('.getUniqueSubdomain() logs a warning if it cannot determine a name', async () => { - jest.spyOn(console, 'warn').mockImplementation(); - simulate.packageNameIs(undefined); - - const hostname = await PWADevServer.getUniqueSubdomain(); - expect(hostname).toMatch(/my\-pwa\-(\w){4,5}/); - expect(console.warn).toHaveBeenCalledWith( - expect.stringMatching('Could not autodetect'), - expect.any(Error) - ); - expect(console.warn.mock.calls[0][1].message).toMatchSnapshot(); - - // and even if package cannot be found: - simulate.noPackageFound(); - await PWADevServer.getUniqueSubdomain(); - expect(console.warn).toHaveBeenLastCalledWith( - expect.stringMatching('Could not autodetect'), - expect.any(Error) - ); - expect(console.warn.mock.calls[1][1].code).toBe('ENOTFOUND'); - console.warn.mockRestore(); -}); - -test('.provideUniqueHost() returns a URL object with a free dev host origin and stores a port', async () => { - simulate - .noPortSavedForNextHostname() - .aFreePortWasFound(8765) - .hostDoesNotResolve(); - - const { protocol, hostname, port } = await PWADevServer.provideUniqueHost( - 'woah' - ); - - expect(protocol).toBe('https:'); - expect(hostname).toMatch(/woah\-(\w){4,5}\.local\.pwadev/); - expect(port).toBe(8765); - - expect(PWADevServer.portsByHostname.get).toHaveBeenCalledWith(hostname); - expect(PWADevServer.portsByHostname.set).toHaveBeenCalledWith( - hostname, - port - ); -}); - -test('.provideUniqueHost() returns a cached port for the hostname', async () => { - const warn = jest.spyOn(console, 'warn').mockImplementation(); - simulate - .portSavedForNextHostname(8000) - .aFreePortWasFound(8776) - .hostResolvesLoopback(); - - const { port } = await PWADevServer.provideUniqueHost('woah'); - - expect(port).toBe(8776); - expect(console.warn).toHaveBeenCalledWith( - expect.stringMatching( - 'port 8000 is in use. The dev server will instead run' - ) - ); - warn.mockRestore(); -}); - -test('.provideUniqueHost() warns about reserved port conflict', async () => { - const warn = jest.spyOn(console, 'warn').mockImplementation(); - simulate - .portSavedForNextHostname(8888) - .aFreePortWasFound(8889) - .hostResolvesLoopback(); - - const { port } = await PWADevServer.provideUniqueHost('woah'); - - expect(port).toBe(8889); - - warn.mockRestore(); -}); - test('.configure() throws errors on missing config', async () => { await expect(PWADevServer.configure({ id: 'foo' })).rejects.toThrow( 'publicPath must be of type string' @@ -237,14 +94,6 @@ test('.configure() throws errors on missing config', async () => { paths: { output: 1234 } }) ).rejects.toThrow('paths.output must be of type string'); - await expect( - PWADevServer.configure({ - id: 'foo', - publicPath: 'bar', - backendDomain: 'https://dumb.domain', - paths: { output: 'foo' } - }) - ).rejects.toThrow('serviceWorkerFileName must be of type string'); }); test('.configure() gets or creates an SSL cert if `provideSSLCert: true`', async () => { @@ -263,9 +112,9 @@ test('.configure() gets or creates an SSL cert if `provideSSLCert: true`', async publicPath: 'bork', serviceWorkerFileName: 'doin', backendDomain: 'growe', + id: 'flowk', provideSSLCert: true }); - expect(SSLCertStore.provide).toHaveBeenCalled(); expect(server.https).toHaveProperty('cert', 'fakeCert'); }); @@ -312,7 +161,11 @@ test('.configure() is backwards compatible with `id` param', async () => { simulate .portSavedForNextHostname(8765) .aFreePortWasFound(8765) - .hostResolvesLoopback(); + .hostResolvesLoopback() + .certExistsForNextHostname({ + key: 'fakeKey2', + cert: 'fakeCert2' + }); const config = { id: 'samiam', @@ -385,12 +238,18 @@ test('.configure() `id` param overrides `provideUniqueHost` param', async () => }); }); -test('.configure() returns a configuration object with before() and after() handlers that add middlewares in order', async () => { - simulate.aFreePortWasFound(); +test('debugErrorMiddleware attached', async () => { + simulate + .portSavedForNextHostname(8765) + .aFreePortWasFound(8765) + .hostResolvesLoopback(); const config = { + id: 'samiam', + provideUniqueHost: 'samiam', paths: { - output: 'path/to/static' + output: 'path/to/static', + assets: 'path/to/assets' }, publicPath: 'full/path/to/publicPath', serviceWorkerFileName: 'swname.js', @@ -399,77 +258,10 @@ test('.configure() returns a configuration object with before() and after() hand const devServer = await PWADevServer.configure(config); + expect(devServer.after).toBeInstanceOf(Function); const app = { use: jest.fn() }; - - middlewares.StaticRootRoute.mockReturnValueOnce('fakeStaticRootRoute'); - - devServer.before(app); - - middlewares.DevProxy.mockReturnValueOnce('fakeDevProxy'); - devServer.after(app); - - expect(middlewares.DevProxy).toHaveBeenCalledWith( - expect.objectContaining({ - target: 'https://magento.backend.domain' - }) - ); - - expect(middlewares.OriginSubstitution).not.toHaveBeenCalled(); - - expect(app.use).toHaveBeenCalledWith('fakeDevProxy'); - - expect(middlewares.StaticRootRoute).toHaveBeenCalledWith( - 'path/to/static/swname.js' - ); - - expect(app.use).toHaveBeenCalledWith('fakeStaticRootRoute'); - - expect(app.use).toHaveBeenCalledWith( - 'full/path/to/publicPath', - expect.any(Function) - ); -}); - -test('.configure() optionally adds OriginSubstitution middleware', async () => { - simulate.aFreePortWasFound(8002); - - const config = { - paths: { - output: 'path/to/static' - }, - publicPath: 'full/path/to/publicPath', - serviceWorkerFileName: 'swname.js', - backendDomain: 'https://magento.backend.domain', - changeOrigin: true - }; - - const devServer = await PWADevServer.configure(config); - - const app = { - use: jest.fn() - }; - - middlewares.OriginSubstitution.mockReturnValueOnce( - 'fakeOriginSubstitution' - ); - middlewares.DevProxy.mockReturnValueOnce('fakeDevProxy'); - middlewares.StaticRootRoute.mockReturnValueOnce('fakeStaticRootRoute'); - - devServer.before(app); - - expect(middlewares.OriginSubstitution).toHaveBeenCalledWith( - expect.objectContaining({ - protocol: 'https:', - hostname: 'magento.backend.domain' - }), - expect.objectContaining({ - hostname: 'localhost', - port: 8002 - }) - ); - - expect(app.use).toHaveBeenCalledWith('fakeOriginSubstitution'); + expect(app.use).toHaveBeenCalledWith(expect.any(Function)); }); diff --git a/packages/pwa-buildpack/src/WebpackTools/__tests__/__snapshots__/PWADevServer.spec.js.snap b/packages/pwa-buildpack/src/WebpackTools/__tests__/__snapshots__/PWADevServer.spec.js.snap deleted file mode 100644 index b7bcf31a478..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/__tests__/__snapshots__/PWADevServer.spec.js.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`.getUniqueSubdomain() logs a warning if it cannot determine a name 1`] = `"package.json does not have a usable \\"name\\" field!"`; diff --git a/packages/pwa-buildpack/src/WebpackTools/index.js b/packages/pwa-buildpack/src/WebpackTools/index.js index 227b3853961..bfb867498c8 100644 --- a/packages/pwa-buildpack/src/WebpackTools/index.js +++ b/packages/pwa-buildpack/src/WebpackTools/index.js @@ -3,5 +3,6 @@ module.exports = { ServiceWorkerPlugin: require('./plugins/ServiceWorkerPlugin'), DevServerReadyNotifierPlugin: require('./plugins/DevServerReadyNotifierPlugin'), MagentoResolver: require('./MagentoResolver'), - PWADevServer: require('./PWADevServer') + PWADevServer: require('./PWADevServer'), + UpwardPlugin: require('./plugins/UpwardPlugin') }; diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/DevProxy.js b/packages/pwa-buildpack/src/WebpackTools/middlewares/DevProxy.js deleted file mode 100644 index 0700c5e87a9..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/DevProxy.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Proxies all requests not served by Webpack in-memory bundling back - * to the underlying store. - * - * Tries to detect a case where the target URL is misconfigured and the - * store tries to redirect to http or https. - */ -const proxyMiddleware = require('http-proxy-middleware'); -const optionsValidator = require('../../util/options-validator'); -const { format, URL } = require('url'); - -const RedirectCodes = [201, 301, 302, 307, 308]; -const findRedirect = message => - RedirectCodes.includes(message.statusCode) && message.headers.location; - -const emitErrorOnProtocolChange = (emit, target, redirected) => { - const backend = new URL(target); - const { host, protocol } = new URL(redirected); - if (backend.host === host && backend.protocol === protocol) { - return; - } - - if (backend.protocol === 'https:' && protocol === 'http:') { - return emit( - new Error( - `pwa-buildpack: Backend domain is configured to ${target}, but redirected to unsecure HTTP. Please configure backend server to use SSL.` - ) - ); - } - - if (backend.protocol === 'http:' && protocol === 'https:') { - return emit( - new Error( - `pwa-buildpack: Backend domain is configured to ${target}, but redirected to secure HTTPS. Please change configuration to point to secure backend domain: ${format( - Object.assign(backend, { protocol: 'https:' }) - )}.` - ) - ); - } - - emit( - new Error( - `pwa-buildpack: Backend domain redirected to unknown protocol: ${redirected}` - ) - ); -}; - -const validateConfig = optionsValidator('DevProxyMiddleware', { - target: 'string' -}); - -module.exports = function createDevProxy(config) { - validateConfig('createDevProxy', config); - const proxyConf = Object.assign( - { - logLevel: 'debug', - logProvider: defaultProvider => config.logger || defaultProvider, - onProxyRes(proxyRes) { - const redirected = findRedirect(proxyRes); - if (redirected) { - emitErrorOnProtocolChange( - nextCallback, - config.target, - redirected - ); - } - }, - secure: false, - changeOrigin: true, - autoRewrite: true, - cookieDomainRewrite: '' // remove any absolute domain on cookies - }, - config - ); - let nextCallback; - const proxy = proxyMiddleware('**', proxyConf); - // Return an outer middleware so we can access the `next` function to - // properly pass errors along. - return (req, res, next) => { - nextCallback = err => { - proxyConf.logProvider(console).error(err); - return next(err); - }; - return proxy(req, res, next); - }; -}; diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/OriginSubstitution.js b/packages/pwa-buildpack/src/WebpackTools/middlewares/OriginSubstitution.js deleted file mode 100644 index 5d0377114b5..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/OriginSubstitution.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Replace all instances of one URL base in an HTML response, with another. - * Useful for proxying to systems like Magento, which often generate absolute - * URLs in their render output. - * - * Rather than configure Magento to use the your temporary dev server URL as - * its configured base domain, this middleware allows the dev server to text - * replace any links, resources, or reference URLs on the fly. - * - * For Magento 2 specifically, This is a stopgap until we can hack Framework to - * have branch logic in asset URL resolvers. - * - * EXPERIMENTAL -- not ready for prime time - */ -const debug = require('../../util/debug').makeFileLogger(__filename); -const url = require('url'); -const harmon = require('harmon'); -const through = require('through'); -const removeTrailingSlash = x => x.replace(/\/$/, ''); -module.exports = function createOriginSubstitutionMiddleware( - oldDomain, - newDomain -) { - const oldOrigin = removeTrailingSlash(url.format(oldDomain)); - const newOrigin = removeTrailingSlash(url.format(newDomain)); - const attributesToReplaceOrigin = ['href', 'src', 'style'].map(attr => ({ - query: `[${attr}*="${oldOrigin}"]`, - func(node) { - node.setAttribute( - attr, - node - .getAttribute(attr) - .split(oldOrigin) - .join(newOrigin) - ); - } - })); - const tagsToReplaceOrigin = ['style'].map(attr => ({ - query: attr, - func(node) { - debug('tag', attr, node); - const stream = node.createStream(); - stream - .pipe( - through(function(buf) { - this.queue( - buf - .toString() - .split(oldOrigin) - .join(newOrigin) - ); - }) - ) - .pipe(stream); - } - })); - debug( - `replace ${oldOrigin} with ${newOrigin} in html`, - attributesToReplaceOrigin - ); - const allTransforms = [ - ...tagsToReplaceOrigin, - ...attributesToReplaceOrigin - ]; - return harmon([], allTransforms, true); -}; diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/StaticRootRoute.js b/packages/pwa-buildpack/src/WebpackTools/middlewares/StaticRootRoute.js deleted file mode 100644 index 441ed006e88..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/StaticRootRoute.js +++ /dev/null @@ -1,11 +0,0 @@ -const { basename } = require('path'); -module.exports = function createStaticRootRoute(filepath) { - const publicPath = '/' + basename(filepath); - return (req, res, next) => { - if (req.method === 'GET' && req.path === publicPath) { - res.sendFile(filepath); - } else { - next(); - } - }; -}; diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/__fixtures__/root-available-file.json b/packages/pwa-buildpack/src/WebpackTools/middlewares/__fixtures__/root-available-file.json deleted file mode 100644 index 2f8d0ebb860..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/__fixtures__/root-available-file.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "goodJsonResponse": true -} diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/DevProxy.spec.js b/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/DevProxy.spec.js deleted file mode 100644 index 2c1b9c7f567..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/DevProxy.spec.js +++ /dev/null @@ -1,149 +0,0 @@ -let devProxy; -const request = require('supertest'); -const nock = require('nock'); -const express = require('express'); - -const TARGET = 'https://proxytarget.test'; -const TARGET_UNSECURE = 'http://proxytarget.test'; -const logger = {}; -const logMethods = ['log', 'debug', 'info', 'warn', 'error']; - -beforeAll(() => { - logMethods.forEach(method => { - logger[method] = jest.fn(); - jest.spyOn(console, method).mockImplementation(); - }); - // We wait to require DevProxy here because DevProxy imports `http-proxy-middleware`, and - // `http-proxy-middleware` creates a "default logger" at module definition time--that is, when - // we require() it. The default logger destructures the console object, so it no longer holds - // a reference to `console` itself. This makes us unable to mock `console` for the - // `http-proxy-middleware` library if it loads before the mock does. - devProxy = require('../DevProxy'); -}); - -beforeEach(() => { - jest.clearAllMocks(); -}); - -afterAll(() => { - logMethods.forEach(method => { - console[method].mockRestore(); - }); - nock.restore(); -}); - -test('logs to custom logger', async () => { - nock(TARGET) - .get('/will-log') - .reply(200, 'Hello world!'); - - const appWithCustomLogger = express(); - appWithCustomLogger.use( - devProxy({ - logger, - target: TARGET - }) - ); - - await request(appWithCustomLogger).get('/will-log'); - - expect(logger.debug).toHaveBeenCalledWith( - expect.stringContaining('will-log') - ); -}); - -test('logs to console by default', async () => { - nock(TARGET) - .get('/will-log') - .reply(200, 'Hello world!'); - const app = express(); - app.use( - devProxy({ - target: TARGET - }) - ); - - await request(app).get('/will-log'); - - expect(console.log).toHaveBeenCalledWith( - expect.stringContaining('will-log') - ); -}); - -test('handles redirects silently when origin is same', async () => { - nock(TARGET) - .get('/will-proxy-to-self') - .reply(301, '', { - Location: TARGET + '/redirected-to' - }); - - const app = express(); - app.use( - devProxy({ - logger, - target: TARGET - }) - ); - - await expect( - request(app) - .get('/will-proxy-to-self') - .expect(301) - .expect('location', /redirected\-to/) - ).resolves.toBeTruthy(); -}); - -test('errors informatively on redirect with protocol change', async () => { - nock(TARGET_UNSECURE) - .get('/will-proxy-to-secure') - .reply(301, '', { - Location: TARGET + '/will-proxy-to-secure' - }); - - const app = express(); - app.use( - devProxy({ - logger, - target: TARGET_UNSECURE - }) - ); - - await expect( - request(app).get('/will-proxy-to-secure') - ).resolves.toMatchObject({ - status: 500, - text: expect.stringContaining('redirected to secure HTTPS') - }); - - nock(TARGET) - .get('/will-proxy-to-unsecure') - .reply(301, '', { - Location: TARGET_UNSECURE + '/will-proxy-to-unsecure' - }) - .get('/will-proxy-to-nowhere') - .reply(302, '', { - Location: 'badprotocol' + TARGET + '/will-proxy-to-nowhere' - }); - - const secureApp = express(); - secureApp.use( - devProxy({ - logger, - target: TARGET - }) - ); - - await expect( - request(secureApp).get('/will-proxy-to-unsecure') - ).resolves.toMatchObject({ - status: 500, - text: expect.stringContaining('redirected to unsecure HTTP') - }); - - await expect( - request(secureApp).get('/will-proxy-to-nowhere') - ).resolves.toMatchObject({ - status: 500, - text: expect.stringContaining('redirected to unknown protocol') - }); -}); diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/OriginSubstitution.spec.js b/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/OriginSubstitution.spec.js deleted file mode 100644 index fbd903831cf..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/OriginSubstitution.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -const { URL } = require('url'); -const request = require('supertest'); -const express = require('express'); - -const originSubstitution = require('../OriginSubstitution'); - -test('swaps origins in html', async () => { - const app = express(); - const backendUrl = new URL('https://old.backend:8080'); - const frontendUrl = new URL('https://cool.frontend:8081'); - app.use(originSubstitution(backendUrl, frontendUrl)); - const htmlWithBaseDomain = base => - ` - - - - - - - - - Home - - - `.trim(); - app.get('/', (req, res) => res.send(htmlWithBaseDomain(backendUrl))); - await expect(request(app).get('/')).resolves.toMatchObject({ - text: htmlWithBaseDomain(frontendUrl) - }); -}); diff --git a/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/StaticRootRoute.spec.js b/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/StaticRootRoute.spec.js deleted file mode 100644 index bef49f2cd90..00000000000 --- a/packages/pwa-buildpack/src/WebpackTools/middlewares/__tests__/StaticRootRoute.spec.js +++ /dev/null @@ -1,30 +0,0 @@ -const { resolve } = require('path'); -const request = require('supertest'); -const express = require('express'); - -const staticRootRoute = require('../StaticRootRoute'); - -test('serves the provided file at root', async () => { - const app = express(); - app.use( - staticRootRoute( - resolve(__dirname, '..', '__fixtures__', 'root-available-file.json') - ) - ); - await expect( - request(app) - .get('/root-available-file.json') - .expect(200) - ).resolves.toMatchObject({ - body: { - goodJsonResponse: true - } - }); - await expect( - request(app) - .get('/some-other-file') - .expect(404) - ).resolves.toMatchObject({ - status: 404 - }); -}); diff --git a/packages/pwa-buildpack/src/WebpackTools/plugins/MagentoRootComponentsPlugin/index.js b/packages/pwa-buildpack/src/WebpackTools/plugins/MagentoRootComponentsPlugin/index.js index c6b049f3eaa..c4379ed2025 100644 --- a/packages/pwa-buildpack/src/WebpackTools/plugins/MagentoRootComponentsPlugin/index.js +++ b/packages/pwa-buildpack/src/WebpackTools/plugins/MagentoRootComponentsPlugin/index.js @@ -1,4 +1,4 @@ -const { isAbsolute, join } = require('path'); +const { isAbsolute, join, extname } = require('path'); const { RawSource } = require('webpack-sources'); const { rootComponentMap, @@ -7,6 +7,8 @@ const { const loaderPath = join(__dirname, 'roots-chunk-loader.js'); +const isJSFile = filename => /^\.jsx?$/.test(extname(filename)); + /** * @description webpack plugin that creates chunks for each * individual RootComponent in a store, and generates a manifest @@ -48,28 +50,31 @@ class MagentoRootComponentsPlugin { moduleByPath.set(mod.resource, mod); } + if (!isJSFile(mod.resource)) { + return; + } // To create a unique chunk for each RootComponent, we want to inject // a dynamic import() for each RootComponent, within each entry point. - // But identifying entry points is hard! - // Top-level modules injected by a downstream "issuer" are not - // entry points. const isEntrySimpleTest = this.phase === 'development' - ? mod => mod.resource.includes('/node_modules/') - : mod => !mod.issuer; + ? // Dependencies are not entry points in development. + mod => mod.resource.includes('/node_modules/') + : // Top-level modules injected by a downstream "issuer" are not + // entry points in production. + mod => !mod.issuer; const isAnEntry = isEntrySimpleTest(mod) && // Otherwise, check if the module being constructed matches a defined entry point compilation.entries.some(entryMod => { + // Check if the module being constructed matches a defined entry point if (mod === entryMod) { return true; } - if (!entryMod.identifier().startsWith('multi')) { - return false; - } + + // If a multi-module entry is used (webpack-dev-server creates one), we // need to try and match against each dependency in the multi module return entryMod.dependencies.some( singleDep => singleDep.module === mod diff --git a/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js b/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js new file mode 100644 index 00000000000..582307d15de --- /dev/null +++ b/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js @@ -0,0 +1,105 @@ +const debug = require('../../util/debug').makeFileLogger(__filename); +const fetch = require('node-fetch'); +const path = require('path'); +const https = require('https'); +const upward = require('@magento/upward-js'); + +// To be used with `node-fetch` in order to allow self-signed certificates. +const agent = new https.Agent({ rejectUnauthorized: false }); + +class UpwardPlugin { + constructor(devServer, upwardPath) { + this.upwardPath = upwardPath; + // Compose `after` function if something else has defined it. + const oldAfter = devServer.after; + devServer.after = app => { + app.use((req, res, next) => this.handleRequest(req, res, next)); + if (oldAfter) oldAfter(app); + }; + } + apply(compiler) { + this.compiler = compiler; + // If a request has run to the devServer before this method has run, + // then there is already a Promise pending for the compiler, and this is + // its resolver. + if (this.resolveCompiler) { + this.resolveCompiler(compiler); + } + } + // Hold the first request (and subsequent requests) until the middleware is + // created, then swap out `handleRequest` for the simplest stack trace. + async handleRequest(req, res, next) { + // Several requests may come in. Only create the middleware once. + if (!this.middlewarePromise) { + this.middlewarePromise = this.createMiddleware(); + } + await this.middlewarePromise; + // When the promise is resolved, `this.middleware` will exist. + // Replace this function itself. + this.handleRequest = this.middleware; + // And then call it to finish the response. + this.middleware(req, res, next); + // Further requests will go straight to the middleware. + } + async createMiddleware() { + // The compiler is necessary to build the fallback filesystem + // so UPWARd can use Webpack-generated assets in dev mode. + const compiler = await this.getCompiler(); + + // Standard filesystem-and-fetch IO. + const defaultIO = upward.IOAdapter.default(this.upwardPath); + + // Use Webpack's in-memory file system for UPWARD file retrieval during + // development. Allows for hot reloading of server-side configuration. + + const io = { + async readFile(filepath, enc) { + const absolutePath = path.resolve(filepath); + + // Most likely scenario: UPWARD needs an output asset. + try { + return compiler.outputFileSystem.readFileSync( + absolutePath, + enc + ); + } catch (e) {} + + // Next most likely scenario: UPWARD needs a file on disk. + try { + const fromDefault = await defaultIO.readFile( + absolutePath, + enc + ); + return fromDefault; + } catch (e) {} + + // Fallback: Use Webpack's resolution rules. + return compiler.inputFileSystem.readFileSync(absolutePath, enc); + }, + + async networkFetch(path, options) { + debug('networkFetch %s, %o', path, options); + // Use the https.Agent to allow self-signed certificates. + return fetch(path, Object.assign({ agent }, options)); + } + }; + + this.middleware = await upward.middleware(this.upwardPath, io); + } + async getCompiler() { + if (this.compiler) { + return this.compiler; + } + if (!this.compilerPromise) { + // Create a promise for the compiler and expose its resolver so it + // can be resolved when the `apply` method runs. + this.compilerPromise = new Promise(resolve => { + this.resolveCompiler = resolve; + }); + } + // Share the compiler promise. + return this.compilerPromise; + } +} + +module.exports = UpwardPlugin; diff --git a/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js b/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js new file mode 100644 index 00000000000..547f1d8c3b6 --- /dev/null +++ b/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js @@ -0,0 +1,218 @@ +jest.mock('node-fetch'); +jest.mock('@magento/upward-js'); +const upward = require('@magento/upward-js'); +const fetch = require('node-fetch'); +const UpwardPlugin = require('../UpwardPlugin'); + +test('creates a devServer.after function if it does not exist', () => { + const devServer = {}; + const app = { + use: jest.fn() + }; + new UpwardPlugin(devServer); + expect(devServer.after).toBeInstanceOf(Function); + devServer.after(app); + expect(app.use).toHaveBeenCalledWith(expect.any(Function)); +}); + +test('composes with an existing devServer.after function', () => { + const after = jest.fn(); + const devServer = { after }; + const app = { + use: jest.fn() + }; + new UpwardPlugin(devServer); + expect(devServer.after).not.toBe(after); + devServer.after(app); + expect(app.use).toHaveBeenCalledWith(expect.any(Function)); + expect(after).toHaveBeenCalledWith(app); +}); + +test('applies to a Webpack compiler and resolves any existing devServer requests', async () => { + const devServer = {}; + const compiler = {}; + const req = {}, + res = {}, + next = {}; + const app = { + use: jest.fn() + }; + const upwardHandler = jest.fn(); + + upward.middleware.mockResolvedValueOnce(upwardHandler); + + const noRequestsWaiting = new UpwardPlugin({}); + noRequestsWaiting.apply(compiler); + expect(noRequestsWaiting.compiler).toBe(compiler); + + const hasRequestsWaiting = new UpwardPlugin(devServer, 'path/to/upward'); + devServer.after(app); + const handler = app.use.mock.calls[0][0]; + + handler(req, res, next); + expect(upward.IOAdapter.default).not.toHaveBeenCalled(); + expect(upward.middleware).not.toHaveBeenCalled(); + expect(hasRequestsWaiting.middlewarePromise).toBeInstanceOf(Promise); + + hasRequestsWaiting.apply(compiler); + await hasRequestsWaiting.middlewarePromise; + + expect(upward.IOAdapter.default).toHaveBeenCalledWith('path/to/upward'); + expect(upward.middleware).toHaveBeenCalledWith( + 'path/to/upward', + expect.objectContaining({ + readFile: expect.any(Function), + networkFetch: expect.any(Function) + }) + ); + expect(upwardHandler).toHaveBeenCalledWith(req, res, next); +}); + +test('shares compiler promise', async () => { + const devServer = {}; + const compiler = {}; + const upwardHandler = jest.fn(); + + upward.middleware.mockResolvedValueOnce(upwardHandler); + const plugin = new UpwardPlugin(devServer, 'path/to/upward'); + + const promises = [plugin.getCompiler(), plugin.getCompiler()]; + + plugin.apply(compiler); + const [c1, c2] = await Promise.all(promises); + + expect(c1).toBe(c2); + expect(c2).toBe(compiler); +}); + +test('shares middleware promise so as not to create multiple middlewares', async () => { + const devServer = {}; + const compiler = {}; + const req = {}, + res = {}, + next = {}; + const app = { + use: jest.fn() + }; + const upwardHandler = jest.fn(); + + upward.middleware.mockResolvedValueOnce(upwardHandler); + const plugin = new UpwardPlugin(devServer, 'path/to/upward'); + devServer.after(app); + const handler = app.use.mock.calls[0][0]; + + handler(req, res, next); + handler('some', 'other', 'stuff'); + plugin.apply(compiler); + + await plugin.middlewarePromise; + + expect(upward.middleware).toHaveBeenCalledTimes(1); +}); + +test('supplies a dev-mode IOAdapter with webpack fs integration', async () => { + const devServer = {}; + const compiler = { + outputFileSystem: { + readFileSync: jest.fn() + }, + inputFileSystem: { + readFileSync: jest.fn() + } + }; + const defaultIO = { + readFile: jest.fn() + }; + const app = { + use: jest.fn() + }; + + upward.middleware.mockResolvedValueOnce(() => {}); + upward.IOAdapter.default.mockReturnValueOnce(defaultIO); + + const plugin = new UpwardPlugin(devServer); + plugin.apply(compiler); + devServer.after(app); + const handler = app.use.mock.calls[0][0]; + handler(); + await plugin.middlewarePromise; + + const io = upward.middleware.mock.calls[0][1]; + + compiler.outputFileSystem.readFileSync.mockImplementationOnce(() => { + return 'from output file system'; + }); + const fromOutputFileSystem = await io.readFile('aFile', 'binary'); + expect(fromOutputFileSystem).toBe('from output file system'); + expect(compiler.outputFileSystem.readFileSync).toHaveBeenCalledWith( + expect.stringMatching(/aFile$/), + 'binary' + ); + + compiler.outputFileSystem.readFileSync.mockImplementationOnce(() => { + throw new Error('ENOENT'); + }); + defaultIO.readFile.mockResolvedValueOnce('from default filesystem'); + const fromDefaultFileSystem = await io.readFile('bFile'); + expect(fromDefaultFileSystem).toBe('from default filesystem'); + expect(compiler.outputFileSystem.readFileSync).toHaveBeenCalledWith( + expect.stringMatching(/bFile$/), + undefined + ); + expect(defaultIO.readFile).toHaveBeenCalledWith( + expect.stringMatching(/bFile$/), + undefined + ); + + compiler.outputFileSystem.readFileSync.mockImplementationOnce(() => { + throw new Error('ENOENT'); + }); + defaultIO.readFile.mockImplementationOnce(() => + Promise.reject(new Error('ENOENT')) + ); + compiler.inputFileSystem.readFileSync.mockImplementationOnce( + () => 'from input file system' + ); + const fromInputFileSystem = await io.readFile('cFile'); + expect(fromInputFileSystem).toBe('from input file system'); + expect(compiler.outputFileSystem.readFileSync).toHaveBeenCalledWith( + expect.stringMatching(/cFile$/), + undefined + ); + expect(defaultIO.readFile).toHaveBeenCalledWith( + expect.stringMatching(/cFile$/), + undefined + ); + expect(compiler.inputFileSystem.readFileSync).toHaveBeenCalledWith( + expect.stringMatching(/cFile$/), + undefined + ); +}); + +test('dev-mode IOAdapter uses fetch', async () => { + const devServer = {}; + const app = { + use: jest.fn() + }; + + upward.middleware.mockResolvedValueOnce(() => {}); + + const plugin = new UpwardPlugin(devServer); + plugin.apply({}); + devServer.after(app); + const handler = app.use.mock.calls[0][0]; + handler(); + await plugin.middlewarePromise; + + const io = upward.middleware.mock.calls[0][1]; + + io.networkFetch('https://example.com', { method: 'POST' }); + + expect(fetch).toHaveBeenCalledWith( + 'https://example.com', + expect.objectContaining({ + method: 'POST', + agent: expect.anything() + }) + ); +}); diff --git a/packages/pwa-buildpack/src/index.js b/packages/pwa-buildpack/src/index.js index 86cc56756ff..7e5d369dbd9 100644 --- a/packages/pwa-buildpack/src/index.js +++ b/packages/pwa-buildpack/src/index.js @@ -2,5 +2,6 @@ const magentoLayoutLoader = require('./magento-layout-loader'); module.exports = { magentoLayoutLoader, - WebpackTools: require('./WebpackTools') + WebpackTools: require('./WebpackTools'), + Utilities: require('./Utilities') }; diff --git a/packages/pwa-buildpack/src/util/__tests__/check-loopback.spec.js b/packages/pwa-buildpack/src/util/__tests__/check-loopback.spec.js new file mode 100644 index 00000000000..6a59599ade7 --- /dev/null +++ b/packages/pwa-buildpack/src/util/__tests__/check-loopback.spec.js @@ -0,0 +1,71 @@ +jest.mock('../promisified/dns'); +jest.mock('../run-as-root'); +jest.mock('hostile'); + +const { lookup } = require('../promisified/dns'); +const runAsRoot = require('../run-as-root'); +const hostile = require('hostile'); + +const checkLoopback = require('../check-loopback'); + +const simulate = { + hostResolvesLoopback({ family = 4 } = {}) { + lookup.mockReturnValueOnce({ + address: family === 6 ? '::1' : '127.0.0.1', + family + }); + return simulate; + }, + hostDoesNotResolve() { + lookup.mockRejectedValueOnce({ code: 'ENOTFOUND' }); + return simulate; + } +}; + +test('checks if hostnames resolve local, ipv4 or 6', async () => { + simulate.hostResolvesLoopback(); + const loopbacks = await checkLoopback(['excelsior.com']); + expect(loopbacks.has('excelsior.com')).toBe(true); + expect(lookup).toHaveBeenCalledWith('excelsior.com'); + + simulate.hostResolvesLoopback({ family: 6 }); + const v6loopbacks = await checkLoopback(['excelsior.com']); + expect(v6loopbacks.has('excelsior.com')).toBe(true); +}); + +test('works on multiple hostnames', async () => { + simulate.hostResolvesLoopback().hostResolvesLoopback(); + const loopbacks = await checkLoopback(['excelsior.com', 'reliant.com']); + expect(loopbacks.has('excelsior.com')).toBe(true); +}); + +test.skip('updates /etc/hosts to make hostname local', async () => { + lookup.mockRejectedValueOnce({ code: 'ENOTFOUND' }); + await checkLoopback(['excelsior.com']); + expect(runAsRoot).toHaveBeenCalledTimes(1); + const updater = runAsRoot.mock.calls[0][1]; + updater(['defiant.com', 'yamato.com']); + expect(hostile.set).toHaveBeenCalledTimes(2); + expect(hostile.set).toHaveBeenNthCalledWith(1, '127.0.0.1', 'defiant.com'); + expect(hostile.set).toHaveBeenNthCalledWith(2, '127.0.0.1', 'yamato.com'); +}); + +test('dies if unexpected lookup error', async () => { + lookup.mockRejectedValueOnce(new Error('unknown')); + await expect(checkLoopback(['excelsior.com'])).rejects.toThrow( + 'Error trying to check' + ); +}); + +test('throws informative error if invalid argument', async () => { + await expect( + checkLoopback('wat') + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"[pwa-buildpack:util:check-loopback.js] hostnames must be an array of strings"` + ); + await expect( + checkLoopback(['wat', {}]) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"[pwa-buildpack:util:check-loopback.js] hostnames must be an array of strings"` + ); +}); diff --git a/packages/pwa-buildpack/src/util/__tests__/ssl-cert-store.spec.js b/packages/pwa-buildpack/src/util/__tests__/ssl-cert-store.spec.js deleted file mode 100644 index ef7bbd57800..00000000000 --- a/packages/pwa-buildpack/src/util/__tests__/ssl-cert-store.spec.js +++ /dev/null @@ -1,95 +0,0 @@ -jest.mock('../promisified/child_process'); -jest.mock('../run-as-root'); -jest.mock('../global-config'); - -const GlobalConfig = require('../global-config'); -const { exec } = require('../promisified/child_process'); -const runAsRoot = require('../run-as-root'); - -let SSLCertStore; -beforeAll(() => { - GlobalConfig.mockImplementation(({ key }) => ({ - set: jest.fn((...args) => { - const keyParts = args.slice(0, -1); - expect(typeof key(...keyParts)).toBe('string'); - }), - get: jest.fn(), - values: jest.fn(), - del: jest.fn() - })); - SSLCertStore = require('../ssl-cert-store'); -}); -afterAll(() => GlobalConfig.mockRestore()); - -test('static async expired(cert) uses openssl to test whether a cert has expired or is expiring', async () => { - exec.mockRejectedValueOnce({ - stdout: '\nCertificate will expire\n' - }); - const shouldBeTrue = await SSLCertStore.expired('fakeCert'); - expect(exec).toHaveBeenCalledWith( - 'openssl x509 -checkend 0 <<< "fakeCert"' - ); - expect(shouldBeTrue).toBe(true); - - exec.mockResolvedValueOnce(null); - const shouldBeFalse = await SSLCertStore.expired('fakeCert'); - expect(shouldBeFalse).toBe(false); - - exec.mockRejectedValueOnce({ - stdout: 'Some other value' - }); - const shouldStillBeFalse = await SSLCertStore.expired('fakeCert'); - expect(shouldStillBeFalse).toBe(false); -}); - -test('static async provide() throws on a non-string', async () => { - await expect(SSLCertStore.provide(null)).rejects.toThrowError( - 'Must provide a commonName' - ); -}); - -test('static async provide() gets a valid cached cert', async () => { - exec.mockResolvedValueOnce(null); - SSLCertStore.userCerts.get.mockResolvedValueOnce({ - cert: 'cachedCert', - key: 'cachedKey' - }); - await expect(SSLCertStore.provide('example.com')).resolves.toMatchObject({ - cert: 'cachedCert', - key: 'cachedKey' - }); -}); - -test('static async provide() deletes and recreates an expired cert', async () => { - SSLCertStore.userCerts.get.mockResolvedValueOnce({ - cert: 'expiredCert', - key: 'expiredKey' - }); - exec.mockRejectedValueOnce({ stdout: 'Certificate will expire' }); - runAsRoot.mockResolvedValueOnce( - '{ "key": "refreshedKey", "cert": "refreshedCert" }' - ); - await expect(SSLCertStore.provide('example.com')).resolves.toMatchObject({ - cert: 'refreshedCert', - key: 'refreshedKey' - }); -}); - -test('static async provide() creates a cert for a fresh domain', async () => { - SSLCertStore.userCerts.get.mockRestore(); - runAsRoot.mockImplementationOnce(() => { - return Promise.resolve('{ "key": "newKey", "cert": "newCert" }'); - }); - // and again with no cert, not even an expired one - await expect(SSLCertStore.provide('existing.com')).resolves.toMatchObject({ - cert: 'newCert', - key: 'newKey' - }); -}); - -test('static async create() throws a formatted error if the root call did not work', async () => { - runAsRoot.mockRejectedValueOnce(''); - await expect(SSLCertStore.provide('example.com')).rejects.toThrowError( - /generating dev cert/ - ); -}); diff --git a/packages/pwa-buildpack/src/util/check-loopback.js b/packages/pwa-buildpack/src/util/check-loopback.js new file mode 100644 index 00000000000..bd498f2ef56 --- /dev/null +++ b/packages/pwa-buildpack/src/util/check-loopback.js @@ -0,0 +1,48 @@ +const debug = require('./debug').makeFileLogger(__filename); +const { lookup } = require('./promisified/dns'); + +async function resolveIp(hostname) { + debug(`checking if ${hostname} is loopback`); + try { + const lookedUp = await lookup(hostname); + return lookedUp; + } catch (e) { + if (e.code !== 'ENOTFOUND') { + throw Error( + debug.errorMsg( + `Error trying to check that ${hostname} is loopback: ${ + e.message + }` + ) + ); + } + } +} + +async function checkLoopback(hostnames) { + if ( + !Array.isArray(hostnames) || + hostnames.some(name => typeof name !== 'string') + ) { + throw new Error( + debug.errorMsg(`hostnames must be an array of strings`) + ); + } + const ips = await Promise.all(hostnames.map(resolveIp)); + + return new Set( + hostnames.filter((hostname, i) => { + const ip = ips[i]; + const loopsBack = + ip && (ip.address === '127.0.0.1' || ip.address === '::1'); + + if (loopsBack) { + debug(`${hostname} already resolves to ${ip.address}!`); + } + + return loopsBack; + }) + ); +} + +module.exports = checkLoopback; diff --git a/packages/pwa-buildpack/src/util/ssl-cert-store.js b/packages/pwa-buildpack/src/util/ssl-cert-store.js deleted file mode 100644 index 52e5c0e36af..00000000000 --- a/packages/pwa-buildpack/src/util/ssl-cert-store.js +++ /dev/null @@ -1,59 +0,0 @@ -const GlobalConfig = require('./global-config'); -const debug = require('./debug').makeFileLogger(__filename); -const { exec } = require('./promisified/child_process'); -const runAsRoot = require('./run-as-root'); - -const userCerts = new GlobalConfig({ - prefix: 'devcert', - key: x => x -}); - -module.exports = { - userCerts, - // treat a certificate as basically expired if it'll expire in 1 day (86400s) - async expired(cert) { - return exec(`openssl x509 -checkend 0 <<< "${cert}"`) - .then(() => false) - .catch(({ stdout }) => stdout.trim() === 'Certificate will expire'); - }, - async provide(commonName) { - if (typeof commonName !== 'string') { - throw Error( - debug.errorMsg( - `Must provide a commonName to SSLCertStore.provide(). Instead, argument was ${commonName}` - ) - ); - } - let certPair = await userCerts.get(commonName); - if (certPair && (await this.expired(certPair.cert))) { - certPair = null; - await userCerts.del(commonName); - } - if (!certPair) { - certPair = await this.create(commonName); - await userCerts.set(commonName, certPair); - } - return certPair; - }, - async create(commonName) { - try { - const cert = await runAsRoot( - 'Creating and trusting an SSL certificate for local dev requires temporary administrative privileges.\n Enter password for %u on %H: ', - /* istanbul ignore next: this runs out of band in another process, hard to test */ - async name => { - const devcert = require('@magento/devcert'); - const certs = await devcert(name); - process.stdout.write(JSON.stringify(certs)); - }, - commonName - ); - return JSON.parse(cert); - } catch (e) { - throw Error( - debug.errorMsg( - `Error generating dev certificate: ${e.message} ${e.stack}` - ) - ); - } - } -}; diff --git a/packages/pwa-devdocs/CHANGELOG.md b/packages/pwa-devdocs/CHANGELOG.md new file mode 100644 index 00000000000..12d1dbf1eff --- /dev/null +++ b/packages/pwa-devdocs/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +## 1.0.1 (2018-08-13) + + +### Bug Fixes + +* **dev:** merge 'assets' and 'output' paths ([36d8157](https://github.com/magento-research/pwa-studio/commit/36d8157)) diff --git a/packages/pwa-module/Block/Bundle.php b/packages/pwa-module/Block/Bundle.php deleted file mode 100644 index 9fc55e0613f..00000000000 --- a/packages/pwa-module/Block/Bundle.php +++ /dev/null @@ -1,81 +0,0 @@ -webpackConfig = $webpackConfig; - $this->state = $state; - -// $om = \Magento\Framework\App\ObjectManager::getInstance(); -// $mode = \Magento\Framework\App\ObjectManager::getInstance()->create(\Magento\Framework\App\State::class)->getMode(); -// $page = $om->get('Magento\Framework\View\Page\Config'); -// -// if ($mode == 'production') { -// $page->addPageAsset('bundles/vendor.js'); -// $page->addPageAsset('bundles/client.js'); -// } - - } - - /** - * @return string - */ - public function getMode(): string - { - return $this->state->getMode(); - } - - /** - * @return string - */ - public function getBundleUrl(): string - { - $mode = $this->getMode(); - if ($mode === 'development') { - return $this->webpackConfig->getDevServerHost() . $this->webpackConfig->getPublicAssetPath() . 'client.js'; - } - - return ''; - } -} diff --git a/packages/pwa-module/Controller/Index/Js.php b/packages/pwa-module/Controller/Index/Js.php deleted file mode 100644 index ecb2a640096..00000000000 --- a/packages/pwa-module/Controller/Index/Js.php +++ /dev/null @@ -1,81 +0,0 @@ -webpackConfig = $webpackConfig; - $this->jsFileResultFactory = $jsFileResultFactory; - } - - /** - * @inheritdoc - */ - public function execute() - { - $filePath = implode(DIRECTORY_SEPARATOR, [ - $this->webpackConfig->getThemePath(), - 'web', - 'js', - $this->webpackConfig->getServiceWorkerFileName() - ]); - - if (file_exists($filePath)) { - $result = $this->jsFileResultFactory->create(); - $result->setHttpResponseCode(200); - $result->sendJSFile($filePath); - return $result; - } - - /** @var Raw $result */ - $result = $this->resultFactory->create(ResultFactory::TYPE_RAW); - $result->setHttpResponseCode(404); - $result->setContents('404: Could not find ' . $this->webpackConfig->getServiceWorkerFileName()); - - return $result; - } -} diff --git a/packages/pwa-module/Controller/Index/WebpackConfigEndpoint.php b/packages/pwa-module/Controller/Index/WebpackConfigEndpoint.php deleted file mode 100644 index 27f97fd1e49..00000000000 --- a/packages/pwa-module/Controller/Index/WebpackConfigEndpoint.php +++ /dev/null @@ -1,52 +0,0 @@ -webpackConfig = $webpackConfig; - } - - /** - * @inheritdoc - */ - public function execute() - { - /** @var Json $result */ - $result = $this->resultFactory->create(ResultFactory::TYPE_JSON); - $result->setHttpResponseCode(200); - $result->setData($this->webpackConfig); - return $result; - } -} diff --git a/packages/pwa-module/Controller/Router.php b/packages/pwa-module/Controller/Router.php deleted file mode 100644 index 6e140a44307..00000000000 --- a/packages/pwa-module/Controller/Router.php +++ /dev/null @@ -1,65 +0,0 @@ -actionFactory = $actionFactory; - $this->webpackConfig = $webpackConfig; - } - - /** - * @inheritdoc - */ - public function match(RequestInterface $request) - { - $rootPath = trim($request->getPathInfo(), '/'); - if ($rootPath == $this->webpackConfig->getServiceWorkerFileName()) { - $request->setModuleName('pwa') - ->setControllerName('index') - ->setActionName('js'); - return $this->actionFactory->create( - Forward::class - ); - } - if ($rootPath == "webpack-config.json") { - $request->setModuleName('pwa') - ->setControllerName('index') - ->setActionName('webpackconfigendpoint'); - return $this->actionFactory->create( - Forward::class - ); - } - return null; - } -} diff --git a/packages/pwa-module/Helper/WebpackConfig.php b/packages/pwa-module/Helper/WebpackConfig.php deleted file mode 100644 index 1d24acc238b..00000000000 --- a/packages/pwa-module/Helper/WebpackConfig.php +++ /dev/null @@ -1,331 +0,0 @@ -viewConfig = $viewConfig; - $this->directoryList = $directoryList; - $this->themeProvider = $themeProvider; - $this->scopeConfig = $scopeConfig; - $this->storeManager = $storeManager; - $this->assetRepo = $assetRepo; - $this->baseUrl = $baseUrl; - } - - /** - * Get the base origin of the store. - * - * @return string - */ - public function getStoreOrigin(): string - { - if (empty($this->storeOrigin)) { - $this->storeOrigin = $this->baseUrl->getBaseUrl(['_secure' => true]); - } - - return $this->storeOrigin; - } - - /** - * Get the public URL path of the service worker - * - * @return string - */ - public function getPublicAssetPath(): string - { - if (empty($this->publicAssetPath)) { - $this->publicAssetPath = "/" . trim(str_replace( - $this->getStoreOrigin(), - "", - $this->baseUrl->getBaseUrl(['_type' => UrlInterface::URL_TYPE_STATIC, '_secure' => true]) . - $this->assetRepo->createAsset("/")->getPath() - ), "/") . "/"; - } - - return $this->publicAssetPath; - } - - /** - * Get the name of the service worker file - * @return string - */ - public function getServiceWorkerFileName(): string - { - if (empty($this->serviceWorkerFileName)) { - $this->serviceWorkerFileName = (string) $this->_getVarOrFallback( - self::SERVICE_WORKER_NAME_VAR, - self::DEFAULT_SERVICE_WORKER_NAME - ); - } - return $this->serviceWorkerFileName; - } - - /** - * Get the absolute filesystem path of the theme - * - * @return string - * @throws FileSystemException - */ - public function getThemePath(): string - { - if (empty($this->themePath)) { - $this->themePath = implode(DIRECTORY_SEPARATOR, [ - $this->directoryList->getPath('app'), - "design", - $this->_getTheme()->getFullPath() - ]); - } - - return $this->themePath; - } - - /** - * @return string - */ - public function getDevServerHostname(): string - { - if (empty($this->devServerHostname)) { - $this->devServerHostname = (string) $this->_getVarOrFallback( - self::DEVSERVER_HOSTNAME_VAR, - self::DEFAULT_DEVSERVER_HOSTNAME - ); - } - - return $this->devServerHostname; - } - - /** - * @return string - */ - public function getDevServerPort(): string - { - if (empty($this->devServerPort)) { - $this->devServerPort = (string) $this->_getVarOrFallback( - self::DEVSERVER_PORT_VAR, - self::DEFAULT_DEVSERVER_PORT - ); - } - - return $this->devServerPort; - } - - /** - * Get the configured local webpack-dev-server hostname - * @return string - */ - public function getDevServerHost(): string - { - // TODO: proper URL builder - return self::DEVSERVER_PROTOCOL . "://" . $this->getDevServerHostname() . ":" . $this->getDevServerPort(); - } - - /** - * @return array - * @throws ReflectionException - */ - public function jsonSerialize(): array - { - $class = new ReflectionClass(self::class); - $methods = $class->getMethods(ReflectionMethod::IS_PUBLIC); - $properties = []; - foreach ($methods as $method) { - $name = $method->getName(); - if (preg_match('/^get[A-Z0-9]/', $name)) { - $propName = lcfirst(substr($name, 3)); - $properties[$propName] = $method->invoke($this); - } - } - - return $properties; - } - - /** - * Get the currently active theme instance - * - * @return ThemeInterface - * @throws NoSuchEntityException - */ - private function _getTheme(): ThemeInterface - { - - $themeId = $this->scopeConfig->getValue( - DesignInterface::XML_PATH_THEME_ID, - ScopeInterface::SCOPE_STORE, - $this->storeManager->getStore()->getId() - ); - - return $this->themeProvider->getThemeById($themeId); - } - - /** - * Get a variable from view.xml or fall back to a default value - * - * @param string $name variable name - * @param string $fallback value if var is null - * @return string|false - */ - private function _getVarOrFallback($name, $fallback) - { - $varValue = $this->viewConfig->getViewConfig()->getVarValue(self::PWA_MODULE_NAME, $name); - return empty($varValue) ? $fallback : $varValue; - } -} diff --git a/packages/pwa-module/Model/Result/JsFileResult.php b/packages/pwa-module/Model/Result/JsFileResult.php deleted file mode 100644 index 09cddc89875..00000000000 --- a/packages/pwa-module/Model/Result/JsFileResult.php +++ /dev/null @@ -1,75 +0,0 @@ -file = $file; - } - - /** - * Serve this file from disk. - * - * @param string $path - */ - public function sendJSFile($path) - { - $this->contents = $this->file->read($path); - $this->contentLength = filesize($path); - } - - /** - * {@inheritdoc} - */ - protected function render(HttpResponseInterface $response) - { - $response->setHeader('Content-Type', 'application/json', true) - ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true) - ->setHeader('Pragma', 'public', true) - ->setHeader('Content-Type', 'application/javascript', true) - ->setHeader('Content-Length', $this->contentLength) - ->setBody($this->contents); - return $this; - } -} diff --git a/packages/pwa-module/etc/di.xml b/packages/pwa-module/etc/di.xml deleted file mode 100644 index 82e7ce1b193..00000000000 --- a/packages/pwa-module/etc/di.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Magento\Pwa\Controller\Router - false - 100 - - - - - diff --git a/packages/pwa-module/etc/frontend/routes.xml b/packages/pwa-module/etc/frontend/routes.xml deleted file mode 100644 index 13e0af481bc..00000000000 --- a/packages/pwa-module/etc/frontend/routes.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/packages/pwa-module/etc/module.xml b/packages/pwa-module/etc/module.xml deleted file mode 100644 index a97547dea69..00000000000 --- a/packages/pwa-module/etc/module.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/packages/pwa-module/package.json b/packages/pwa-module/package.json deleted file mode 100644 index d0359b478c5..00000000000 --- a/packages/pwa-module/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "pwa-module", - "private": true -} diff --git a/packages/pwa-module/registration.php b/packages/pwa-module/registration.php deleted file mode 100644 index 89e24330e54..00000000000 --- a/packages/pwa-module/registration.php +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/packages/upward-js/README.md b/packages/upward-js/README.md new file mode 100644 index 00000000000..a4cc3232bf0 --- /dev/null +++ b/packages/upward-js/README.md @@ -0,0 +1,60 @@ +# upward-js + +Reference implementation of the [UPWARD](../upward-spec) protocol in JavaScript. Runs as a standalone server or as an Express/Connect middleware. + +## Installation + +`npm install @magento/upward-js` + +### Usage + +Your UPWARD definition file drives the behavior of upward-js. Create that definition as a YAML file and save it in your project. + +You can use `upward-js` from the command line, through the server API, or through the middleware API. + +#### Command Line + +The `upward-js-server` command will become globally available if you install globally: `npm install -g upward-js`. + +The server takes no arguments; instead it is configured by environment variables. At minimum, the environment variable `UPWARD_JS_UPWARD_PATH` must be set to the path of your definition file, and `UPWARD_JS_BIND_LOCAL` must be set to 1. + +The server launches in the foreground and if `UPWARD_JS_LOG_URL` is set to 1, it prints its bound URL to stdout. + +```sh +$ UPWARD_JS_BIND_LOCAL=1 UPWARD_JS_UPWARD_PATH=./my-upward-server.yml upward-js-server + https://0.0.0.0:23651 +``` + +#### Server API + +Import the server into your Node script. + +```js + +const { server } = require('@magento/upward-js'); + +const { app } = upward({ + upwardPath: './my-upward-server.yml' +}) + +app.listen(8000); +``` + +#### Middleware API + +The middleware is compatible with Express 4, Connect, and other frameworks compatible with this common pattern. It returns a Promise for a function which handles request/response pairs. + +```js + +const express = require('express'); +const { middleware } = require('@magento/upward-js'); + +const app = express(); + +app.use(otherMiddlewaresMaybe); + +app.use(middleware('./my-upward-server.yml')); + +``` + +Optionally, you may pass an `IOAdapter` as a second argument to the middleware. diff --git a/packages/upward-js/bin/server b/packages/upward-js/bin/server new file mode 100755 index 00000000000..378cb4cfe69 --- /dev/null +++ b/packages/upward-js/bin/server @@ -0,0 +1,9 @@ +#!/usr/bin/env node +require('dotenv').config(); + +const config = require('../lib/envToConfig')(); + +require('../lib/server.js')(config).catch(e => { + console.error(e.stack); + process.exit(e.errno || 1); +}); diff --git a/packages/upward-js/jest.config.js b/packages/upward-js/jest.config.js new file mode 100644 index 00000000000..d79f925647a --- /dev/null +++ b/packages/upward-js/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + displayName: 'Upward JS', + clearMocks: true, + testEnvironment: 'node' +}; diff --git a/packages/upward-js/lib/Context.js b/packages/upward-js/lib/Context.js new file mode 100644 index 00000000000..3ceae4faa95 --- /dev/null +++ b/packages/upward-js/lib/Context.js @@ -0,0 +1,115 @@ +const debug = require('debug')('upward-js:Context'); +const { pick } = require('lodash'); +const { URL } = require('url'); + +const ContextPath = require('./ContextPath'); + +const statusCodes = Array.from({ length: 600 }, (_, i) => i + 100); +const constants = new Set([ + true, + false, + 'GET', + 'POST', + 'mustache', + 'text/html', + 'text/plain', + 'application/json', + 'utf-8', + 'utf8', + 'latin-1', + 'base64', + 'binary', + 'hex', + ...statusCodes, + ...statusCodes.map(code => code.toString()) +]); + +class Context { + static fromRequest(env, request) { + debug('generating from request: %s', request.url); + const hostedUrl = new URL(request.url, `http://${request.get('host')}`); + debug('url derived from host is %O', hostedUrl); + const url = pick(hostedUrl, [ + 'host', + 'hostname', + 'port', + 'pathname', + 'path', + 'search', + 'searchParams' + ]); + url.query = request.query; + return new Context({ + env, + request: { + url, + headers: request.headers, + headerEntries: Object.entries(request.headers).map( + ([name, value]) => ({ name, value }) + ), + queryEntries: Object.entries(url.query).map( + ([name, value]) => ({ name, value }) + ) + } + }); + } + + constructor(data) { + this._data = data; + this._promises = new Map(); + } + + setVisitor(visitor) { + this.visitor = visitor; + } + + async get(lookup) { + const path = ContextPath.from(lookup); + debug('lookup %s at path %s', lookup, path); + if (constants.has(path.toString())) { + debug('%s is a constant', lookup); + return lookup; + } + const base = path.base(); + debug('%s is from context base %s', lookup, base); + if (!this._data.hasOwnProperty(base)) { + debug('%s not yet assigned, acquiring promise handle', base); + let promise = this._promises.get(base); + if (!promise) { + debug('%s has never been requested, visiting from root', base); + promise = this.visitor.downward([base]).then(value => { + if (typeof value === 'function') { + debug( + '%s assigned to context as function: %o', + base, + value + ); + this.set(base, value); + } else { + debug('%s assigned: %o', base, value[base]); + this.set(base, value[base]); + } + }); + this._promises.set(base, promise); + } + await promise; + } + return path.getFrom(this._data); + } + + set(base, value, override) { + const isSet = constants.has(base) || this._data.hasOwnProperty(base); + if (isSet && !override) { + throw new Error( + `Attempted to reassign context property '${base}' to '${value}'. Context properties cannot be reassigned.` + ); + } + this._data[base] = value; + } + + forget(base) { + delete this._data[base]; + } +} + +module.exports = Context; diff --git a/packages/upward-js/lib/ContextPath.js b/packages/upward-js/lib/ContextPath.js new file mode 100644 index 00000000000..546bbe85f3c --- /dev/null +++ b/packages/upward-js/lib/ContextPath.js @@ -0,0 +1,104 @@ +const debug = require('debug')('upward-js:ContextPath'); +// Tests for dot-separated strings of "word characters" or slashes. +// Slashes so that MIME type constants, like "text/html", can be legal values. +// "Word characters" are [a-zA-Z0-9_]. +const illegalPathChars = /(^[\.\[\]])|[^\.\w\$\/]/; +const contextPathCache = new Map(); +class ContextPath { + static from(lookup) { + if (lookup instanceof ContextPath) { + return lookup; + } + if (typeof lookup !== 'string') { + throw new Error( + `Internal error: Cannot build ContextPath from non-string ${lookup}` + ); + } + if (illegalPathChars.test(lookup)) { + throw new Error( + `Illegal context property name found: ${lookup}\nContext properties must be dot-separated strings and contain only letters, numbers, and underscores, and cannot begin with a dot.` + ); + } + if (contextPathCache.has(lookup)) { + return contextPathCache.get(lookup); + } + const segments = lookup.split('.'); + const path = segments.reduce( + (parent, newSegment) => parent.extend(newSegment), + ContextPath.root + ); + contextPathCache.set(lookup, path); + return path; + } + extend(newSegment) { + const fullPath = this._segments.concat(newSegment); + const fullPathString = fullPath.join('.'); + let path = contextPathCache.get(fullPathString); + if (!path) { + path = new ContextPath(fullPath); + contextPathCache.set(fullPathString, path); + } + return path; + } + constructor(segments) { + this._segments = segments; + } + base() { + return this._segments[0]; + } + getFrom(obj) { + let current = obj; + for (const segment of this._segments) { + if (Array.isArray(current)) { + const index = Number(segment); + if (!isNaN(index)) { + debug('array index %d yields %o', segment, current[index]); + if (current.length < index - 1) { + return ''; + } + current = current[index]; + } else { + throw new Error( + `Attempted non-integer lookup on a list: ${current} [${segment}]` + ); + } + } else if (current === undefined || current === null) { + current = ''; + break; + } else if (typeof current === 'object') { + current = current[segment]; + } else { + break; + } + } + debug( + 'traverse %j yielded %j from %j', + this._segments, + current, + obj[this.base()] + ); + return current; + } + // contains(otherPath) { + // return this._segments.every((segment, i) => otherPath.keyAt(i) === i); + // } + // containsSegment(segment) { + // return this._segments.some(mySegment => mySegment === segment); + // } + // depth() { + // return this._segments.length; + // } + // keyAt(index) { + // return this._segments[index]; + // } + // relative(ancestor) { + // return this._segments.slice(ancestor.depth()); + // } + toString() { + return this._segments.join('.'); + } +} + +ContextPath.root = new ContextPath([]); + +module.exports = ContextPath; diff --git a/packages/upward-js/lib/IOAdapter.js b/packages/upward-js/lib/IOAdapter.js new file mode 100644 index 00000000000..2edc4c0892f --- /dev/null +++ b/packages/upward-js/lib/IOAdapter.js @@ -0,0 +1,59 @@ +const debug = require('debug')('upward-js:IOAdapter'); +const containsPath = require('contains-path'); +const { resolve, dirname } = require('path'); +const { readFile: fsReadFile } = require('fs'); +const { promisify } = require('util'); + +const readFile = promisify(fsReadFile); +class IOAdapter { + static default(upwardPath) { + debug(`creating default IO from ${upwardPath}`); + const baseDir = dirname(upwardPath); + debug(`baseDir ${baseDir}`); + return new IOAdapter({ + networkFetch: require('node-fetch'), + readFile: (filePath, enc) => { + // prevent path traversal above baseDir + const resolvedPath = resolve(baseDir, filePath); + if (!containsPath(resolvedPath, baseDir)) { + throw new Error( + `Cannot read ${resolvedPath} because it is outside ${baseDir}` + ); + } + return readFile(resolvedPath, enc); + } + }); + } + constructor(implementations) { + const missingImpls = ['readFile', 'networkFetch'].reduce( + (missing, method) => + method in implementations + ? missing + : missing + + `Must provide an implementation of '${method}\n`, + '' + ); + if (missingImpls) { + throw new Error(`Error creating IOAdapter:\n${missingImpls}`); + } + Object.assign(this, implementations); + } + /** + * Works like promisified Node `fs.readFile`. (Injected for testability.) + * Cannot traverse below working directory. + * @param {string} path Path of file to read. + * @param {string} [encoding] Character set, e.g. 'utf-8'. + * @return {Promise} Promise for file contents. + */ + async readFile(filePath, encoding) {} //eslint-disable-line + + /** + * Works like `node-fetch`. (Injected for testability.) + * @param {string|URL} URL URL to fetch. + * @param {object} options Fetch options, see node-fetch docs. + * @return {Promise} + */ + async networkFetch(url, options) {} //eslint-disable-line +} + +module.exports = IOAdapter; diff --git a/packages/upward-js/lib/ResolverVisitor.js b/packages/upward-js/lib/ResolverVisitor.js new file mode 100644 index 00000000000..536cb53d69a --- /dev/null +++ b/packages/upward-js/lib/ResolverVisitor.js @@ -0,0 +1,107 @@ +const debug = require('debug')('upward-js:ResolverVisitor'); +const { inspect } = require('util'); +const { ResolverList, ResolversByType } = require('./resolvers'); +const { zipObject } = require('lodash'); +const isPrimitive = require('./isPrimitive'); + +class ResolverVisitor { + constructor(io, rootDefinition, context) { + this.io = io; + this.rootDefinition = rootDefinition; + this.context = context; + this.context.setVisitor(this); + } + async downward(contextNames) { + debug('resolving downward: %o', contextNames); + let passedMiddleware = false; + const valuePromises = contextNames.map(async name => { + const value = await this.upward(this.rootDefinition, name); + if (typeof value === 'function') { + debug( + '%s request returned a function, we are assuming it is a middleware' + ); + passedMiddleware = value; + throw new Error('PASSED_MIDDLEWARE'); + } + return value; + }); + try { + const values = await Promise.all(valuePromises); + return zipObject(contextNames, values); + } catch (e) { + if (e.message === 'PASSED_MIDDLEWARE') { + debug( + `returning middleware from visitor.downward() instead of object` + ); + return passedMiddleware; + } else { + throw e; + } + } + } + async upward(definition, propertyName) { + debug('resolving upward: %s from %o', propertyName, definition); + if (!definition.hasOwnProperty(propertyName)) { + throw new Error( + `Context value '${propertyName}' not defined in ${inspect( + definition + )}.` + ); + } + const defined = definition[propertyName]; + + const resolver = this.getResolverFor(defined, propertyName); + + if (resolver) { + return resolver.resolve(defined); + } + + if (isPrimitive(defined)) { + const definedString = defined.toString(); + debug( + 'defined: %s is primitive, yielding to context.get("%s")', + definedString, + definedString + ); + return this.context.get(definedString); + } + + if (typeof defined !== 'object' || !this.getResolverFailure) { + throw new Error(`Unexpected value in config: ${defined}`); + } else { + throw new Error(this.getResolverFailure); + } + } + getResolverFor(defined, propertyName) { + let Resolver; + for (Resolver of ResolverList) { + const recognized = + Resolver.recognize && Resolver.recognize(defined); + if (recognized) { + return { + resolve: () => new Resolver(this).resolve(recognized) + }; + } + } + if (defined.resolver) { + Resolver = ResolversByType[defined.resolver]; + if (!Resolver) { + this.getResolverFailure = `Unrecognized resolver type: ${ + defined.resolver + }`; + } + } else { + Resolver = ResolverList.find(({ telltale }) => + defined.hasOwnProperty(telltale) + ); + if (!Resolver) { + this.getResolverFailure = `Unrecognized configuration. Could not match a resolver to ${propertyName}: ${inspect( + defined + )}`; + } + } + if (Resolver) return new Resolver(this); + } +} + +module.exports = ResolverVisitor; diff --git a/packages/upward-js/lib/UpwardServerError.js b/packages/upward-js/lib/UpwardServerError.js new file mode 100644 index 00000000000..a7a4ffeac9b --- /dev/null +++ b/packages/upward-js/lib/UpwardServerError.js @@ -0,0 +1,11 @@ +class UpwardServerError extends Error { + get name() { + return 'UpwardServerError'; + } + constructor(originalError, message) { + super(originalError); + this.message += ' -- ' + message; + } +} + +module.exports = UpwardServerError; diff --git a/packages/upward-js/lib/__tests__/Context.test.js b/packages/upward-js/lib/__tests__/Context.test.js new file mode 100644 index 00000000000..2b60dced002 --- /dev/null +++ b/packages/upward-js/lib/__tests__/Context.test.js @@ -0,0 +1,40 @@ +const Context = require('../Context'); + +test('promises are cached', async () => { + const context = new Context({}); + const downward = jest.fn(async () => ({ identity: 'same' })); + context.setVisitor({ downward }); + + await Promise.all([ + expect(context.get('identity')).resolves.toBe('same'), + expect(context.get('identity')).resolves.toBe('same') + ]); + expect(context._promises.size).toBe(1); +}); + +test('cannot set context property twice', () => { + const context = new Context({ immu: 'table' }); + expect(() => + context.set('immu', 'nized') + ).toThrowErrorMatchingInlineSnapshot( + `"Attempted to reassign context property 'immu' to 'nized'. Context properties cannot be reassigned."` + ); +}); + +test('forget() deletes ephemeral data', async () => { + const context = new Context({ mu: 'table' }); + const downward = jest.fn(async () => ({ mu: 'nificent' })); + context.setVisitor({ downward }); + + await expect(context.get('mu')).resolves.toBe('table'); + expect(downward).not.toHaveBeenCalled(); + context.forget('mu'); + await expect(context.get('mu')).resolves.toBe('nificent'); + expect(downward).toHaveBeenCalledWith(['mu']); +}); + +test('constants are always present', async () => { + const context = new Context({}); + await expect(context.get('text/plain')).resolves.toBe('text/plain'); + await expect(context.get('208')).resolves.toBe('208'); +}); diff --git a/packages/upward-js/lib/__tests__/ResolverVisitor.test.js b/packages/upward-js/lib/__tests__/ResolverVisitor.test.js new file mode 100644 index 00000000000..de9ee318e1b --- /dev/null +++ b/packages/upward-js/lib/__tests__/ResolverVisitor.test.js @@ -0,0 +1,93 @@ +const ResolverVisitor = require('../ResolverVisitor'); + +const mockIO = () => ({ + readFile: jest.fn(), + networkFetch: jest.fn() +}); + +const mockContext = () => ({ + setVisitor: jest.fn(), + get: jest.fn() +}); + +test('binds itself to supplied context', async () => { + const context = mockContext(); + const visitor = new ResolverVisitor(null, null, context); + expect(context.setVisitor).toHaveBeenCalledWith(visitor); +}); + +test('.upward() errors on a value not found in definition', async () => { + const visitor = new ResolverVisitor(null, null, mockContext()); + await expect(visitor.upward({}, 'foo')).rejects.toThrow( + "Context value 'foo' not defined" + ); +}); + +test('.upward() derives resolvers from shortcut strings', async () => { + const io = mockIO(); + const context = mockContext(); + context.get.mockRejectedValue('Should have resolved FileResolver shortcut'); + io.readFile.mockReturnValueOnce('sepia'); + const visitor = new ResolverVisitor(io, null, context); + await expect( + visitor.upward({ cuttlefish: './ink' }, 'cuttlefish') + ).resolves.toEqual('sepia'); + expect(io.readFile).toHaveBeenCalledWith('./ink', 'utf8'); + expect(context.get).not.toHaveBeenCalled(); +}); + +test('.upward() gets primitive from context', async () => { + const context = mockContext(); + context.get.mockResolvedValueOnce('green'); + const visitor = new ResolverVisitor(null, null, context); + await expect(visitor.upward({ foo: 'bar' }, 'foo')).resolves.toBe('green'); + expect(context.get).toHaveBeenCalledWith('bar'); +}); + +test('.upward() errors on a non-primitive, non-object value', async () => { + const visitor = new ResolverVisitor(null, null, mockContext()); + await expect(visitor.upward({ foo: () => {} }, 'foo')).rejects.toThrow( + 'Unexpected value' + ); +}); + +test('.upward() finds resolvers using `resolver` property', async () => { + const visitor = new ResolverVisitor(mockIO(), null, mockContext()); + await expect( + visitor.upward( + { foo: { resolver: 'inline', inline: 'fighters' } }, + 'foo' + ) + ).resolves.toEqual('fighters'); +}); + +test('.upward() throws on an unrecognized `resolver` property', async () => { + const visitor = new ResolverVisitor(mockIO(), null, mockContext()); + await expect( + visitor.upward({ foo: { resolver: 'wat', no: 'really?' } }, 'foo') + ).rejects.toThrow('Unrecognized resolver type'); +}); + +test('.upward() derives resolver from telltale property', async () => { + const visitor = new ResolverVisitor(mockIO(), null, mockContext()); + await expect( + visitor.upward({ foo: { inline: 'fighters' } }, 'foo') + ).resolves.toEqual('fighters'); +}); + +test('.upward() throws if it cannot derive a resolver strategy', async () => { + const visitor = new ResolverVisitor(mockIO(), null, mockContext()); + await expect( + visitor.upward({ foo: { hopeless: 'case' } }, 'foo') + ).rejects.toThrow('Unrecognized configuration. Could not match a resolver'); +}); + +test('.downward() calls visitor.upward() with root definition', async () => { + const context = mockContext(); + context.get.mockResolvedValueOnce('green'); + const visitor = new ResolverVisitor(null, { frog: 'kermit' }, context); + await expect(visitor.downward(['frog'])).resolves.toEqual({ + frog: 'green' + }); + expect(context.get).toHaveBeenCalledWith('kermit'); +}); diff --git a/packages/upward-js/lib/__tests__/buildResponse.test.js b/packages/upward-js/lib/__tests__/buildResponse.test.js new file mode 100644 index 00000000000..d1384228fc2 --- /dev/null +++ b/packages/upward-js/lib/__tests__/buildResponse.test.js @@ -0,0 +1,137 @@ +const buildResponse = require('../buildResponse'); +const { getScenarios } = require('@magento/upward-spec'); + +let scenarios, mockIO; +beforeAll(async () => { + scenarios = await getScenarios(/static\-servers/); + mockIO = { + readFile: jest.fn(scenarios.getResource) + }; +}); + +const stubRequest = () => ({ + url: 'http://example.com/nowhere?special', + query: { + special: undefined + }, + headers: { + host: 'example.com', + 'content-type': 'text/plain' + }, + get(header) { + return this.headers[header]; + } +}); + +test('builds a response from a static definition', async () => { + const definition = await scenarios.getDefinition('hello-inline-only'); + return expect( + buildResponse(mockIO, process.env, definition, stubRequest()) + ).resolves.toMatchObject({ + status: 200, + headers: { + 'content-type': 'text/plain' + }, + body: 'Hello World!!' + }); +}); + +test('handles implicit resolvers', async () => { + const definition = await scenarios.getDefinition( + 'hello-inline-implicit-resolvers' + ); + return expect( + buildResponse(mockIO, process.env, definition, stubRequest()) + ).resolves.toMatchObject({ + status: 200, + headers: { + 'content-type': 'text/plain' + }, + body: 'Hello World, concisely!!' + }); +}); + +test('handles env interpolation', async () => { + const definition = await scenarios.getDefinition('hello-env-interpolation'); + return expect( + buildResponse( + mockIO, + { UPWARD_TEST_RESPONSE_BODY: 'Hello, environment!' }, + definition, + stubRequest() + ) + ).resolves.toMatchObject({ + status: 200, + headers: { + 'content-type': 'text/plain' + }, + body: 'Hello, environment!' + }); +}); + +test('handles inline templates', async () => { + const definition = await scenarios.getDefinition( + 'hello-env-inline-template' + ); + return expect( + buildResponse(mockIO, { ADDRESSEE: 'Earth' }, definition, stubRequest()) + ).resolves.toMatchObject({ + status: 200, + headers: { + 'content-type': 'text/plain' + }, + body: 'Hello, environment of Earth!!' + }); +}); + +test('handles file resolvers and context interpolation', async () => { + const definition = await scenarios.getDefinition( + 'hello-env-context-file-template' + ); + return expect( + buildResponse(mockIO, { sender: 'world' }, definition, stubRequest()) + ).resolves.toMatchObject({ + status: 200, + headers: { + 'content-type': 'text/plain' + }, + body: 'Hello from a world of external templates!!' + }); +}); + +test('handles deep template resolvers, can return json', async () => { + const definition = await scenarios.getDefinition( + 'hello-context-inline-template-json' + ); + const response = await buildResponse( + mockIO, + { + ADDRESSEE: 'deep space' + }, + definition, + stubRequest() + ); + expect(response).toMatchObject({ + status: 200, + headers: { + 'content-type': 'application/json' + } + }); + expect(response.body).toEqual( + JSON.stringify({ + greeting: 'Hello', + subject: 'the depths of deep space...', + shouldYouReallyHandwriteJSON: 'no' + }) + ); +}); + +// test.skip('makes GQL queries'); + +// test.skip('conditionally resolves'); + +// test.skip('conditional resolution falls through in order'); + +// test.skip('conditional resolution yields to default'); + +// test.skip('responds to request data'); diff --git a/packages/upward-js/lib/__tests__/envToConfig.test.js b/packages/upward-js/lib/__tests__/envToConfig.test.js new file mode 100644 index 00000000000..ab6013f5960 --- /dev/null +++ b/packages/upward-js/lib/__tests__/envToConfig.test.js @@ -0,0 +1,16 @@ +const envToConfig = require('../envToConfig'); + +test('converts namespaced env vars to config object and casts values', () => { + Object.assign(process.env, { + UPWARD_JS_ONE_TWO: 'false', + UPWARD_JS_THREE_FOUR: 'trUE', + UPWARD_JS_FIVE_SIX_SEVEN: '9.4', + UPWARD_JS_EIGHTNINE: 'eight and nine' + }); + expect(envToConfig()).toEqual({ + oneTwo: false, + threeFour: true, + fiveSixSeven: 9.4, + eightnine: 'eight and nine' + }); +}); diff --git a/packages/upward-js/lib/__tests__/server.test.js b/packages/upward-js/lib/__tests__/server.test.js new file mode 100644 index 00000000000..b178769a1e5 --- /dev/null +++ b/packages/upward-js/lib/__tests__/server.test.js @@ -0,0 +1,35 @@ +jest.mock('morgan', () => () => (_, __, next) => next()); +const { Server } = require('http'); +const supertest = require('supertest'); +const { getScenarios } = require('@magento/upward-spec'); +const createUpwardServer = require('../createUpwardServer'); + +let upwardPath; +beforeAll(async () => { + upwardPath = (await getScenarios(/static\-servers/)).getResourcePath( + 'hello-inline-only.yml' + ); +}); + +test('returns app alone if bindLocal is false', async () => { + const { app, server } = await createUpwardServer({ upwardPath }); + expect(app).toBeTruthy(); + expect(server).not.toBeDefined(); +}); + +test('returns app and server if bindLocal is true', async () => { + const { app, server, close } = await createUpwardServer({ + upwardPath, + bindLocal: true + }); + expect(app).toBeTruthy(); + expect(server).toBeInstanceOf(Server); + await close(); +}); + +test('responds to requests based on UPWARD config', async () => { + const { app } = await createUpwardServer({ upwardPath }); + const response = await supertest(app).get('/article?articleId=1'); + expect(response.statusCode).toBe(200); + expect(response.text).toEqual('Hello World!!'); +}); diff --git a/packages/upward-js/lib/buildResponse.js b/packages/upward-js/lib/buildResponse.js new file mode 100644 index 00000000000..b785e581454 --- /dev/null +++ b/packages/upward-js/lib/buildResponse.js @@ -0,0 +1,34 @@ +const debug = require('debug')('upward-js:buildResponse'); +const { isPlainObject } = require('lodash'); +const ResolverVisitor = require('./ResolverVisitor'); +const Context = require('./Context'); + +async function buildResponse(io, env, rootDefinition, request) { + debug('creating Context'); + const requestContext = Context.fromRequest(env, request); + debug('creating ResolverVisitor'); + const visitor = new ResolverVisitor(io, rootDefinition, requestContext); + debug('visiting for status, headers, and body'); + try { + const responseData = await visitor.downward([ + 'status', + 'headers', + 'body' + ]); + if (isPlainObject(responseData)) { + debug('successfully built response, %O', responseData); + return { + status: Number(responseData.status), + headers: responseData.headers, + body: responseData.body + }; + } else { + debug('visitor returned request-handling middleware'); + return responseData; + } + } catch (e) { + throw new Error(e.stack); + } +} + +module.exports = buildResponse; diff --git a/packages/upward-js/lib/compiledResources/AbstractCompiledResource.js b/packages/upward-js/lib/compiledResources/AbstractCompiledResource.js new file mode 100644 index 00000000000..6f625134044 --- /dev/null +++ b/packages/upward-js/lib/compiledResources/AbstractCompiledResource.js @@ -0,0 +1,33 @@ +class AbstractCompiledResource { + static get supportedExtensions() { + throw new Error( + 'Internal error: CompiledResources must define static supported file extensions.' + ); + } + constructor(source, io) { + if (this.constructor === AbstractCompiledResource) { + throw new Error( + 'Internal error: Cannot instantiate AbstractCompiledResource directly' + ); + } + if (typeof source !== 'string') { + throw new Error( + `Must construct a CompiledResource with string source. Was supplied a ${typeof source}: ${source}` + ); + } + this.source = source; + this.io = io; + } + async compile() { + throw new Error( + 'Internal error: CompiledResources must define a compile method.' + ); + } + async render() { + throw new Error( + 'Internal error: CompiledResources must define a render method.' + ); + } +} + +module.exports = AbstractCompiledResource; diff --git a/packages/upward-js/lib/compiledResources/GraphQLDocument.js b/packages/upward-js/lib/compiledResources/GraphQLDocument.js new file mode 100644 index 00000000000..ebe78608b4c --- /dev/null +++ b/packages/upward-js/lib/compiledResources/GraphQLDocument.js @@ -0,0 +1,16 @@ +const AbstractCompiledResource = require('./AbstractCompiledResource'); +const gql = require('graphql-tag'); + +class GraphQLDocument extends AbstractCompiledResource { + static get supportedExtensions() { + return ['.graphql', '.gql']; + } + async compile() { + this._contents = gql(this.source); + } + async render() { + return this._contents; + } +} + +module.exports = GraphQLDocument; diff --git a/packages/upward-js/lib/compiledResources/MustacheTemplate.js b/packages/upward-js/lib/compiledResources/MustacheTemplate.js new file mode 100644 index 00000000000..f0bc0eedda4 --- /dev/null +++ b/packages/upward-js/lib/compiledResources/MustacheTemplate.js @@ -0,0 +1,100 @@ +const { inspect } = require('util'); +const AbstractCompiledResource = require('./AbstractCompiledResource'); +const Hogan = require('hogan.js'); + +class MustacheTemplate extends AbstractCompiledResource { + static get supportedExtensions() { + return ['.mst', '.mustache', '.tpt']; + } + constructor(...args) { + super(...args); + if (!this.io) { + throw new Error('IOInterface as second argument'); + } + if (typeof this.io.readFile !== 'function') { + throw new Error( + `IOInterface missing readFile method: ${inspect(this.io)}` + ); + } + this._loadedPartials = new Map(); + } + _tryLoadAllExtensions( + name, + extensions = MustacheTemplate.supportedExtensions + ) { + return this.io.readFile(name + extensions[0], 'utf8').catch(e => { + if (e.code !== 'ENOENT' || extensions.length === 1) { + throw e; + } + return this._tryLoadAllExtensions(name, extensions.slice(1)); + }); + } + _findUnloadedPartialNames(template) { + const partialNames = Object.values(template.partials).map( + ({ name }) => name + ); + const uniquePartialNames = [...new Set(partialNames)]; + return uniquePartialNames.filter( + name => !this._loadedPartials.has(name) + ); + } + async _loadPartial(name) { + let partial = this._loadedPartials.get(name); + if (!partial) { + try { + partial = Hogan.compile( + (await this._tryLoadAllExtensions(name)).trim() + ); + this._loadedPartials.set(name, partial); + } catch (error) { + return { badPartial: { name, error } }; + } + } + return partial; + } + async _loadPartials(partialNames) { + const loadedPartials = await Promise.all( + partialNames.map(name => this._loadPartial(name)) + ); + + const badPartials = loadedPartials.filter( + ({ badPartial }) => badPartial + ); + if (badPartials.length > 0) { + const partialErrors = badPartials.map( + ({ badPartial: { name, error } }) => + `'${name}: ${error.stack}\n` + ); + throw new Error(`Error in template partials: ${partialErrors}`); + } + + const foundDescendentPartials = loadedPartials.reduce( + (found, tpt) => found.concat(this._findUnloadedPartialNames(tpt)), + [] + ); + + if (foundDescendentPartials.length > 0) { + return await this._loadPartials([ + ...new Set(foundDescendentPartials) + ]); + } + } + async compile() { + this._template = Hogan.compile(this.source); + + // recursively load all descendent partials ahead of time + await this._loadPartials( + this._findUnloadedPartialNames(this._template) + ); + + this._partials = {}; + for (const [name, tpt] of this._loadedPartials.entries()) { + this._partials[name] = tpt; + } + } + async render(context) { + return this._template.render(context, this._partials, '').trim(); + } +} + +module.exports = MustacheTemplate; diff --git a/packages/upward-js/lib/compiledResources/__tests__/AbstractCompiledResource.test.js b/packages/upward-js/lib/compiledResources/__tests__/AbstractCompiledResource.test.js new file mode 100644 index 00000000000..5369aecf9df --- /dev/null +++ b/packages/upward-js/lib/compiledResources/__tests__/AbstractCompiledResource.test.js @@ -0,0 +1,35 @@ +const AbstractCompiledResource = require('../AbstractCompiledResource'); + +test('requires override to static supportedExtensions getter', () => { + expect(() => AbstractCompiledResource.supportedExtensions).toThrow( + 'must define static supported' + ); +}); + +test('cannot be directly instantiated', () => { + expect(() => new AbstractCompiledResource()).toThrow('Cannot instantiate'); +}); + +test('sets source and io properties from constructor args', () => { + const source = ''; + const io = {}; + const compiler = new class extends AbstractCompiledResource {}(source, io); + expect(compiler.source).toBe(source); + expect(compiler.io).toBe(io); +}); + +test('throws if it receives no source argument', () => { + expect(() => new class extends AbstractCompiledResource {}()).toThrow( + 'string source' + ); +}); + +test('requires override to compile method', () => { + const rsrc = new class extends AbstractCompiledResource {}(''); + expect(rsrc.compile()).rejects.toThrow('must define a compile'); +}); + +test('requires override to render method', () => { + const rsrc = new class extends AbstractCompiledResource {}(''); + expect(rsrc.render()).rejects.toThrow('must define a render'); +}); diff --git a/packages/upward-js/lib/compiledResources/__tests__/GraphQLDocument.test.js b/packages/upward-js/lib/compiledResources/__tests__/GraphQLDocument.test.js new file mode 100644 index 00000000000..bef6e2d2350 --- /dev/null +++ b/packages/upward-js/lib/compiledResources/__tests__/GraphQLDocument.test.js @@ -0,0 +1,97 @@ +const GraphQLDocument = require('../GraphQLDocument'); +const AbstractCompiledResource = require('../AbstractCompiledResource'); + +test('extends AbstractCompiledResource concretely', () => { + const instantiate = () => new GraphQLDocument('', {}); + expect(instantiate).not.toThrow(); + expect(instantiate()).toBeInstanceOf(AbstractCompiledResource); +}); + +test('supported extensions include standard .graphql', () => { + expect(GraphQLDocument.supportedExtensions).toContain('.graphql'); +}); + +test('compiles GraphQL documents', async () => { + const doc = new GraphQLDocument(` + { + foos(bar: 1) { + mahna + } + } + `); + await expect(doc.compile()).resolves.not.toThrow(); + await expect(doc.render()).resolves.toMatchInlineSnapshot(` +Object { + "definitions": Array [ + Object { + "directives": Array [], + "kind": "OperationDefinition", + "name": undefined, + "operation": "query", + "selectionSet": Object { + "kind": "SelectionSet", + "selections": Array [ + Object { + "alias": undefined, + "arguments": Array [ + Object { + "kind": "Argument", + "name": Object { + "kind": "Name", + "value": "bar", + }, + "value": Object { + "kind": "IntValue", + "value": "1", + }, + }, + ], + "directives": Array [], + "kind": "Field", + "name": Object { + "kind": "Name", + "value": "foos", + }, + "selectionSet": Object { + "kind": "SelectionSet", + "selections": Array [ + Object { + "alias": undefined, + "arguments": Array [], + "directives": Array [], + "kind": "Field", + "name": Object { + "kind": "Name", + "value": "mahna", + }, + "selectionSet": undefined, + }, + ], + }, + }, + ], + }, + "variableDefinitions": Array [], + }, + ], + "kind": "Document", + "loc": Object { + "end": 112, + "start": 0, + }, +} +`); +}); + +test('fails on illegal graphql documents', async () => { + const compiler = new GraphQLDocument(` + # missing open curly + foos(bar: 1) { + mahna + } + } + `); + await expect(compiler.compile()).rejects.toThrowErrorMatchingInlineSnapshot( + `"Syntax Error: Unexpected Name \\"foos\\""` + ); +}); diff --git a/packages/upward-js/lib/compiledResources/__tests__/MustacheTemplate.test.js b/packages/upward-js/lib/compiledResources/__tests__/MustacheTemplate.test.js new file mode 100644 index 00000000000..73b987596f4 --- /dev/null +++ b/packages/upward-js/lib/compiledResources/__tests__/MustacheTemplate.test.js @@ -0,0 +1,145 @@ +const MustacheTemplate = require('../MustacheTemplate'); +const AbstractCompiledResource = require('../AbstractCompiledResource'); + +test('supported extensions include standard .mst and .mustache', () => { + expect(MustacheTemplate.supportedExtensions).toEqual( + expect.arrayContaining(['.mst', '.mustache']) + ); +}); + +test('extends AbstractCompiledResource concretely', () => { + const io = { + readFile: () => {} + }; + const instantiate = () => new MustacheTemplate('', io); + expect(instantiate).not.toThrow(); + expect(instantiate()).toBeInstanceOf(AbstractCompiledResource); +}); + +test('throws if IOInterface is not present or lacks methods at constructor time', () => { + expect(() => new MustacheTemplate('')).toThrow( + 'IOInterface as second argument' + ); + expect(() => new MustacheTemplate('', { networkFetch() {} })).toThrow( + 'missing readFile' + ); +}); + +test('compiles Mustache ', async () => { + const template = new MustacheTemplate( + ` + {{#existenz}} + Existenz is {{status}}! + {{/existenz}} + {{^existenz}} + What, you hate Cronenberg? + {{/existenz}} + `, + { readFile: () => {} } + ); + await expect(template.compile()).resolves.not.toThrow(); + await expect( + template.render({ existenz: { status: 'paused' } }) + ).resolves.toMatchInlineSnapshot(`"Existenz is paused!"`); + await expect( + template.render({ + existenz: [ + { status: 'a movie with a weird goop gun in it' }, + { status: 'overshadowed by The Matrix' } + ] + }) + ).resolves.toMatchInlineSnapshot(` +"Existenz is a movie with a weird goop gun in it! + Existenz is overshadowed by The Matrix!" +`); + await expect(template.render({})).resolves.toMatchInlineSnapshot( + `"What, you hate Cronenberg?"` + ); + await expect(template.render()).resolves.toMatchInlineSnapshot( + `"What, you hate Cronenberg?"` + ); +}); + +test('loads Mustache partials using io', async () => { + const io = { + readFile: jest.fn( + async name => + `

Hello {{addressee}}, I am the template called ${name}!

` + ) + }; + const template = new MustacheTemplate( + ` +

Important announcements!

+ {{> firstPartial}} + {{> secondPartial}} + `, + io + ); + await expect(template.compile()).resolves.not.toThrow(); + await expect(template.render({ addressee: 'unit test' })).resolves + .toMatchInlineSnapshot(` +"

Important announcements!

+

Hello unit test, I am the template called firstPartial.mst!

Hello unit test, I am the template called secondPartial.mst!

" +`); + expect(io.readFile).toHaveBeenCalledTimes(2); + expect(io.readFile.mock.calls).toMatchObject([ + ['firstPartial.mst', 'utf8'], + ['secondPartial.mst', 'utf8'] + ]); +}); + +test('loads descendent partials using io', async () => { + const io = { + readFile: jest.fn(async name => { + if (name.indexOf('subPartial') !== -1) { + return `I'm a subpartial, {{addressee}}!!`; + } + return `

Hello {{addressee}}, I am the template called ${name}, and I have sub-partials!

{{> subPartial}}`; + }) + }; + const template = new MustacheTemplate( + ` +

Important announcements!

+ {{> firstPartial}} + {{> secondPartial}} +`, + io + ); + await expect(template.compile()).resolves.not.toThrow(); + await expect(template.render({ addressee: 'unit test' })).resolves + .toMatchInlineSnapshot(` +"

Important announcements!

+

Hello unit test, I am the template called firstPartial.mst, and I have sub-partials!

I'm a subpartial, unit test!!

Hello unit test, I am the template called secondPartial.mst, and I have sub-partials!

I'm a subpartial, unit test!!" +`); + expect(io.readFile).toHaveBeenCalledTimes(3); + expect(io.readFile.mock.calls).toMatchObject([ + ['firstPartial.mst', 'utf8'], + ['secondPartial.mst', 'utf8'], + ['subPartial.mst', 'utf8'] + ]); +}); + +test('handles missing partials', async () => { + const io = { + readFile: jest.fn(async () => + Promise.reject(new Error('Everything is very bad')) + ) + }; + const template = new MustacheTemplate( + `{{> aPartial}} will never exist`, + io + ); + await expect(template.compile()).rejects.toThrowError( + 'Error in template partials' + ); +}); + +test('handles partial errors', async () => { + const io = { + readFile: jest.fn(async () => '{{/katzs}} never closes!i809ula/sn') + }; + const template = new MustacheTemplate(`{{> aPartial }} ought to close`, io); + await expect(template.compile()).rejects.toThrowError( + 'Error in template partials' + ); +}); diff --git a/packages/upward-js/lib/compiledResources/__tests__/forFileOfType.test.js b/packages/upward-js/lib/compiledResources/__tests__/forFileOfType.test.js new file mode 100644 index 00000000000..aad0bc52174 --- /dev/null +++ b/packages/upward-js/lib/compiledResources/__tests__/forFileOfType.test.js @@ -0,0 +1,17 @@ +const { forFileOfType, GraphQLDocument, MustacheTemplate } = require('../'); + +test('returns constructor for a given file extension', () => { + expect(forFileOfType('.graphql')).toBe(GraphQLDocument); + expect(forFileOfType('.gql')).toBe(GraphQLDocument); + expect(forFileOfType('.mst')).toBe(MustacheTemplate); +}); + +test('returns constructor for a filename', () => { + expect(forFileOfType('/Somewhere/somequery.graphql')).toBe(GraphQLDocument); + expect(forFileOfType('/SomewhereElse/document.gql')).toBe(GraphQLDocument); + expect(forFileOfType('someTpt.mst')).toBe(MustacheTemplate); +}); + +test('returns undefined for unsupported file type', () => { + expect(forFileOfType('.pif')).toBeUndefined(); +}); diff --git a/packages/upward-js/lib/compiledResources/index.js b/packages/upward-js/lib/compiledResources/index.js new file mode 100644 index 00000000000..c1f042a3796 --- /dev/null +++ b/packages/upward-js/lib/compiledResources/index.js @@ -0,0 +1,23 @@ +const { extname, normalize } = require('path'); +const CompiledResources = { + GraphQLDocument: require('./GraphQLDocument'), + MustacheTemplate: require('./MustacheTemplate') +}; + +const byExtension = new Map(); + +for (const Resource of Object.values(CompiledResources)) { + for (const extension of Resource.supportedExtensions) { + byExtension.set(extension, Resource); + } +} + +module.exports = Object.assign(CompiledResources, { + forFileOfType(filenameOrExtension) { + const normalized = normalize(filenameOrExtension); + const extension = normalized.startsWith('.') + ? normalized + : extname(normalized); + return byExtension.get(extension); + } +}); diff --git a/packages/upward-js/lib/createUpwardServer.js b/packages/upward-js/lib/createUpwardServer.js new file mode 100644 index 00000000000..3c61921b9dc --- /dev/null +++ b/packages/upward-js/lib/createUpwardServer.js @@ -0,0 +1,91 @@ +/** + * Standalone server script which creates an Express server, configures and + * binds it according to configuration, and applies the upward-js middleware. + */ + +const { resolve } = require('path'); +const express = require('express'); +const middleware = require('./middleware'); +const debugErrorMiddleware = require('debug-error-middleware').express; +const morgan = require('morgan'); + +/** + * Create an upward-js standalone server and optionally bind it to a local + * address. Configure logging and debugging middleware depending on standard + * detection of environment: `process.env.NODE_ENV` === 'production'. + * + * ### `createUpwardServer` Configuration Options + * + * | Property | Type | Default | Description + * | -------- | ---- | ------- | ----------- + * |`upwardPath` | `string` | | Path, relative to the current directory, of a YML file with an UPWARD configuration. **Required**. + * |`bindLocal` | `boolean` | `false` | Create and bind an HTTP server before returning. + * |`port` | `number` | `0` | Specify the port to be bound. `0` means the first open port. + * |`host` | `string` | `0.0.0.0` | Specify the host on which to listen. `0.0.0.0` means all local IPv4 requests. + * |`https` | `object` | | To bind an HTTPS server instead of HTTP, pass a valid `{ key, cert }` object here. + * |`logUrl` | `boolean` | `false` | Log the bound URL to stdout (mostly used for testing against upward-spec) + * + * Returns a plain object with the following properties: + * an `app` property. This is an Express + * + * + * @param {object} config Configuration object. + * @return Promise `{ app, server?, close? }` + */ +async function createUpwardServer({ + bindLocal = false, + port = 0, + host = '0.0.0.0', + https, + logUrl = false, + upwardPath +}) { + if (!upwardPath) { + throw new Error(`upwardPath is required`); + } + const app = express(); + const upward = await middleware(resolve(upwardPath)); + if (process.env.NODE_ENV === 'production') { + app.use(morgan('combined')); + app.use(upward); + } else { + app.use(morgan('dev')); + app.use(upward); + app.use(debugErrorMiddleware()); + } + if (bindLocal) { + return new Promise((resolve, reject) => { + try { + const protocol = https ? 'https' : 'http'; + const server = https + ? require('https').createServer(https, app) + : require('http').createServer(app); + + server.listen(port, host); + + server.on('listening', () => { + if (logUrl) { + console.log( + `${protocol}://${host}:${server.address().port}/` + ); + } + resolve({ + app, + server, + close() { + return new Promise(resolve => { + server.on('close', resolve); + server.close(); + }); + } + }); + }); + } catch (e) { + reject(e); + } + }); + } + return { app }; +} + +module.exports = createUpwardServer; diff --git a/packages/upward-js/lib/envToConfig.js b/packages/upward-js/lib/envToConfig.js new file mode 100644 index 00000000000..2a8b4a0948b --- /dev/null +++ b/packages/upward-js/lib/envToConfig.js @@ -0,0 +1,50 @@ +const decimalRE = /^\d*\.?\d+$/; +function castValue(value) { + const boolStrings = { + false: false, + true: true + }; + const lowered = value.toString().toLowerCase(); + if (boolStrings.hasOwnProperty(lowered)) { + return boolStrings[lowered]; + } + if (decimalRE.test(value)) { + return Number(value); + } + return value; +} + +const envPrefix = 'UPWARD_JS_'; +// Parse and camelcast all environment variables beginning with a prefix. +function envToConfig() { + return Object.entries(process.env).reduce((cfg, [key, value]) => { + if (key.startsWith(envPrefix)) { + const camelCased = key + .slice(envPrefix.length) + .toLowerCase() + .replace(/_[a-z]/g, match => match.charAt(1).toUpperCase()); + cfg[camelCased] = castValue(value); + } + return cfg; + }, {}); +} + +module.exports = envToConfig; + +/** + * const config = envToConfig('UPWARD_JS_'); + * + * UPWARD_JS_BIND_LOCAL=true \ + * UPWARD_JS_FOO=FALSE \ + * UPWARD_JS_FOO_BAR=9.5 \ + * UPWARD_JS_UPWARD_PATH='./path' + * + * becomes + * + * { + * bindLocal: true, + * foo: false, + * fooBar: 9.5, + * upwardPath: './path' + * } + */ diff --git a/packages/upward-js/lib/index.js b/packages/upward-js/lib/index.js new file mode 100644 index 00000000000..8baecfca997 --- /dev/null +++ b/packages/upward-js/lib/index.js @@ -0,0 +1,6 @@ +module.exports = { + IOAdapter: require('./IOAdapter'), + middleware: require('./middleware'), + createUpwardServer: require('./createUpwardServer'), + envToConfig: require('./envToConfig') +}; diff --git a/packages/upward-js/lib/isPrimitive.js b/packages/upward-js/lib/isPrimitive.js new file mode 100644 index 00000000000..9fb1c8dffd6 --- /dev/null +++ b/packages/upward-js/lib/isPrimitive.js @@ -0,0 +1,4 @@ +const { isBoolean, isFinite, isString } = require('lodash'); + +const isPrimitive = v => isBoolean(v) || isString(v) || isFinite(v); +module.exports = isPrimitive; diff --git a/packages/upward-js/lib/middleware.js b/packages/upward-js/lib/middleware.js new file mode 100644 index 00000000000..9593c665346 --- /dev/null +++ b/packages/upward-js/lib/middleware.js @@ -0,0 +1,98 @@ +const debug = require('debug')('upward-js:middleware'); +const jsYaml = require('js-yaml'); +const UpwardServerError = require('./UpwardServerError'); +const IOAdapter = require('./IOAdapter'); +const buildResponse = require('./buildResponse'); + +class UpwardMiddleware { + constructor(upwardPath, io) { + this.upwardPath = upwardPath; + debug(`created for path ${upwardPath}`); + this.io = io; + } + async load() { + const { upwardPath } = this; + try { + this.yamlTxt = await this.io.readFile(upwardPath); + } catch (e) { + throw new UpwardServerError(e, `unable to read file ${upwardPath}`); + } + debug(`read upward.yml file successfully`); + try { + this.definition = await jsYaml.safeLoad(this.yamlTxt); + } catch (e) { + throw new UpwardServerError( + e, + `error parsing ${upwardPath} contents: \n\n${this.yamlTxt}` + ); + } + debug(`parsed upward.yml file successfully: %o`, this.definition); + } + async getHandler() { + return async (req, res, next) => { + const errors = []; + let response; + try { + response = await buildResponse( + this.io, + process.env, + this.definition, + req + ); + if (typeof response === 'function') { + debug('buildResponse returned function'); + response(req, res, next); + return; + } + if (isNaN(response.status)) { + errors.push( + `Non-numeric status! Status was '${response.status}'` + ); + } + if (typeof response.headers !== 'object') { + errors.push( + `Resolved with a non-compliant headers object! Headers are: ${ + response.headers + }` + ); + } + if (typeof response.body !== 'string') { + errors.push( + `Resolved with a non-string body! Body was '${ + response.body + }'` + ); + } + } catch (e) { + errors.push(e.stack); + } + if (errors.length > 0) { + next( + new UpwardServerError( + `Request did not evaluate to a valid response, because: \n${errors.join( + '\n' + )}` + ) + ); + } else { + debug('status, headers, and body valid. responding'); + res.status(response.status) + .set(response.headers) + .send(response.body); + } + }; + } +} + +async function upwardJSMiddlewareFactory( + upwardPath, + io = IOAdapter.default(upwardPath) +) { + const middleware = new UpwardMiddleware(upwardPath, io); + await middleware.load(); + return middleware.getHandler(); +} + +upwardJSMiddlewareFactory.UpwardMiddleware = UpwardMiddleware; + +module.exports = upwardJSMiddlewareFactory; diff --git a/packages/upward-js/lib/resolvers/AbstractResolver.js b/packages/upward-js/lib/resolvers/AbstractResolver.js new file mode 100644 index 00000000000..4f250953e7a --- /dev/null +++ b/packages/upward-js/lib/resolvers/AbstractResolver.js @@ -0,0 +1,17 @@ +class AbstractResolver { + static get resolverType() { + throw new Error( + 'Internal error: Resolvers must define a static resolverType getter' + ); + } + constructor(visitor) { + this.visitor = visitor; + } + resolve() { + throw new Error( + 'Internal error: Resolvers must define a resolve() method' + ); + } +} + +module.exports = AbstractResolver; diff --git a/packages/upward-js/lib/resolvers/ConditionalResolver.js b/packages/upward-js/lib/resolvers/ConditionalResolver.js new file mode 100644 index 00000000000..f8bb5c6f8b7 --- /dev/null +++ b/packages/upward-js/lib/resolvers/ConditionalResolver.js @@ -0,0 +1,58 @@ +const debug = require('debug')('upward-js:ConditionalResolver'); +const AbstractResolver = require('./AbstractResolver'); + +class ConditionalResolver extends AbstractResolver { + static get resolverType() { + return 'conditional'; + } + static get telltale() { + return 'when'; + } + async resolve(definition) { + if ( + !definition.when || + !Array.isArray(definition.when) || + definition.when.length === 0 + ) { + throw new Error( + `ConditionalResolver must a 'when' list, with at least one matcher.` + ); + } + if (!definition.default) { + throw new Error( + `ConditionalResolver must have a 'default' condition.` + ); + } + this.default = definition.default; + + return this.tryMatchers(definition.when); + } + async tryMatchers([top, ...rest]) { + debug('matching %o with %d left to go', top, rest.length); + const regex = new RegExp(top.pattern); + let candidate = await this.visitor.context.get(top.matches); + if (candidate === null || candidate === undefined) { + candidate = ''; + } + candidate = candidate.toString(); + debug('regex is %s, %s is %s', regex, top.matches, candidate); + const regexMatch = candidate.toString().match(regex); + + if (regexMatch) { + const match = regexMatch.reduce((contextMatch, group, index) => { + contextMatch[`$${index}`] = group || ''; + return contextMatch; + }, {}); + this.visitor.context.set('$match', match, true); + const yielded = await this.visitor.upward(top, 'use'); + this.visitor.context.forget('$match'); + return yielded; + } + if (rest.length === 0) { + return this.visitor.upward(this, 'default'); + } + return this.tryMatchers(rest); + } +} + +module.exports = ConditionalResolver; diff --git a/packages/upward-js/lib/resolvers/DirectoryResolver.js b/packages/upward-js/lib/resolvers/DirectoryResolver.js new file mode 100644 index 00000000000..65d455d43d0 --- /dev/null +++ b/packages/upward-js/lib/resolvers/DirectoryResolver.js @@ -0,0 +1,44 @@ +const debug = require('debug')('upward-js:DirectoryResolver'); +const serveStatic = require('express').static; +const AbstractResolver = require('./AbstractResolver'); + +const AllServers = new Map(); +class DirectoryResolver extends AbstractResolver { + static get resolverType() { + return 'directory'; + } + static get telltale() { + return 'directory'; + } + static get servers() { + return AllServers; + } + async resolve(definition) { + if (!definition.directory) { + throw new Error( + `Directory argument is required: ${JSON.stringify(definition)}` + ); + } + const directory = await this.visitor.upward(definition, 'directory'); + if (typeof directory !== 'string') { + throw new Error( + `'directory' argument to DirectoryResolver must be a string, but was a: ${typeof directory}` + ); + } + debug('resolved directory %s', directory); + + let server = DirectoryResolver.servers.get(directory); + if (!server) { + debug(`creating new server for ${directory}`); + server = serveStatic(directory, { + fallthrough: false, + index: false + }); + DirectoryResolver.servers.set(directory, server); + } + + return server; + } +} + +module.exports = DirectoryResolver; diff --git a/packages/upward-js/lib/resolvers/FileResolver.js b/packages/upward-js/lib/resolvers/FileResolver.js new file mode 100644 index 00000000000..49137dcbb19 --- /dev/null +++ b/packages/upward-js/lib/resolvers/FileResolver.js @@ -0,0 +1,101 @@ +const debug = require('debug')('upward-js:FileResolver'); +const AbstractResolver = require('./AbstractResolver'); +const { forFileOfType } = require('../compiledResources'); + +class FileResolver extends AbstractResolver { + static get resolverType() { + return 'file'; + } + static get telltale() { + return 'file'; + } + static get paramTypes() { + return { + file: { + type: 'string', + required: true + }, + encoding: { + type: 'oneOf', + oneOf: ['utf-8', 'utf8', 'latin1', 'binary'], + default: 'utf-8' + }, + parse: { + type: 'oneOf', + oneOf: ['auto', 'text'], + default: 'auto' + } + }; + } + static recognize(value) { + const str = value.toString(); + const derivedConfig = { file: {} }; + if (str.startsWith('file://')) { + derivedConfig.file.inline = str.slice(7); + } else if (str.startsWith('./') || str.startsWith('../')) { + derivedConfig.file.inline = str; + } + if (derivedConfig.file.inline) { + return derivedConfig; + } + } + async resolve(definition) { + if (!definition.file) { + throw new Error( + `File argument is required: ${JSON.stringify(definition)}` + ); + } + const toResolve = [ + this.visitor.upward(definition, 'file'), + definition.encoding + ? this.visitor.upward(definition, 'encoding') + : 'utf8', + definition.parse ? this.visitor.upward(definition, 'parse') : 'auto' + ]; + const [file, encoding, parse] = await Promise.all(toResolve); + debug( + 'resolved file %s, encoding %s, parse mode %s', + file, + encoding, + parse + ); + const { paramTypes } = this.constructor; + const allowedencodings = paramTypes.encoding.oneOf; + if (!allowedencodings.some(value => encoding === value)) { + throw new Error( + `Invalid 'encoding': ${encoding}. Must be one of ${allowedencodings}` + ); + } + debug('encoding %s is valid', encoding); + const fileText = await this.visitor.io.readFile(file, encoding); + if (encoding !== 'binary') debug('retrieved file text %s', fileText); + if (parse === 'text') { + debug('parse === text, returning file text directly'); + return fileText; + } + let Resource; + if (parse === 'auto') { + debug('parse === auto, detecting from filename %s\n\n\n\n', file); + Resource = forFileOfType(file); + if (!Resource) { + debug( + 'autoparse found no parser for %s, returning text instead', + file + ); + return fileText; + } + } else { + const extension = parse.startsWith('.') ? parse : '.' + parse; + Resource = forFileOfType(extension); + if (!Resource) { + throw new Error(`Unsupported parse type '${parse}'`); + } + } + debug('parse === %s, found %s to compile', parse, Resource.name); + const rsrc = new Resource(fileText, this.visitor.io); + await rsrc.compile(); + return rsrc; + } +} + +module.exports = FileResolver; diff --git a/packages/upward-js/lib/resolvers/InlineResolver.js b/packages/upward-js/lib/resolvers/InlineResolver.js new file mode 100644 index 00000000000..44ab2813864 --- /dev/null +++ b/packages/upward-js/lib/resolvers/InlineResolver.js @@ -0,0 +1,33 @@ +const debug = require('debug')('upward-js:InlineResolver'); +const { fromPairs, isPlainObject } = require('lodash'); +const AbstractResolver = require('./AbstractResolver'); +const isPrimitive = require('../isPrimitive'); + +class InlineResolver extends AbstractResolver { + static get resolverType() { + return 'inline'; + } + static get telltale() { + return 'inline'; + } + async resolve({ inline }) { + if (isPrimitive(inline)) { + debug('quick-resolving primitive %s', inline); + return inline; + } else if (isPlainObject(inline)) { + debug('resolving object %o', inline); + const resolvedEntries = await Promise.all( + Object.keys(inline).map(async key => [ + key, + await this.visitor.upward(inline, key) + ]) + ); + return fromPairs(resolvedEntries); + } + throw new Error( + `Internal error: Invalid value supplied to InlineResolver: ${inline}` + ); + } +} + +module.exports = InlineResolver; diff --git a/packages/upward-js/lib/resolvers/ProxyResolver.js b/packages/upward-js/lib/resolvers/ProxyResolver.js new file mode 100644 index 00000000000..f5e425f0034 --- /dev/null +++ b/packages/upward-js/lib/resolvers/ProxyResolver.js @@ -0,0 +1,56 @@ +const debug = require('debug')('upward-js:ProxyResolver'); +const proxyMiddleware = require('http-proxy-middleware'); +const AbstractResolver = require('./AbstractResolver'); + +const AllServers = new Map(); +class ProxyResolver extends AbstractResolver { + static get resolverType() { + return 'proxy'; + } + static get telltale() { + return 'target'; + } + static get servers() { + return AllServers; + } + async resolve(definition) { + if (!definition.target) { + throw new Error( + `'target' URL argument is required: ${JSON.stringify( + definition + )}` + ); + } + const toResolve = [ + this.visitor.upward(definition, 'target'), + definition.ignoreSSLErrors + ? this.visitor.upward(definition, 'ignoreSSLErrors') + : false + ]; + const [target, ignoreSSLErrors] = await Promise.all(toResolve); + + debug('resolved target %o', target); + if (typeof target !== 'string') { + throw new Error( + `'target' argument to ProxyResolver must be a string URL, but was a: ${typeof target}` + ); + } + + let server = ProxyResolver.servers.get(target); + if (!server) { + debug(`creating new server for ${target}`); + server = proxyMiddleware({ + target, + secure: !ignoreSSLErrors, + changeOrigin: true, + autoRewrite: true, + cookieDomainRewrite: '' + }); + ProxyResolver.servers.set(target, server); + } + + return server; + } +} + +module.exports = ProxyResolver; diff --git a/packages/upward-js/lib/resolvers/ServiceResolver.js b/packages/upward-js/lib/resolvers/ServiceResolver.js new file mode 100644 index 00000000000..08699f9cf6f --- /dev/null +++ b/packages/upward-js/lib/resolvers/ServiceResolver.js @@ -0,0 +1,99 @@ +const debug = require('debug')('upward-js:ServiceResolver'); +const { inspect } = require('util'); +const { execute, makePromise } = require('apollo-link'); +const { HttpLink } = require('apollo-link-http'); +const { isPlainObject } = require('lodash'); +const AbstractResolver = require('./AbstractResolver'); +const GraphQLDocument = require('../compiledResources/GraphQLDocument'); +class ServiceResolver extends AbstractResolver { + static get resolverType() { + return 'service'; + } + static get telltale() { + return 'url'; + } + async resolve(definition) { + const die = msg => { + throw new Error( + `Invalid arguments to ServiceResolver: ${inspect(definition, { + compact: false + })}.\n\n${msg}` + ); + }; + if (!definition.url) { + die('No URL specified.'); + } + if (!definition.query) { + die('No GraphQL query document specified.'); + } + debug('validated config %o', definition); + const toResolve = [ + this.visitor.upward(definition, 'url'), + this.visitor.upward(definition, 'query'), + definition.method + ? this.visitor.upward(definition, 'method') + : 'POST', + definition.headers + ? this.visitor.upward(definition, 'headers') + : {}, + definition.variables + ? this.visitor.upward(definition, 'variables') + : {} + ]; + + const [url, query, method, headers, variables] = await Promise.all( + toResolve + ); + + if (variables && !isPlainObject(variables)) { + die(`Variables must resolve to a plain object.`); + } + + debug('url retrieved: "%s", query resolved, creating link', url); + + const link = new HttpLink({ + uri: url, + fetch: this.visitor.io.networkFetch, + headers, + useGETForQueries: method === 'GET' + }); + + let parsedQuery; + if (typeof query === 'string') { + parsedQuery = new GraphQLDocument(query, this.visitor.io); + await parsedQuery.compile(); + } else if (query instanceof GraphQLDocument) { + parsedQuery = query; + } else { + throw new Error(`Unknown type passed to 'query'.`); + } + + debug('running query with %o', variables); + return makePromise( + execute(link, { query: await parsedQuery.render(), variables }) + ) + .then(({ data, errors }) => { + debug( + 'query %s with %o resulted in %o', + definition.query, + variables, + { data, errors } + ); + if (errors && errors.length > 0) { + throw new Error(errors[0].message); + } else { + return { data }; + } + }) + .catch(e => { + if ( + e.message.indexOf('Only absolute URLs are supported') !== -1 + ) { + throw new Error(url.toString() + 'invalid: ' + e.stack); + } + throw e; + }); + } +} + +module.exports = ServiceResolver; diff --git a/packages/upward-js/lib/resolvers/TemplateResolver.js b/packages/upward-js/lib/resolvers/TemplateResolver.js new file mode 100644 index 00000000000..363c38a7b3a --- /dev/null +++ b/packages/upward-js/lib/resolvers/TemplateResolver.js @@ -0,0 +1,108 @@ +const debug = require('debug')('upward-js:TemplateResolver'); +const { inspect } = require('util'); +const { fromPairs, isPlainObject } = require('lodash'); +const AbstractResolver = require('./AbstractResolver'); +const MustacheTemplate = require('../compiledResources/MustacheTemplate'); +const Engines = { + mustache: MustacheTemplate +}; +module.exports = class TemplateResolver extends AbstractResolver { + static get resolverType() { + return 'template'; + } + static get telltale() { + return 'engine'; + } + async resolve(definition) { + let providePromise; + const die = msg => { + throw new Error( + `Invalid arguments to TemplateResolver: ${inspect(definition, { + compact: false + })}.\n\n${msg}` + ); + }; + if (!definition.template) { + die('No template specified.'); + } + if (!definition.provide) { + die( + `'provide' property must be an array of context values or object of resolvable definitions, was ${inspect( + definition.provide + )}` + ); + } else if (Array.isArray(definition.provide)) { + if (definition.provide.some(value => typeof value != 'string')) { + die( + `'provide' property must be an array of context values or object of resolvable definitions, was ${inspect( + definition.provide + )}` + ); + } else { + providePromise = Promise.all( + definition.provide.map(async name => [ + name, + await this.visitor.context.get(name) + ]) + ); + } + } else if (isPlainObject(definition.provide)) { + providePromise = Promise.all( + Object.keys(definition.provide).map(async name => [ + name, + await this.visitor.upward(definition.provide, name) + ]) + ); + } else { + die(`Unrecognized 'provide' configuration: ${definition.provide}`); + } + debug('validated config %o', definition); + const toResolve = [ + this.visitor.upward(definition, 'engine'), + this.visitor.upward(definition, 'template'), + providePromise + ]; + + let [engine, template, rootEntries] = await Promise.all(toResolve); + debug('template retrieved, "%s"', template); + debug('rootEntries retrieved, %o', rootEntries.map(([name]) => name)); + + if (!engine) { + engine = 'mustache'; + } + + const Engine = Engines[engine]; + + if (!Engine) { + throw new Error(`Template engine '${engine}' unsupported`); + } + debug('got template engine %s', Engine.name); + + let renderer; + if (template instanceof Engine) { + debug( + 'how nice, the template is already resolved into a %s for us', + Engine.name + ); + renderer = template; + } else if (typeof template === 'string') { + debug('template is a string, creating %s', Engine.name); + renderer = new Engine(template, this.visitor.io); + } else { + throw new Error( + `Expected string or ${ + Engine.name + }-compatible template and received a foreign object ${ + template.constructor.name + }!` + ); + } + + debug('created renderer'); + + await renderer.compile(); + debug('renderer compiled'); + + return renderer.render(fromPairs(rootEntries)); + } +}; diff --git a/packages/upward-js/lib/resolvers/__tests__/AbstractResolver.test.js b/packages/upward-js/lib/resolvers/__tests__/AbstractResolver.test.js new file mode 100644 index 00000000000..f7b104e5a57 --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/AbstractResolver.test.js @@ -0,0 +1,9 @@ +const AbstractResolver = require('../AbstractResolver'); + +test('static resolverType must be implemented', () => { + expect(() => AbstractResolver.resolverType).toThrow('static resolverType'); +}); + +test('resolve must be implemented', () => { + expect(() => new AbstractResolver().resolve()).toThrow('resolve'); +}); diff --git a/packages/upward-js/lib/resolvers/__tests__/ConditionalResolver.test.js b/packages/upward-js/lib/resolvers/__tests__/ConditionalResolver.test.js new file mode 100644 index 00000000000..611951a0dad --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/ConditionalResolver.test.js @@ -0,0 +1,158 @@ +const ConditionalResolver = require('../ConditionalResolver'); + +test('resolverType is conditional', () => + expect(ConditionalResolver.resolverType).toBe('conditional')); + +test('telltale exists', () => + expect(ConditionalResolver.telltale).toBe('when')); + +test(`throws if the when list is absent or empty`, async () => + expect(new ConditionalResolver().resolve({})).rejects.toThrow( + "'when' list" + )); + +test(`throws if the default is not present`, async () => + await expect( + new ConditionalResolver().resolve({ + when: [ + { matches: 'request.url.pathname', pattern: '^/derp' }, + { use: { inline: 'lerp' } } + ] + }) + ).rejects.toThrow('default')); + +test(`resolves a matcher and yields a value`, async () => { + const visitor = { + upward: jest.fn((x, y) => [x, y]), + context: { + get: jest.fn( + name => + ({ + 'one.fish': 'blue', + 'red.fish': 'two' + }[name]) + ), + set: jest.fn(), + forget: jest.fn() + } + }; + await expect( + new ConditionalResolver(visitor).resolve({ + when: [ + { + matches: 'one.fish', + pattern: 'green', + use: { inline: '#00FF00' } + }, + { + matches: 'red.fish', + pattern: 'tw.', + use: { inline: '#FF0000' } + } + ], + default: { inline: 'chum' } + }) + ).resolves.toMatchObject([ + { + matches: 'red.fish', + pattern: 'tw.', + use: { inline: '#FF0000' } + }, + 'use' + ]); +}); + +test(`when no matchers match, yields default`, async () => { + const visitor = { + upward: jest.fn((x, y) => [x, y]), + context: { + get: jest.fn( + name => + ({ + 'one.fish': 'blue', + 'red.fish': 'two' + }[name]) + ), + set: jest.fn(), + forget: jest.fn() + } + }; + await expect( + new ConditionalResolver(visitor).resolve({ + when: [ + { + matches: 'one.fish', + pattern: 'green', + use: { inline: '#00FF00' } + }, + { + matches: 'red.fish', + pattern: 'thr', + use: { inline: '#FF0000' } + }, + { + matches: 'one.fish', + pattern: 'lemons', + use: { inline: '#00FF00' } + }, + { + matches: 'red.fish', + pattern: 'noooo', + use: { inline: '#FF0000' } + } + ], + default: { inline: 'chum' } + }) + ).resolves.toMatchObject([ + { + default: { inline: 'chum' } + }, + 'default' + ]); +}); + +test(`context values for match are temporarily present`, async () => { + const visitor = { + upward: jest.fn(() => { + expect(visitor.context.set).toHaveBeenCalledWith( + '$match', + expect.objectContaining({ + $0: 'blu', + $1: 'l', + $2: 'u' + }), + true + ); + return 'match set'; + }), + context: { + get: jest.fn( + name => + ({ + 'one.fish': 'blue', + 'red.fish': 'two' + }[name]) + ), + set: jest.fn(), + forget: jest.fn() + } + }; + await expect( + new ConditionalResolver(visitor).resolve({ + when: [ + { + matches: 'one.fish', + pattern: 'b(l)(u)', + use: { inline: '#00FF00' } + }, + { + matches: 'red.fish', + pattern: 'noooo', + use: { inline: '#FF0000' } + } + ], + default: { inline: 'chum' } + }) + ).resolves.toEqual('match set'); + expect(visitor.context.forget).toHaveBeenCalledWith('$match'); +}); diff --git a/packages/upward-js/lib/resolvers/__tests__/FileResolver.test.js b/packages/upward-js/lib/resolvers/__tests__/FileResolver.test.js new file mode 100644 index 00000000000..fc807cd86f8 --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/FileResolver.test.js @@ -0,0 +1,253 @@ +const FileResolver = require('../FileResolver'); + +test('resolverType is file', () => + expect(FileResolver.resolverType).toBe('file')); + +test('telltale exists', () => expect(FileResolver.telltale).toBeDefined()); + +test('resolve() throws error if no definition provided', async () => { + expect(new FileResolver().resolve({})).rejects.toThrow( + 'File argument is required' + ); +}); + +test('resolves filename and uses default encoding and parse', async () => { + const visitor = { + upward: jest.fn(() => 'in-the-way'), + io: { + readFile: jest.fn(() => 'ooh') + } + }; + await expect( + new FileResolver(visitor).resolve({ file: 'something' }) + ).resolves.toEqual('ooh'); + expect(visitor.upward).toHaveBeenCalledTimes(1); + expect(visitor.upward).toHaveBeenCalledWith( + expect.objectContaining({ + file: 'something' + }), + + 'file' + ); + expect(visitor.io.readFile).toHaveBeenCalledWith('in-the-way', 'utf8'); +}); + +test('uses custom encoding', async () => { + const visitor = { + upward: jest.fn(), + io: { + readFile: jest.fn(() => 'whats going on') + } + }; + visitor.upward + .mockResolvedValueOnce('i-said') + .mockResolvedValueOnce('latin1'); + await expect( + new FileResolver(visitor).resolve({ + file: 'something', + encoding: 'hey' + }) + ).resolves.toEqual('whats going on'); + expect(visitor.upward).toHaveBeenCalledTimes(2); + expect(visitor.upward.mock.calls).toMatchObject([ + [{ encoding: 'hey', file: 'something' }, 'file'], + [{ encoding: 'hey', file: 'something' }, 'encoding'] + ]); + expect(visitor.io.readFile).toHaveBeenCalledWith('i-said', 'latin1'); +}); + +test('throws on invalid encoding', async () => { + const visitor = { + upward: jest.fn(), + io: { + readFile: jest.fn(() => 'whats going on') + } + }; + visitor.upward + .mockResolvedValueOnce('i-said') + .mockResolvedValueOnce('bad-encoding'); + await expect( + new FileResolver(visitor).resolve({ + file: 'something', + encoding: 'hey' + }) + ).rejects.toThrow("Invalid 'encoding'"); +}); + +test('parse === "text" shortcuts parse', async () => { + const visitor = { + upward: jest.fn(), + io: { + readFile: jest.fn(() => '{{curlies}}') + } + }; + visitor.upward + .mockResolvedValueOnce('bristly.mustache') + .mockResolvedValueOnce('text'); + await expect( + new FileResolver(visitor).resolve({ + file: 'something', + parse: 'text' + }) + ).resolves.toEqual('{{curlies}}'); + expect(visitor.upward).toHaveBeenCalledWith( + expect.objectContaining({ + parse: 'text' + }), + 'parse' + ); +}); + +test('auto-parses a file from extension', async () => { + const visitor = { + upward: jest.fn(() => 'bristly.mustache'), + io: { + readFile: jest.fn(() => '{{curlies}}') + } + }; + const tpt = await new FileResolver(visitor).resolve({ + file: 'aTemplate' + }); + expect(visitor.io.readFile).toHaveBeenCalledWith( + 'bristly.mustache', + 'utf8' + ); + expect(tpt).toHaveProperty('compile', expect.any(Function)); +}); + +test('falls back silently to text for an unrecognized file type', async () => { + const visitor = { + upward: jest.fn(() => 'bristly.porcupine'), + io: { + readFile: jest.fn(() => '\\||||////') + } + }; + const txt = await new FileResolver(visitor).resolve({ + file: 'aFile' + }); + expect(visitor.io.readFile).toHaveBeenCalledWith( + 'bristly.porcupine', + 'utf8' + ); + expect(txt).toEqual('\\||||////'); +}); + +test('force parses a specific file type', async () => { + const visitor = { + upward: jest.fn(), + io: { + readFile: jest.fn(() => '{ foo { bar } }') + } + }; + visitor.upward + .mockResolvedValueOnce('graphql-disguised-by.mustache') + .mockResolvedValueOnce('graphql'); + const gqlDoc = await new FileResolver(visitor).resolve({ + file: 'anything', + parse: 'turns-into-graphql' + }); + expect(gqlDoc).toMatchObject({ + compile: expect.any(Function), + render: expect.any(Function) + }); + expect(gqlDoc.compile()).resolves.not.toThrow(); + expect(gqlDoc.render()).resolves.toMatchInlineSnapshot(` +Object { + "definitions": Array [ + Object { + "directives": Array [], + "kind": "OperationDefinition", + "name": undefined, + "operation": "query", + "selectionSet": Object { + "kind": "SelectionSet", + "selections": Array [ + Object { + "alias": undefined, + "arguments": Array [], + "directives": Array [], + "kind": "Field", + "name": Object { + "kind": "Name", + "value": "foo", + }, + "selectionSet": Object { + "kind": "SelectionSet", + "selections": Array [ + Object { + "alias": undefined, + "arguments": Array [], + "directives": Array [], + "kind": "Field", + "name": Object { + "kind": "Name", + "value": "bar", + }, + "selectionSet": undefined, + }, + ], + }, + }, + ], + }, + "variableDefinitions": Array [], + }, + ], + "kind": "Document", + "loc": Object { + "end": 15, + "start": 0, + }, +} +`); +}); + +test('force parses throws on unrecognized file type', async () => { + const visitor = { + upward: jest.fn(), + io: { + readFile: jest.fn(() => 'an executable lol') + } + }; + visitor.upward + .mockResolvedValueOnce('exe-disguised-by.mustache') + .mockResolvedValueOnce('.exe') + // should add a dot where necessary + .mockResolvedValueOnce('exe-disguised-by.mustache') + .mockResolvedValueOnce('exe'); + await expect( + new FileResolver(visitor).resolve({ + file: 'afile', + parse: 'aparser' + }) + ).rejects.toThrow('Unsupported parse type'); + await expect( + new FileResolver(visitor).resolve({ + file: 'afile', + parse: 'aparser' + }) + ).rejects.toThrow('Unsupported parse type'); +}); + +test('recognizes file paths', async () => { + expect(FileResolver.recognize('not a file')).toBeFalsy(); + expect(FileResolver.recognize('./a-file')).toBeTruthy(); + expect(FileResolver.recognize('../../..//a-file')).toBeTruthy(); + const config = FileResolver.recognize('file:///a-file'); + const visitor = { + upward: jest.fn(() => Promise.resolve('/a-file')), + io: { + readFile: () => + Promise.resolve('goodness gracious, great text of file') + } + }; + await expect(new FileResolver(visitor).resolve(config)).resolves.toEqual( + 'goodness gracious, great text of file' + ); + expect(visitor.upward).toHaveBeenCalledWith( + { + file: { inline: '/a-file' } + }, + 'file' + ); +}); diff --git a/packages/upward-js/lib/resolvers/__tests__/InlineResolver.test.js b/packages/upward-js/lib/resolvers/__tests__/InlineResolver.test.js new file mode 100644 index 00000000000..b11e77dc688 --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/InlineResolver.test.js @@ -0,0 +1,34 @@ +const InlineResolver = require('../InlineResolver'); + +test('resolverType is inline', () => + expect(InlineResolver.resolverType).toBe('inline')); + +test('telltale exists', () => expect(InlineResolver.telltale).toBeDefined()); + +test('primitive resolves with no visitor calls', async () => { + const visitor = { + upward: jest.fn() + }; + const resolver = new InlineResolver(visitor); + expect(resolver.resolve({ inline: 'a string' })).resolves.toBe('a string'); + expect(visitor.upward).not.toHaveBeenCalled(); +}); + +test('plain object calls visitor.upward to traverse', async () => { + const visitor = { + upward: jest.fn(() => 'a resolved string') + }; + const resolver = new InlineResolver(visitor); + expect( + resolver.resolve({ inline: { resolvedString: 'a resolved string' } }) + ).resolves.toEqual({ resolvedString: 'a resolved string' }); + expect(visitor.upward).toHaveBeenCalledWith( + expect.objectContaining({ resolvedString: 'a resolved string' }), + 'resolvedString' + ); +}); + +test('non-primitive and non-plain object inline argument throws error', async () => { + const resolver = new InlineResolver(); + expect(resolver.resolve([])).rejects.toThrow('Invalid value'); +}); diff --git a/packages/upward-js/lib/resolvers/__tests__/ServiceResolver.test.js b/packages/upward-js/lib/resolvers/__tests__/ServiceResolver.test.js new file mode 100644 index 00000000000..c45f3a04ff2 --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/ServiceResolver.test.js @@ -0,0 +1,260 @@ +const ServiceResolver = require('../ServiceResolver'); +const GraphQLDocument = require('../../compiledResources/GraphQLDocument'); + +test('resolverType is file', () => + expect(ServiceResolver.resolverType).toBe('service')); + +test('telltale exists', () => expect(ServiceResolver.telltale).toBeDefined()); + +test('places a server call and returns results', async () => { + const res = { data: { foo: { bar: 'exam' } } }; + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + theUrl: 'https://example.com/graphql', + theQuery: '{ foo { bar } }' + }[dfn[name]]) + ), + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery' + }) + ).resolves.toEqual(res); + + const [fetchUri, fetchOptions] = visitor.io.networkFetch.mock.calls[0]; + + expect(fetchUri).toBe('https://example.com/graphql'); + + expect(JSON.parse(fetchOptions.body)).toMatchInlineSnapshot(` +Object { + "operationName": null, + "query": "{ + foo { + bar + } +} +", + "variables": Object {}, +} +`); +}); + +test('places a server call with custom method and headers', async () => { + const res = { data: { foo: { bar: 'exam' } } }; + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + theUrl: 'https://example.com/graphql', + theHeaders: { Authorization: 'Bear OMG' }, + theMethod: 'GET', + theQuery: '{ foo { bar } }' + }[dfn[name]]) + ), + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery', + headers: 'theHeaders', + method: 'theMethod' + }) + ).resolves.toEqual(res); + + const [fetchUri, fetchOptions] = visitor.io.networkFetch.mock.calls[0]; + + expect(fetchUri).toMatch('https://example.com/graphql?query'); + + expect(fetchOptions.method).toBe('GET'); +}); + +test('places a server call with variables', async () => { + const res = { data: { foo: { bar: 'nothing' } } }; + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + theUrl: 'https://example.com/graphql', + theQuery: + 'query getFoo($id: String!) { foo(id: $id) { bar } }', + 'combination.to.my.luggage': { + id: 12345 + } + }[dfn[name]]) + ), + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery', + variables: 'combination.to.my.luggage' + }) + ).resolves.toEqual(res); + + const fetchOptions = visitor.io.networkFetch.mock.calls[0][1]; + + expect(JSON.parse(fetchOptions.body)).toMatchInlineSnapshot(` +Object { + "operationName": "getFoo", + "query": "query getFoo($id: String!) { + foo(id: $id) { + bar + } +} +", + "variables": Object { + "id": 12345, + }, +} +`); +}); + +test('throws if variables are in an unacceptable format', async () => { + const visitor = { + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + }, + upward: jest.fn(async () => 'bleh') + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery', + variables: { + inline: 'bleh' + } + }) + ).rejects.toThrow('Variables must resolve to a plain object.'); +}); + +test('throws if variables are in an unacceptable format', async () => { + const visitor = { + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + }, + upward: jest.fn(async () => 'bleh') + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery', + variables: 'combination.to.my.luggage' + }) + ).rejects.toThrow('Variables must resolve to a plain object.'); +}); + +test('throws if query is missing', async () => { + const visitor = { + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl' + }) + ).rejects.toThrow('No GraphQL query'); +}); + +test('throws if url is missing', async () => { + const visitor = { + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + query: 'theQuery' + }) + ).rejects.toThrow('No URL'); +}); + +test('accepts a precompiled GraphQLDocument', async () => { + const res = { data: { foo: { bar: 'exam' } } }; + const gqlDoc = new GraphQLDocument('{ foo { bar } }'); + await gqlDoc.compile(); + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + theUrl: 'https://example.com/graphql', + theQuery: gqlDoc + }[dfn[name]]) + ), + io: { + networkFetch: jest.fn(async () => ({ + json: async () => res, + text: async () => JSON.stringify(res) + })) + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery' + }) + ).resolves.toEqual(res); +}); + +test('throws if the query is neither a string nor a GraphQLDocument', async () => { + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + theUrl: 'https://example.com/graphql', + theQuery: {} + }[dfn[name]]) + ), + io: { + networkFetch: jest.fn() + } + }; + + await expect( + new ServiceResolver(visitor).resolve({ + url: 'theUrl', + query: 'theQuery' + }) + ).rejects.toThrowError('Unknown type'); +}); diff --git a/packages/upward-js/lib/resolvers/__tests__/TemplateResolver.test.js b/packages/upward-js/lib/resolvers/__tests__/TemplateResolver.test.js new file mode 100644 index 00000000000..738c09d7dff --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/TemplateResolver.test.js @@ -0,0 +1,196 @@ +const TemplateResolver = require('../TemplateResolver'); +const MustacheTemplate = require('../../compiledResources/MustacheTemplate'); + +test('resolverType is file', () => + expect(TemplateResolver.resolverType).toBe('template')); + +test('telltale exists', () => expect(TemplateResolver.telltale).toBeDefined()); + +test('throws if no template specified', async () => { + await expect(new TemplateResolver().resolve({ engine: 'mustache' })).rejects + .toThrowErrorMatchingInlineSnapshot(` +"Invalid arguments to TemplateResolver: { engine: 'mustache' }. + +No template specified." +`); +}); + +test('throws if no provide arg specified', async () => { + await expect( + new TemplateResolver().resolve({ + engine: 'mustache', + template: './some-template' + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(` +"Invalid arguments to TemplateResolver: { engine: 'mustache', template: './some-template' }. + +'provide' property must be an array of context values or object of resolvable definitions, was undefined" +`); +}); + +test('throws if provide arg is invalid', async () => { + await expect( + new TemplateResolver().resolve({ + engine: 'mustache', + template: './some-template', + provide: [{}] + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(` +"Invalid arguments to TemplateResolver: { engine: 'mustache', + template: './some-template', + provide: [ {} ] }. + +'provide' property must be an array of context values or object of resolvable definitions, was [ {} ]" +`); +}); + +test('throws if template engine is unsupported', async () => { + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + anEngine: 'beard', + aTemplate: 'some-template' + }[dfn[name]]) + ), + context: { + get: jest.fn(() => { + ENV_VAR: 'ENV_VALUE'; + }) + } + }; + await expect( + new TemplateResolver(visitor).resolve({ + engine: 'anEngine', + template: 'aTemplate', + provide: ['env'] + }) + ).rejects.toThrow(`Template engine 'beard' unsupported`); + expect(visitor.context.get).toHaveBeenCalledWith('env'); +}); + +test('accepts a template engine instance as the template arg', async () => { + const io = { readFile() {} }; + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + anEngine: 'mustache', + aTemplate: new MustacheTemplate('{{ env.ENV_VAR }}', io) + }[dfn[name]]) + ), + context: { + get: jest.fn(() => ({ + ENV_VAR: 'ENV_VALUE' + })) + }, + io + }; + await expect( + new TemplateResolver(visitor).resolve({ + engine: 'anEngine', + template: 'aTemplate', + provide: ['env'] + }) + ).resolves.toEqual('ENV_VALUE'); + expect(visitor.context.get).toHaveBeenCalledWith('env'); +}); + +test('accepts a template string as the template arg', async () => { + const io = { readFile() {} }; + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + anEngine: 'mustache', + aTemplate: + '{{ env.ENV_VAR }} see the {{#arbitrary}}{{animal}}{{/arbitrary}}' + }[dfn[name]]) + ), + context: { + get: jest.fn( + name => + ({ + env: { ENV_VAR: 'come and' }, + arbitrary: { + animal: 'horsie' + } + }[name]) + ) + }, + io + }; + await expect( + new TemplateResolver(visitor).resolve({ + engine: 'anEngine', + template: 'aTemplate', + provide: ['env', 'arbitrary'] + }) + ).resolves.toEqual('come and see the horsie'); + expect(visitor.context.get).toHaveBeenCalledWith('env'); +}); + +test('throws if template argument is not an enging instance or a string', async () => { + const io = { readFile() {} }; + const visitor = { + upward: jest.fn( + (dfn, name) => + ({ + anEngine: 'mustache', + aTemplate: [] + }[dfn[name]]) + ), + context: { + get: jest.fn(() => ({ + ENV_VAR: 'ANOTHER_VALUE' + })) + }, + io + }; + await expect( + new TemplateResolver(visitor).resolve({ + engine: 'anEngine', + template: 'aTemplate', + provide: ['env'] + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Expected string or MustacheTemplate-compatible template and received a foreign object Array!"` + ); +}); + +test('"provide" accepts an object mapping of string => contextValue also', async () => { + const io = { readFile() {} }; + const visitor = { + upward: jest.fn( + async (dfn, name) => + ({ + anEngine: 'mustache', + aTemplate: + 'how {{flavor}} it is to be {{quality}} like you', + 'env.ENV_VAR': 'sweet', + 'deep.structure.isNot': 'flat' + }[dfn[name]]) + ), + io + }; + await expect( + new TemplateResolver(visitor).resolve({ + engine: 'anEngine', + template: 'aTemplate', + provide: { + flavor: 'env.ENV_VAR', + quality: 'deep.structure.isNot' + } + }) + ).resolves.toEqual('how sweet it is to be flat like you'); +}); + +test('throws if "provide" is unrecognized', async () => { + await expect( + new TemplateResolver().resolve({ + engine: 'anEngine', + template: 'aTemplate', + provide: 54332 + }) + ).rejects.toThrow("Unrecognized 'provide' configuration"); +}); diff --git a/packages/upward-js/lib/resolvers/__tests__/index.test.js b/packages/upward-js/lib/resolvers/__tests__/index.test.js new file mode 100644 index 00000000000..32def91150e --- /dev/null +++ b/packages/upward-js/lib/resolvers/__tests__/index.test.js @@ -0,0 +1,22 @@ +const { ResolverList, ResolversByType } = require('../'); +const AbstractResolver = require('../AbstractResolver'); + +test('Resolvers exports', () => { + expect(ResolverList).toBeInstanceOf(Array); + expect( + ResolverList.every(resolver => + AbstractResolver.prototype.isPrototypeOf(resolver.prototype) + ) + ).toBeTruthy(); + expect(ResolversByType).toMatchInlineSnapshot(` +Object { + "conditional": [Function], + "directory": [Function], + "file": [Function], + "inline": [Function], + "proxy": [Function], + "service": [Function], + "template": [Function], +} +`); +}); diff --git a/packages/upward-js/lib/resolvers/index.js b/packages/upward-js/lib/resolvers/index.js new file mode 100644 index 00000000000..b2f0dda7489 --- /dev/null +++ b/packages/upward-js/lib/resolvers/index.js @@ -0,0 +1,17 @@ +// const debug = require('debug')('upward-js:resolvers'); +const ResolverList = [ + require('./InlineResolver'), + require('./FileResolver'), + require('./TemplateResolver'), + require('./ServiceResolver'), + require('./ProxyResolver'), + require('./DirectoryResolver'), + require('./ConditionalResolver') +]; + +const ResolversByType = ResolverList.reduce((out, Resolver) => { + out[Resolver.resolverType] = Resolver; + return out; +}, {}); + +module.exports = { ResolverList, ResolversByType }; diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json new file mode 100644 index 00000000000..c5042b6de17 --- /dev/null +++ b/packages/upward-js/package.json @@ -0,0 +1,60 @@ +{ + "name": "@magento/upward-js", + "version": "0.1.0", + "description": "Implementation of the UPWARD spec as a NodeJS server", + "main": "./lib/index.js", + "bin": { + "upward-js-server": "./bin/server" + }, + "files": [ + "./lib", + "./bin" + ], + "engines": { + "node": ">=8.0.0" + }, + "scripts": { + "test": "jest", + "test:spec": "upward-spec ./test_spec.sh" + }, + "repository": "github:magento-research/pwa-studio", + "keywords": [ + "magento", + "pwa", + "express", + "upward" + ], + "author": "Magento Commerce", + "license": "SEE LICENSE IN LICENSE.txt", + "bugs": { + "url": "https://github.com/magento-research/pwa-studio/issues" + }, + "homepage": "https://github.com/magento-research/pwa-studio/tree/master/packages/upward-js#readme", + "dependencies": { + "apollo-boost": "^0.1.13", + "apollo-link": "^1.2.2", + "apollo-link-http": "^1.5.4", + "contains-path": "^1.0.0", + "debug": "^3.1.0", + "debug-error-middleware": "^1.3.0", + "dotenv": "^6.0.0", + "graphql": "^0.13.2", + "graphql-tag": "^2.9.2", + "hogan.js": "^3.0.2", + "http-proxy-middleware": "^0.19.0", + "js-yaml": "^3.12.0", + "lodash": "^4.17.10", + "morgan": "^1.9.0", + "mustache": "^2.3.2", + "traverse": "^0.6.6" + }, + "devDependencies": { + "@magento/upward-spec": "*", + "express": "^4.16.3", + "jest": "^23.5.0", + "supertest": "^3.1.0" + }, + "peerDependencies": { + "express": "^4.16.3" + } +} diff --git a/packages/upward-js/test_spec.sh b/packages/upward-js/test_spec.sh new file mode 100755 index 00000000000..d48818d2d4f --- /dev/null +++ b/packages/upward-js/test_spec.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +UPWARD_JS_BIND_LOCAL=1 \ +UPWARD_JS_LOG_URL=1 \ +UPWARD_JS_UPWARD_PATH="$UPWARD_PATH" exec ./bin/server diff --git a/packages/upward-spec/EXECUTION_SCHEDULING_STRATEGIES.md b/packages/upward-spec/EXECUTION_SCHEDULING_STRATEGIES.md new file mode 100644 index 00000000000..3164e21a6f2 --- /dev/null +++ b/packages/upward-spec/EXECUTION_SCHEDULING_STRATEGIES.md @@ -0,0 +1,256 @@ +# Execution Scheduling Strategies + +As mentioned in the ["Execution scheduling and ordering"](README.md#execution-scheduling-and-ordering) section of the specification, UPWARD servers must run their resolvers: + +- **_only_ when their results are used** +- **as _concurrently_ as possible** + +One approach to this is a state machine. A state machine can provide lazy execution by traversing a graph while keeping track of outstanding dependencies, and it can manage concurrency by spawning and keeping references to other instances of the same state machine. + +Consider the following `upward.yml` configuration: + +```yaml +status: page.status +headers: page.headers +body: page.body + +articleResult: + url: env.LIBRARY_SVC + query: './getArticle.graphql' + variables: + articleId: request.url.query.artID + +authorBioResult: + url: env.LIBRARY_SVC + query: './getAuthor.graphql' + variables: + searchTerm: request.url.query.authorID + +textHtml: + inline: + 'content-type': 'text/html' + +notFound: + inline: + status: 404 + headers: textHtml + body: + engine: mustache + template: './notFound.mst' + +page: + when: + - matches: request.url.pathname + pattern: '/article' + use: + when: + - matches: articleResult.data.article.id + pattern: '.' + use: + inline: + status: 200 + headers: textHtml + body: + engine: mustache + template: './article.mst' + default: notFound + - matches: request.url.pathname + pattern: '/author' + use: + when: + - matches: authorBioResult.data.author.id + pattern: '.' + use: + inline: + status: 200 + headers: textHtml + body: + engine: mustache + template: './authorBio.mst' + default: notFound + default: notFound +``` + +## Possible tasks + +I/O dependent tasks defined by resolvers in this configuration include: + +**A.** Reading and parsing `./getArticle.graphql` from the file system +**B.** Querying a remote service for articles +**C.** Reading and parsing `./getAuthor.graphql` from the file system +**D.** Querying a remote service for authors +**E.** Reading and parsing `./authorBio.mst` from the file system +**F.** Reading and parsing `./article.mst` from the file system +**G.** Reading and parsing `./notFound.mst` from the file system + +In the above example, a request to `/author?id=1` should never cause the `articleResult` resolver to execute its query to the remote service. If the result is not found, it should never cause the `authorBio.mst` resolver to read from the file system. Even though the file format is declarative, each request should traverse through the resolvers using a minimal path. The request `/author?id=1`, if no data exists for it in the backing resource, should only run tasks **C, D,** and **G** from the above list. + +## Example state machine resolution + +:information_source: _(The below is an example and not normative. UPWARD-compliant servers must lazily execute resolvers, and a state machine is one way to implement this. What follows is a description of one path through such a state machine, not a formal definition of a state machine.)_ + +In a state-machine-based lazy-execution implementation, the request `/author?id=1` would cause the following. + +Starting state: **Response readiness analysis** + + 1. `status`, `headers`, and `body` have not been assigned. + 1. No resolvers are currently in operation or have resolved. + 1. `status`, `headers`, and `body` resolution are all defined in configuration. + + State: **Context dependency analysis** + 1. The context names pending resolution all depend on `page`. + 1. `page` has not been assigned. + 1. `page` resolution is defined in configuration. + + State: **Context resolution** + 1. `page` depends on a ConditionalResolver. + + State: **Conditional execution** + 1. The first matcher depends on `request.url.pathname`. + 1. That value is already present in context, so the matcher can run. + + State: **Conditional matching** + 1. The first matcher tests `request.url.pathname`, which is the value `/author`, against the pattern `/article`. The test fails. + + State: **Conditional execution** + 1. The second matcher depends on `request.url.pathname`. + 1. That value is already present in context, so the matcher can run. + + State: **Conditional matching** + 1. The second matcher tests `request.url.pathname`, which is the value `/author`, against the pattern `/author`. The test passes. + 1. The conditional yields to the resolver in the `use` parameter of the second matcher. That resolver is a ConditionalResolver. + + State: **Conditional execution** + 1. The first matcher depends on `authorBioResult`. + 1. `authorBioResult` has not been assigned. + + State: **Resolver dependency detection** + 1. `authorBioResult` resolution is defined in configuration. + + State: **Context resolution** + 1. `authorBioResult` depends on a ServiceResolver. + + State: **Resolver dependency detection** + 1. The ServiceResolver depends on context values `env.LIBRARY_SVC`, `request.url.query.authorId`, and a FileResolver (shorthand form) for the `query`. + 1. Both context values are present. + 1. The shorthand FileResolver creates and resolves an implicit InlineResolver, determining that it depends on the filesystem path `./getAuthor.graphql`. + + State: **File resolution** + 1. The server reads, parses, and caches the contents of `./getAuthor.graphql`. + + State: **Service resolution** + 1. The server places an HTTP request to the GraphQL service. The GraphQL service responds with a result payload: + ```json + { + "data": { + "author:" null + } + } + ``` + + State: **Context assignment** + 1. The context value `authorBioResult` is set to the result payload. + + State: **Response readiness analysis** + 1. `status`, `headers`, and `body` have not been assigned. + 1. One or more context values have been assigned. + 1. A ConditionalResolver is still resolving. + + State: **Context dependency analysis** + 1. The context names pending resolution depend on `page` and `authorBioResult`. + 1. `page` has not been assigned. + 1. `authorBioResult` has been assigned. + + State: **Context resolution** + 1. The conditional resolver depending on `authorBioResult` resumes. + + State: **Conditional execution** + 1. The first matcher runs again and fails again. + 1. The second matcher runs again and succeeds again, yielding another ConditionalResolver. + 1. The first matcher depends on `authorBioResult`. + 1. That value is now present in context, so the matcher can run. + + State: **Conditional matching** + 1. The first matcher tests `authorBioResult.data.author.id` against the pattern `.`. Because `authorBioResult.data.author` is null, the match fails. + + State: **Conditional execution** + 1. All matchers in the `when` configuration have failed, so the conditional yields to the value of `default`. + 1. The value of `default` is the context lookup `notFound`. + 1. `notFound` has not been assigned. + + State: **Resolver dependency detection** + 1. `notFound` resolution is defined in configuration. + + State: **Context resolution** + 1. `notFound` depends on an InlineResolver. + 1. The InlineResolver specifies an object whose properties depend on context value `textHtml` for `headers` and a TemplateResolver for `body`. + 1. `textHtml` has not been assigned. + 1. `textHtml` is defined in configuration. + 1. `textHtml` depends on an InlineResolver. + 1. The InlineResolver specifies an object whose properties depend on context value `text/html`. + 1. That value is present in context (it is built in). + 1. The InlineResolver depending on `textHtml` resolves, assigning a value to the `header` property of the `notFound` resolver. + + State: **Resolver dependency detection** + 1. The TemplateResolver depends on a context value `mustache` for `engine`, and a shorthand FileResolver for `template`. + 1. The value `mustache` is present in context (it is built in). + 1. The shorthand FileResolver creates and resolves an implicit InlineResolver, determining that it depends on the filesystem path `./notFound.mst`. + + State: **File resolution** + 1. The server reads, parses, and caches the contents of `./notFound.mst`. + + State: **Template resolution** + 1. The TemplateResolver executes its template against the entire context object, creating an interpolated string: + + ```html + That doesn't look like anything to me. + ``` + + The TemplateResolver depending on `./notFound.mst` resolves, assigning the string to the `body` property of the `notFound` resolver. + + State: **Context resolution** + 1. The InlineResolver for `notFound` resolves. + 1. The conditional resolver depending on `notFound` resumes. + + State: **Conditional execution** + 1. The first matcher runs again and fails again. + 1. All matchers in the `when` configuration have failed, so the conditional yields to the value of `default`. + 1. The value of `default` is a resolved InlineResolver producing an object. + + State: **Conditional resolution** + 1. The ConditionalResolver resolves. + 1. The `use` property of the match in the parent ConditionalResolver is fully resolved. + 1. The parent ConditionalResolver resolves. + + State: **Context assignment** + 1. The context value `page` is set to the result payload. + + State: **Response readiness analysis** + 1. `status`, `headers`, and `body` have not been assigned. + 1. One or more top-level context values have resolved. + 1. No resolvers are currently resolving. + + State: **Context dependency analysis** + 1. The context names pending resolution depend on `page`. + 1. `page` has been assigned. + + State: **Context resolution** + 1. `status`, `headers`, and `body` depend on `page`. + 1. `page` exists in context and can be used. + + State: **Context assignment** + 1. The context value `status` is set to `page.status`. + 1. `headers` is set to `page.headers`. + 1. `body` is set to `page.body`. + + State: **Response readiness analysis** + 1. `status`, `headers`, and `body` have all been assigned. + + State: **Response flush** + 1. The context is cast to an HTTP response and sent to the requesting client. + +## Conclusion + +While resolving the request, the state machine did not execute all [possible tasks](#possible-tasks); it did not run tasks **A, B, E,** or **F**, even though there is no indication of task ordering or conditional execution in those task definitions themselves. + +This _topologically-ordered_, _maximally concurrent_, and _lazily evaluated_ process enables UPWARD configuration authors to describe the available tasks without writing any imperative logic. diff --git a/packages/upward-spec/RATIONALE.md b/packages/upward-spec/RATIONALE.md new file mode 100644 index 00000000000..47403423163 --- /dev/null +++ b/packages/upward-spec/RATIONALE.md @@ -0,0 +1,184 @@ +# Rationale: Why UPWARD + +- [Rationale: Why UPWARD](#rationale-why-upward) + - [The Problem With PWA Runtime Dependencies](#the-problem-with-pwa-runtime-dependencies) + - [Tiered Architectures](#tiered-architectures) + - [Edge Definition, Not Service Orchestration](#edge-definition-not-service-orchestration) + - [Common PWA Backing Service Characteristics](#common-pwa-backing-service-characteristics) + - [UPWARD with PWAs](#upward-with-pwas) + - [Enforce stateless middle tiers](#enforce-stateless-middle-tiers) + - [Example `upward.yml`](#example-upwardyml) + - [Push business logic to the edges of the system](#push-business-logic-to-the-edges-of-the-system) + - [Objections](#objections) + +Progressive Web Apps represent a new plateau of maturity for the Web as a platform. Like any other high-quality software, PWAs benefit from [Twelve-factor methodology][twelve factor], but they have historically been considered a _part_ of a full-scale deployed application, the "frontend", and not a full application to which all twelve-factor principles should apply. + +Until PWAs, "web apps" have not been apps on their own; they could not function without a specific set of backing services. Those services should be decoupled and abstracted as [resource locators][twelve factor resources], so that individual servers can be swapped in and out, but the "frontend" is still tightly coupled to a specific topology of services, culminating in end-to-end functionality that depends on all of those services being present. + +![12-factor resource diagram: 12factor.net](backing_services.png) +_Image courtesy of 12factor.net_ + +A PWA must run independently from any backing services as much as possible; therefore, it must have alternate strategies to replace the functionality of each backing service. The simplest and most efficient PWA would have as few individual backing services as possible, so a need emerges for a tool which unifies backing services into a single layer that deliver, supports, and synchronizes with a PWA. + +## The Problem With PWA Runtime Dependencies + +A PWA must have at least partial functionality offline; for example, an eCommerce store PWA should be able to navigate its catalog in several dimensions, including categories and configurable products, without placing a server call for each transition. Therefore, at least some of its business logic must be implemented in the HTML/CSS/JS layer traditionally designated as "frontend". + +However, duplication of logic is an antipattern, and the spreading of business logic across multiple layers is an antipattern that harms testability. The [ports and adapters architecture, or "hexagonal" architecture,][hexagonal architecture] describes how business logic must be confined to the center of the architecture, and expressed or interpreted through a small number of adapters, so that it can be connected with backing services and tested in multiple contexts. + +This seems incompatible with an app architecture that supports "offline mode", where workflows should be independent of the availability of services. Since business logic must be in the center and accessible through ports, it follows that a Web app should move its "center" of authoritative business logic to the frontend, or as close to the frontend as possible. + +This is a difficult migration path for many web apps, for many reasons: security concerns, scalability concerns about the JavaScript language and runtime, and the value inherent in existing codebases. Yet as more Web apps implement offline functionality, pressure increases on their business logic to duplicate and/or spread out across platforms in a dangerously coupled way. **A robust architecture must provide natural and obvious locations for different types of business logic.** Without them, an application will amass implicit, undocumented, informal business logic in one or more places. + +### Tiered Architectures + +The most frequently used solution to the problem of PWA runtime dependencies is a [multitier architecture][multitier architecture], using some combination of: + +- a "presentation tier" or "[backend-for-frontend][backend-for-frontend]" for serving the app assets and reverse proxying to services +- a "middle tier" or "[gateway][gateway aggregation]" for combining related service requests. + +In both of those cases, the intermediaries serve as a gathering point for the frontend: + +![Tiered architecture](tiered_architecture.png) + +However, these tiers are almost implemented in a **general-purpose web framework**, written in a **general-purpose programming language**. The hazard always exists for an implementer to "cheat" the architecture, and fix a bug in either the production web app, or one of the attached services, in the presentation tier! + +A declarative middle tier architecture is called for. Early efforts to standardize a format for [service discovery][uddi], as well as more recent efforts to standardize a format for [service topology][tosca], have resulted in complex and overspecified configurations most useful in closed systems. + +### Edge Definition, Not Service Orchestration + +A common solution to the problem of business logic that exists across multiple services is [service orchestration][service orchestration], but a service orchestrator is a separate program with foreknowledge of the workflows that exist, and an imperative programming paradigm that enforces the workflows. UPWARD more closely resembles [service choreography][service choreography]; an UPWARD configuration has global control over a request, rather than control from a specific node in the network. This simplification is possible because UPWARD is for a PWA [application shell][application shell], so it needs to respond to a more restricted set of conditions than some other service architectures. + +### Common PWA Backing Service Characteristics + +PWA best practices recommend a small subset of the possible things a web server can do. This set of restrictions makes it much easier to describe web server behavior with a limited set of definitions. + +A PWA should: + +- Serve over [HTTPS only][pwa https] +- Serve an [application shell][application shell] with some aspects common to all pages +- Serve static resources from [edge servers][cdn def] whenever possible +- Provide a common strategy for data exchange, such as GraphQL, to avoid excess client responsibilities +- Consume data from as few conceptual domains as possible + +A PWA should not: + +- Require many resources that cannot be [cached and reused when offline][offline mode] +- Depend on server-side state for [most interactions and workflows][high perf loading] +- Depend on a particular backing technology stack + +It follows that a server which delivers PWA resources can count on the following to be true: + +- Requests are idempotent +- Responses are small +- All services are GraphQL + +These assumptions enable a manageably small declarative specification for an app shell server. + +## UPWARD with PWAs + +The UPWARD specification enables developers and administrators to describe a middle tier and/or backend-for-frontend architecture that cannot include arbitrary business logic, since its behavior is confined to the declarative specification. + +### Enforce stateless middle tiers + +The following configuration file defines a middle tier server that renders a simple application shell, using different templates based on pattern-matching conditions. It cannot maintain any local state. It cannot, and does not need to, do any significant rule-based data transformation beyond pattern matches. + +#### Example `upward.yml` + +```yaml +status: page.status +headers: page.headers +body: page.body + +articleResult: + url: env.LIBRARY_SVC + query: './getArticle.graphql' + variables: + articleId: request.url.query.artID + +authorBioResult: + url: env.LIBRARY_SVC + query: './getAuthor.graphql' + variables: + searchTerm: request.url.query.authorID + +textHtml: + inline: + 'content-type': 'text/html' + +notFound: + inline: + status: 404 + headers: textHtml + body: + engine: mustache + template: './notFound.mst' + +page: + when: + - matches: request.url.pathname + pattern: '/article' + use: + when: + - matches: articleResult.data.article.id + pattern: '.' + use: + inline: + status: 200 + headers: textHtml + body: + engine: mustache + template: './article.mst' + default: notFound + - matches: request.url.pathname + pattern: '/author' + use: + when: + - matches: authorBioResult.data.author.id + pattern: '.' + use: + inline: + status: 200 + headers: textHtml + body: + engine: mustache + template: './authorBio.mst' + default: notFound + default: notFound +``` + +The `LIBRARY_SVC` endpoint is responsible for providing, querying, and doing existence checks on the backing data. The `.mst` template files implement only the base Mustache specification, so they are almost completely logic-free--they don't even have conditionals. A PWA expecting this server can read this document and structure the same GraphQL calls; in this way, a PWA can include an `upward.yml` to define service depdencies, or it can build against a service-provided `upward.yml` to do service discovery. + +#### Push business logic to the edges of the system + +When an architecture uses an UPWARD server as a middle tier, it can't hide any business logic there. Business logic must be extracted to reusable templates or queries, pushed forward to the frontend, or pushed backward to the backend. When logic duplication must occur, it is pushed to the edges of the system, rather than hiding in the middle of a tiered architecture. + +An UPWARD-compliant server is not responsible for caching, proxying, or static assets. Its only responsibility is to unify, in a central format, the requirements and processes that create an application shell for a Progressive Web App, so that both a backend server and a frontend client can use the same cross-platform implementations (such as templates and queries) to perform render. + +![Unified graph over backing services](unified_graph.png) + +## Objections + +Common objections to creating new specifications and standards include: + +- **Necessity**: Unclear what problem the standard solves +- **Proliferation**: Too many standards exist already +- **Restrictiveness**: The standard imposes restrictions that hamper desired functionality +- **Erosion risk**: Ensuring compliance with a standard's updates adds to the cost of software development and maintenance + +The UPWARD team shares those concerns, and applies them continuously to the standard as it develops. UPWARD exists because it answers these concerns with clear necessity, wise restrictiveness and limited scope, in this document and in its specification. + +[pwa https]: +[twelve factor]: +[twelve factor resources]: +[application shell]: +[ports and adapters architecture]: +[cdn def]: +[offline mode]: +[high perf loading]: +[service orchestration]: +[service choreography]: +[backend-for-frontend]: +[gateway aggregation]: +[uddi]: +[tosca]: diff --git a/packages/upward-spec/README.md b/packages/upward-spec/README.md new file mode 100644 index 00000000000..87bbb6b695a --- /dev/null +++ b/packages/upward-spec/README.md @@ -0,0 +1,1129 @@ +# UPWARD Specification + +**U**nified **P**rogressive **W**eb **A**pp **R**esponse **D**efinitions are simple files describing how a web server delivers and supports a [Progressive Web Application][pwa def]. They denote server behavior in a platform-independent way, so that a PWA client application expecting certain behavior from HTTP endpoints can be deployed on any type of tech stack that implements the UPWARD specification. + +See [RATIONALE.md](RATIONALE.md) for a detailed explanation of the context that led to the introduction of UPWARD, and the problems it intends to solve. + +See [EXECUTION_SCHEDULING_STRATEGIES.md](EXECUTION_SCHEDULING_STRATEGIES.md) for a deep dive into how the core logic of an UPWARD-compliant server might be implemented with a state machine. + +See [UPWARD_MAGENTO.md](UPWARD_MAGENTO.md) for context on how UPWARD fills a need in Magento PWA Studio and Magento 2 frontend development. + +- [UPWARD Specification](#upward-specification) + - [Quickstart](#quickstart) + - [Summary](#summary) + - [Simple example](#simple-example) + - [Configuration](#configuration) + - [Responding to requests](#responding-to-requests) + - [Execution scheduling and ordering](#execution-scheduling-and-ordering) + - [Cyclic dependencies](#cyclic-dependencies) + - [Response flush triggering](#response-flush-triggering) + - [Context Reference](#context-reference) + - [Initial context](#initial-context) + - [Context Path Syntax](#context-path-syntax) + - [Using context](#using-context) + - [Context persistence and size](#context-persistence-and-size) + - [Resolver Reference](#resolver-reference) + - [InlineResolver](#inlineresolver) + - [InlineResolver Configuration Options](#inlineresolver-configuration-options) + - [FileResolver](#fileresolver) + - [FileResolver Configuration Options](#fileresolver-configuration-options) + - [Parsing](#parsing) + - [FileResolver Error Handling](#fileresolver-error-handling) + - [FileResolver shorthand](#fileresolver-shorthand) + - [ServiceResolver](#serviceresolver) + - [ServiceResolver Configuration Options](#serviceresolver-configuration-options) + - [Example REST service call](#example-rest-service-call) + - [Response Assignment](#response-assignment) + - [ServiceResolver Error Handling](#serviceresolver-error-handling) + - [TemplateResolver](#templateresolver) + - [TemplateResolver Configuration Options](#templateresolver-configuration-options) + - [Template Context](#template-context) + - [Template Engines](#template-engines) + - [Example React DOM Server support](#example-react-dom-server-support) + - [TemplateResolver Error Handling](#templateresolver-error-handling) + - [ConditionalResolver](#conditionalresolver) + - [ConditionalResolver Configuration Options](#conditionalresolver-configuration-options) + - [Matchers](#matchers) + - [Match context](#match-context) + - [ConditionalResolver notes](#conditionalresolver-notes) + - [ProxyResolver](#proxyresolver) + - [ProxyResolver Example](#proxyresolver-example) + - [ProxyResolver Configuration Options](#proxyresolver-configuration-options) + - [ProxyResolver notes](#proxyresolver-notes) + - [DirectoryResolver](#directoryresolver) + - [DirectoryResolver Example](#directoryresolver-example) + - [DirectoryResolver Configuration Options](#directoryresolver-configuration-options) + - [Reducing boilerplate](#reducing-boilerplate) + - [Default parameters](#default-parameters) + - [Builtin constants](#builtin-constants) + - [Resolver type inference](#resolver-type-inference) + - [YAML anchors](#yaml-anchors) + +## Quickstart + +This repository is a test suite for UPWARD compliance, testing several scenarios and features on a live web server. It requires NodeJS v8 LTS or later. To test an UPWARD server: + +1. Write or obtain a POSIX shell script which: + + - gets the path to an UPWARD definition file from the environment variable `UPWARD_PATH` + - launches and/or binds the UPWARD server under test and runs it in the foreground (not as a daemon process). + - prints the hostname and port of the now-running server instance to standard out + - responds to SIGTERM by gracefully closing the server + + [Example here.][spec-shell-script] + +2. Use `npx` to run `upward-spec` on your shell script + + ```sh + npx upward-spec ./test_my_upward.sh + ``` + +3. The shell script will run for each test suite with the environment variable `UPWARD_YAML` set to the path of a fixture YAML file for configuring a server instance. The script should launch a server (on a local port or a remote port, but resolvable to the local system) and print its host to standard out, staying in the foreground. + + The tests may run in parallel, so the server or launch script should seek open ports to bind to. When each test suite is over, the script will receive a SIGTERM or SIGKILL. + +4. By default, the test runner will print human-readable results to stdout; the argument `--xunit` will make it print XUnit-compatible (and therefore JUnit-compatible) test result XML. The argument `--tap` will make it print [Test Anything Protocol](https://testanything.org/)-compatible text. Under the hood, this uses [tape](https://github.com/substack/tape) and it can be piped to [any number of open-source TAP reporters](https://github.com/sindresorhus/awesome-tap#javascript). + +:information_source: _(The `npx` tool above is not required; it's a convenience script to avoid installing global NPM dependencies. You can also install `upward-spec` permanently using `npm install -g upward-spec`, and then simply invoke `upward-spec ./test_my_upward.sh` from that point forward.)_ + +## Summary + +UPWARD definitions are YAML files which declare the behavior of an [application shell][application shell] server. An application shell server implements a strict subset of HTTP functionality: it proxies to API backends, it serves static files, and it handles an HTTP GET request for a resource by delivering a minimal app shell: the code and data to bootstrap a Progressive Web App which displays that resource. + +An App Shell is purposefully minimal, and so is an UPWARD server. It is meant to initialize or refresh sessions, deliver small HTML documents with enough server-side rendering for initial display and SEO, and then hand off subsequent request handling to the PWA running in the client. + +The declarative format of UPWARD means that an UPWARD-compliant server may be written in any programming language and run on any tech stack; therefore, a PWA can declare the URIs and behavior of the network endpoints it depends on by including an UPWARD file. + +### Simple example + +This example definition file echoes request data as text back to the client. + +```yaml +status: + resolver: inline + inline: 200 +headers: + resolver: inline + inline: + content-type: text/plain +body: + resolver: template + engine: mustache + provide: + - request + template: + resolver: inline + inline: | + {{#request}} + Headers: + {{#headerEntries}} + {{name}}: {{value}} + {{/headerEntries}} + URL: + {{#url}}{{#?protocol}}protocol: {{protocol}} + {{/?protocol}}{{#?host}}host: {{host}} + {{/?host}}{{#?hostname}}hostname: {{hostname}} + {{/?hostname}}{{#?port}}port: {{port}} + {{/?port}}pathname: {{pathname}} + {{/url}} + URL Query: + {{#queryEntries}} + {{name}}: {{value}} + {{/queryEntries}} + {{/request}} + +``` + +This trivial example demonstrates the initial properties of the context object, populated by the originating HTTP request. describes a server which always returns status 200 with a single header, `content-type`, and a text body which is a plaintext summary of the GET request properties. An example request to such a server results in: + +```sh +$ curl 'http://localhost:54422/head/shoulders?and=knees&and=toes' + +Headers: + host: localhost:54422 + user-agent: curl/7.54.0 + accept: */* +URL: + host: localhost:54422 + hostname: localhost + port: 54422 + pathname: /head/shoulders +URL Query: + and: knees,toes +``` + +## Configuration + +A spec-compliant UPWARD server should be configurable with a runtime parameter: the location of the UPWARD definition YML file. The file references external resources using [Resolvers](#resolvers). + +## Responding to requests + +**An UPWARD definition file is an instruction manual for building an HTTP response.** It links values together in a global namespace hereafter called the **context**. Each request handling cycle begins with with a new context object, with the incoming `Request` assigned to the context value `request`, and current environment variables assigned to the context value `env`. Root properties of the definition file represent other named values in the context, which Resolvers populate. Resolvers can use other context properties as input, and they can also use other Resolvers directly; in this way, the definition itself can be considered an abstract decision tree, from which code could be statically generated. + +### Execution scheduling and ordering + +1. **Resolvers must execute only when needed.** If a request handling cycle moves through ConditionalResolver branches in a way that never requires a particular context value, then that context value must never be resolved during that execution cycle. + +2. **Resolvers must execute as concurrently as possible**. The maximum concurrency is left to the implementation. A compliant server detects when a Resolver uses a context value, and delays its execution until that context value becomes available, via [topological sorting][topological sorting] of resolver execution. + +See [EXECUTION_SCHEDULING_STRATEGIES.md](EXECUTION_SCHEDULING_STRATEGIES.md) for an example of how this could be implemented. + +### Cyclic dependencies + +**An UPWARD server must detect cyclic dependencies, and should detect them as soon as possible**. Only bare string literals can be used to reference context objects in a definition file, so it should be possible to detect potential cyclic dependencies upon first processing the configuration file, before any requests are made. If a cyclic dependency is detected in this manner, the server should raise an error on startup. If a cyclic dependency occurs at runtime, the server should return a 500 error. + +### Response flush triggering + +**The root context must always eventually have non-null `status`, `headers`, and `body` properties.** Once the resolution path has assigned these three values fo context, the UPWARD-compliant server should immediately use those three values to create an HTTP response and flush it to the client. No streaming or buffering interface should be provided; UPWARD servers should not deal in data large enough to require streaming. **If all resolvers finish executing and the response is lacking any of the `status`, `headers`, or `body` properties, the server should emit a 500 error.** If it is possible at startup time to trace a path through the decision tree where this occurs, the implementation may use static analysis to do so and raise an error on startup. + +:information_source: _In real-world scenarios, the generation of `status`, `headers`, and `body` will share a lot of logic. The recommended best practice is to use an InlineResolver to create a top-level object, called something like "response", with those properties, and then define the top-level `status`, `headers`, and `body` properties to refer to that object in context, e.g. `status: response.status`. + +## Context Reference + +The context is a global namespace created for each request. It is a dictionary of values, like a JSON object. A typical response cycle may append intermediate values to the context, like a query result or a template string. Those values do not emit as part of the response. Only the `status`, `headers`, and `body` properties of the context will be flushed to the client. Since the context is the global namespace and the means of sharing values between resolvers, it may become a large object at some points in the cycle, but this should not affect performance on the client. + +Context values cannot be overwritten. A resolver which attempts to overwrite an already-set context value must raise a context conflict error. UPWARD-compliant servers should be able to identify potential context conflict errors during static analysis of the definition file and raise an error on launch. UPWARD-compliant servers must be able to identify a context conflict during runtime execution and respond with a 500 error. + +### Initial context + +When an UPWARD-compliant server receives an HTTP GET request, it must populate an initial context object with the following values: + +- `request`: an object representing the incoming HTTP request. It must have these properties: + + - `headers`: An object representing HTTP headers. Header names are lower-cased, and multiple values are joined with commas. + + - `headerEntries`: An iterable array version of the `headers` object, suitable for use in a Mustache template (which cannot iterate over plain JSON objects). For this headers object: + ```json + { + "accept": "text/html", + "host": "example.com" + } + ``` + the `headerEntries` array would be: + ```json + [ + { "name": "accept", "value": "text/html" }, + { "name": "host", "value": "example.com" } + ] + ``` + - `queryEntries`: An iterable array version of the URL `query` object, suitable for Mustache like the `headerEntries` property explained above. + + - `url`: A subset of a [URL record][url spec] as specified by WHATWG. The following properties should at least be populated; the Host header can be used to infer the origin. + + | Attribute | Example + | --------- | ------- + | `host` | `example.com:8080` + | `hostname`| `example.com` + | `port` | `8080` + | `pathname`| `/deep/blue/sea` + | `search` | `?baby=beluga` + | `query` | `{ "baby": "beluga" }` + + Because HTTP servers are sometimes unable to ascertain their own domain names or origins, it is acceptable for one or more of the `href`, `origin`, `protocol`, `username`, `password`, `host`, `hostname`, and `port` properties to be undefined. However, a compliant server MUST provide `pathname`, `search`, and `query`. + + The `query` property is not part of the WHATWG specification, but it must be included in the `url` object nevertheless. Much like the `headers` and `headerEntries` properties, these objects exist for property lookup and iteration in logic-less templates, respectively. + +- `env`: an object containing the environment variables set when the server was launched. For instance, if a Dockerfile launches the server through Apache, with an environment variable MAGENTO_GRAPHQL_ENDPOINT: + + ```dockerfile + ENV MAGENTO_GRAPHQL_ENDPOINT https://m2host.com/graphql + CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] + ``` + + then the context value `env.MAGENTO_GRAPHQL_ENDPOINT` would equal `"https://m2host.com/graphql"`. + +For convenience and concision, frequently used strings should be registered as self-referential top-level context objects. Examples include: + +- `GET`: the string `'GET'` must be included in the global context for convenience, to [reduce boilerplate](#reducing-boilerplate) + +- `POST`: the string `'POST'` must be included in the global context for convenience, to [reduce boilerplate](#reducing-boilerplate) + +- `mustache`: the string `'mustache'`, included in the global context for convenience, to [reduce boilerplate](#reducing-boilerplate) + +- Other strings that must be preset as literals in the context include: + + - `text/html` + - `text/plain` + - `application/json` + - `utf-8` + - `latin-1` + - `base64` + - `hex` + - All valid HTTP response codes, i.e. `200`, `404`, `500`, and all others. + +#### Context Path Syntax + +In UPWARD configuration, **a bare string is treated as a context lookup by default.** Some resolver configuration properties must treat bare strings as literal strings, and the default contains many constants for common strings, as mentioned earlier, so a definition file may appear to use many literal strings, but almost all string values are context lookups. + +A context lookup resembles "dot lookup" notation in JavaSript or Python, though it has simpler rules and cannot be dynamically generated. + +Rules: + +- **Valid characters**: A context lookup may contain any UTF-8 characters except control characters, whitespace, or newlines. All characters that are not lookup operators must be treated as part of a property name. _For the sake of easier manipulation in common programming languages, it is a best to use context names which are legal identifiers in those languages.)_ + - A context lookup cannot begin with a dot ., which is the lookup operator. +- **Lookup operators**: The dot . denotes a property lookup on an object. A positive integer property name in a context lookup, such as `characters.0.name`, will perform array access by index. Array indices must be positive integers; they must be specified literally, just like the rest of a context lookup string, and cannot be dynamically evaluated. +- A context lookup always starts with a **basename**. This may be any string that can be a valid YAML property name. The basename has special significance; when a top-level resolver completes resolution, it assigns a value to this name in the global context, which should trigger resolution of all paths beginning with that name. +- **Behavior for undeclared properties**: Undeclared property lookup should silently fail, resolving the empty string. If the **basename** `foo` is assigned, but it is not an object or it does not contain the property `bar`, then the context lookup `foo.bar` should wait until `foo` is assigned, and then yield the empty string. + +Parts of a context lookup: + +```txt + string property names +basename | | + | | array index | + | | | | + uxbridges.characters.0.name + | | + named property lookups +``` + +The above context lookup behaves at runtime as an instruction to wait until the `uxbridges` basename has been assigned. There must be a definition elsewhere in the definition file which assigns this property, e.g. + +```yaml +uxbridges: + resolver: service + method: POST + resolver: inline + inline: false + url: + resolver: inline + inline: http://stapi.co/api/v1/rest/character/search + headers: + resolver: inline + inline: + content-type: application/x-www-form-urlencoded + query: + resolver: inline + inline: '{ + characters @rest(type: "Character", path: ) + }' +``` + +The above definition would assign an [`HttpResponse`](#http-response) to the `uxbridges` basename once it has run. An HTTP response has no `characters` property, so the example context lookup would resolve to the empty string. However, an HTTP response does have a `body` property, so the lookup `uxbridges.body.characters.0.name` would resolve to `Kevin Uxbridge`. + +:information_source: _(Array and list handling is intentionally rudimentary in UPWARD, because of the potential for scope confusion, performance and security issues in iteration. The only recommended use case for list lookup is when a web service returns a list of items expected to have only one result, so that the result may be lifted out into a scalar value.)_ + +Since arbitrary property lookups do not through exceptions and instead return a default empty string, use [pattern matching](#conditional-resolver) to test the success or failure of requests and responses: + +```yaml +matches: uxbridges.body.characters.0..name +pattern: '.' +``` + +The regex dot character will pass if the string is non-empty, and fail if it is empty. This pattern should be common in UPWARD definitions. + +#### Using context + +Anywhere a in the definition file where a resolver is allowed, you may substitute a **context lookup** instead. A context path indicates a dependency on another root context value, which causes the current branch to wait until that value is resolved. In this example: + +```yaml +body: + resolver: conditional + when: + - matches: request.url.query.shipmentId + pattern: '\d+' + use: + resolver: template + engine: mustache + template: + resolver: file + file: + resolver: inline + inline: './renderShipment.mst' + provide: + shipment: + resolver: service + query: + resolver: file + file: + resolver: inline + inline: './getShipment.graphql' + variables: + id: request.url.query.shipmentId + - matches: request.url.query.shipmentName + pattern: '\w+' + use: + resolver: template + engine: mustache + template: + resolver: file + file: + resolver: inline + inline: './renderShipment.mst' + provide: + shipment: + resolver: service + url: env.SHIPMENTS_SVC + query: + resolver: file + file: + resolver: inline + inline: './getShipment.graphql' + variables: + name: request.url.query.shipmentName + - matches: request.url.query.shipmentTrackingNumber + pattern: '[\w\d\.]+' + use: + resolver: template + engine: mustache + template: + resolver: file + file: + resolver: inline + inline: './renderShipment.mst' + provide: + shipment: + resolver: service + url: env.SHIPMENTS_SVC + query: + resolver: file + file: + resolver: inline + inline: './getShipment.graphql' + variables: + trackingNumber: request.url.query.shipmentTrackingNumber + default: + inline: 'Please provide a query' +``` + +The matchers use the context lookups `request.url.query.shipmentId`, `request.url.query.shipmentName`, and `request.url.query.shipmentTrackingNumber` to asynchronously obtain values for comparison, as soon as they have been derived. The request object is part of the initial context, but you can also declare dependencies on other context values you have defined. The above definition could be more concisely expressed using intermediate values and more context lookups: + +```yaml + +body: + resolver: conditional + when: + - matches: gqlVariables + pattern: null + use: + inline: 'Please provide a query' + default: + resolver: template + engine: mustache + template: + resolver: file + file: + resolver: inline + inline: './renderShipment.mst' + provide: + shipment: + resolver: service + url: env.SHIPMENTS_SVC + query: + resolver: file + file: + resolver: inline + inline: './getShipment.graphql' + variables: gqlVariables +gqlVariables: + resolver: conditional + when: + - matches: request.url.query.shipmentId + pattern: '\d+' + use: + resolver: inline + inline: + id: request.url.query.shipmentId + - matches: request.url.query.shipmentName + pattern: '\w+' + use: + resolver: inline + inline: + name: request.url.query.shipmentName + - matches: request.url.query.shipmentTrackingNumber + pattern: '[\w\d\.]+' + use: + resolver: inline + inline: + trackingNumber: request.url.query.trackingNumber + default: null +``` + +The above definition produces a server with identical behavior to the previous query, in 30% fewer lines. This is not the only way to use context values to reduce the first, repetitive definition, but it demonstrates the idea. If the GraphQL service set an order of precedence for the shipment query which used the same priority logic as the ConditionalResolver, the definition could be further reduced to use the same variable set in all cases: + +```yaml +body: + resolver: conditional + when: + - matches: request.url.query.shipmentId + pattern: '\d+' + use: getShipment + - matches: request.url.query.shipmentName + pattern: '\w+' + use: getShipment + - matches: request.url.query.shipmentTrackingNumber + pattern: '[\w\d\.]+' + use: getShipment + default: + inline: 'Please provide a query' +getShipment: + resolver: template + engine: mustache + template: + resolver: file + file: + resolver: inline + inline: './renderShipment.mst' + provide: + shipment: + resolver: service + url: env.SHIPMENTS_SVC + query: + resolver: file + file: + resolver: inline + inline: './getShipment.graphql' + variables: + id: request.url.query.shipmentId + name: request.url.query.shipmentName + trackingNumber: request.url.query.trackingNumber +``` + +Setting top-level context properties for reusable values is an important way to reduce verbosity and code duplication in the definition file. See [Reducing boilerplate](#reducing-boilerplate) for more practices to reduce verbosity in a definition file. + +#### Context persistence and size + +When writing UPWARD definitions, no distinction needs to be made between "persistent" context values that should be the same for each request, and other values that may differ for each request. An UPWARD server must do topological sorting to determine the order in which to run Resolvers, so an efficient implementation can identify the parts of the root context that are not dependent on the incoming request and cache or discard them. + +## Resolver Reference + +A Resolver is an object which describes how a value is obtained. There are five kinds of Resolver: + +- `InlineResolver` adds hardcoded values +- `FileResolver` loads files from a filesystem +- `ServiceResolver` places GraphQL queries and loads the result set +- `TemplateResolver` renders a template string against the context +- `ConditionalResolver` does branch logic using pattern matching on context values +- `ProxyResolver` delegates request/response handling to a proxy +- `DirectoryResolver` delegates request/response handling to a static file directory + +Each Resolver takes different configuration parameters. Like a context lookup string, a resolver represents an operation which will execute and then deliver its results upward in the tree, until all dependencies of the top-level `status`, `headers`, and `body` definitions are resolved. + +### InlineResolver + +There is sometimes a need to put literal values in the context. However, a string property value performs a context lookup: + +```yaml +body: 'Hello world!' +``` + +The above expression uses `Hello world!` as a property name and tries to substitute the value of the context property named `Hello world!`. This is likely not the intent of the user. To set the `body` to the literal string 'Hello world!', use an `InlineResolver`: + +```yaml +body: + resolver: inline + inline: 'Hello world!' +``` + +The `inline` of an InlineResolver may be of any type; it may be a primitive value, a list, or an object of arbitrary depth. List values and Object properties may be context lookups or resolvers themselves, so when building lists or objects, make sure to use InlineResolvers again at every other level of depth. _(A consequence of this is that it is difficult and verbose to set a literal value resembling a resolver configuration, such as `{ "resolver": "inline" }`, but this seems to be a minor inconvenience.)_ + +#### InlineResolver Configuration Options + +| Property | Type | Default | Description +| -------- | ---- | ------- | --------------------------------------------- +| `inline` | `any`| | _Required._ The value to be assigned to context. + +### FileResolver + +Queries and templates are often large, and often reused by other systems. They can be inline strings, as in the [first example](#simple-example), but they should usually be separate files, referenced with a `FileResolver`. + +```yaml +query: + resolver: file + file: + resolver: inline + inline: './productDetail.graphql' + encoding: + resolver: inline + inline: 'utf-8' +``` + +The above expression loads the content of the file `./productDetail.graphql` and sets it as the property `query`. The file path is resolved relative to the location of the definition file. The `encoding` property is optional. + +#### FileResolver Configuration Options + +| Property | Type | Default | Description +| -------- | ---------- | ------- | --------------------------------------------- +| `file` | `Resolved` | | _Required_. Path to the file to be read. Resolved relative to the definition file. +| `encoding` | `Resolved` | `utf-8` | Character set to use when reading the file as text. Can be `utf-8`, `latin-1`, or `binary`. +| `parse` | `Resolved` | `auto` | Attempt to parse the file as a given file type. The default of `auto` should attempt to determine the file type from its extension. The value `text` will effectively disable parsing. + +#### Parsing + +An UPWARD server must support pre-parsing of `graphql`, `json`, and `mustache` files according to their respective specifications, but should support as many filetypes as necessary and may support custom filetypes. + +#### FileResolver Error Handling + +If the file cannot be found or there were any other failures reading the file, the resolver must resolve an object with a single `errors` property instead of a string or a parsed value. Errors must be formatted like [GraphQL errors][graphql spec errors property]. + +:information_source: _(File contents are not expected to change during server runtime, so an UPWARD-compliant server should cache file contents on startup.)_ + +#### FileResolver shorthand + +Filenames are usually not variable; they will usually be specified as literals, rather than dynamically resolved out of context. For readability and convenience, a "shorthand syntax" must be available to imply a FileResolver that loads and parses a UTF-8 encoded file from a string filesystem path. Instead of explicitly resolving a filepath as an inline string: + +```yaml +query: + resolver: file + file: + resolver: inline + inline: './path/to/file.graphql' +``` + +The shorthand syntax should allow the following to be equivalent: + +```yaml +query: './path/to/file.graphql' +``` + +An UPWARD-compliant server must treat a barestring as a literal filepath instead of a context lookup when: + +- The string is being argued to a configuration parameter that accepts a FileResolver for the implied type of the file after parsing + + AND + +- The string begins with one of the following prefixes: + - a relative path prefix, `./` and/or one or more `../` + - an absolute path prefix, `/` or `C:\` or any other Windows drive letter + - a file URI scheme, `file://` + + AND + +- Upon checking the filesystem, the string resolves to a [regular file][regular file] (not a symlink, device, or directory) + +In the latter case, if the shorthand string neither resolves to a legal file, nor exists as a resolvable context value, an UPWARD-compliant server should raise a detailed error message explaining this. + +### ServiceResolver + +An UPWARD server uses a `ServiceResolver` to obtain live data from a GraphQL backing service. URL, method, and headers can be specified manually; the query itself is constructed using `query` and `variables` parameters. + +```yaml +documentResult: + resolver: service + url: + resolver: inline + inline: 'https://example.com/graphql' + method: + resolver: inline + inline: POST + headers: + resolver: inline + inline: + 'content-type': 'application/json' + accept: 'application/json' + # A small inline template renders the full syntax of the OAuth Bearer + # token header, instead of just the plain token. + authorization: + resolver: template + engine: 'mustache' + template: + resolver: 'inline' + inline: 'Bearer {{env.BEARER_TOKEN}}' + query: + resolver: inline + inline: 'query getDocument($id: String!) { + document(id: $id) { + title + contents + } + }' + variables: + resolver: inline + inline: + # This is a barestring indicating a context lookup. It resolves to the + # `id` value in the URL query string of the request, using the builtin + # `request` context object. + id: request.url.query.id +``` + +:information_source: _(For the purposes of demonstration, the query here is resolved inline. The best practice is to store queries in files and use FileResolvers to obtain them.)_ + +#### ServiceResolver Configuration Options + +| Property | Type | Default | Description +| --------- | ------------------ | --------------------------- | --------------- +| `url` | `Resolved` | `https://localhost/graphql` | _Required_. The URL of the service endpoint to call. +| `method` | `Resolved` | `POST` | The HTTP method to use. While GraphQL queries are typically POSTS, some services expose GraphQL over GET instead. +| `headers` | `Resolved>` | | Additional HTTP headers to send with the GraphQL request. Some headers are set automatically, but the `headers` configuration can append to headers that can have multiple values. +| `query` | `Resolved` | | _Required_. The GraphQL query object. Can either be a parsed query, or a string that can be parsed as a valid query. +| `variables` | `Resolved>` | `{}` | Variables to use with the GraphQL query. Must resolve to an object with keys and values, almost always with an InlineResolver. + +**ServiceResolvers always use GraphQL.** To obtain data from a non-GraphQL service, an UPWARD server may implement client-side directives which change the behavior of a GraphQL query, such as [apollo-link-rest][apollo-link-rest], and place the directives in the query itself. This should be transparent to the UPWARD server itself, which delegates the service call to a GraphQL client. If an UPWARD server's GraphQL client has no implementation for such a directive, then it must pass the query unmodified to the backing service to handle the directive. + +#### Example REST service call + +The below behavior is not standard or normative: it is an example of how one might query a REST service using an UPWARD server whose GraphQL client implementation has a `@rest` directive like [apollo-link-rest][apollo-link-rest]. + +```yaml +documentResult: + resolver: service + url: env.REST_API_ENDPOINT + method: + resolver: inline + inline: GET + headers: + # In contrast to the template above, this assumes that en environment + # variable is already set with the "Bearer " format. + inline: + authorization: env.BEARER_TOKEN_STRING + query: 'query getDocument($id: String!) { + document(id: $id) @rest(type: "Document", path: "/documents/{args.id}") { + title + contents + } + links(documentId: $id) { + name + url + } + }' + variables: + inline: + id: request.url.query.id +``` + +#### Response Assignment + +The GraphQL specification requires that a successful response to a GraphQL query have a [root "data" property][graphql spec data property], an object whose properties correspond to the entities returned, and an that a failed response have a [root "errors" property][graphql spec errors property]. **An UPWARD server must assign the entire root object to the named context value.** The query above would, if successful, result in a context with `documentResult.data.document` and `documentResult.data.links` properties. If the query failed, the context would contain `documentResult.errors`. + +#### ServiceResolver Error Handling + +The GraphQL specification [defines error behavior][graphql spec errors] clearly, and UPWARD servers should pass the `errors` collection from a GraphQL response as described above. Other errors can occur during resolution, such as: + +- Network errors: the URL is unresolvable or unresponsive +- Parse errors: a dynamically supplied `query` could not be parsed +- Validation errors: required variables were absent or the wrong type + +An UPWARD server should format these errors the same way that GraphQL services do; it should return an object with an `errors` array containing all errors encountered. + +### TemplateResolver + +Once the UPWARD server assembles the data for a response, it must turn that data into a response body. The `TemplateResolver` renders a template into a string, executing it with the context object as its root value by default. UPWARD servers must provide a Mustache template renderer that adheres to the [Mustache specification][mustache spec]. UPWARD servers can also provide other template renderers, which must evaluate context objects into strings. + +```yaml +status: + resolver: inline + inline: 200 +headers: + resolver: inline + inline: + 'content-type': + resolver: inline + inline: 'text/html' +body: + resolver: template + engine: + resolver: inline + inline: mustache + root: documentResult.data.document + template: + resolver: inline + inline: | + {{> headtag}} + {{> header}} +
+

{{title}}

+
+ {{& contents}} +
+
+ {{> footer}} +``` + +The above configuration resolves into an HTML document displaying content from the `documentResult.data.document` context value. Its use of [Mustache partials][mustache partials] implies that additional files called `headtag.mst`, `header.mst`, and `footer.mst` exist in the directory containing the definition file. Attempting to include a missing partial should raise an error as soon as the template is resolved, ideally at server startup time. + +:information_source: _(For illustrative purposes, the above uses an InlineResolver where it would be more appropriate to use a FileResolver to obtain the template, as with the query in the ServiceResolver example.)_ + +#### TemplateResolver Configuration Options + +| Property | Type | Default | Description +| --------- | ------------------ | --------------------------- | --------------- +| `engine` | `Resolved` | | _Required_. The label of the template engine to use. +| `provide` | `Resolved>` | | _Required._ A list, or an object mapping, of values to make available in the template. Passing the entire context to a template for evaluation can cause cyclic dependencies. +| `template` | `Resolved` | | The template to render. + +#### Template Context + +The entire context cannot be available for template render; that would cause an immediate circular dependency, since the template's output is added to context! Instead, use the `provide` argument to select what values the template actually needs. They will be available, at root, inside the template. + +The `provide` argument can be a list: + +```yaml +provide: + - env + - articleResult +``` + +The resulting template eval context might look like this: + +```json +"env": { + "envVars": "here" +}, +"articleResult": { + "data": { + "article": { + articleContents: 'here' + } + } +} +``` + +*Lists may only inject "base" context properties.* The above `articleResult` could not be `articleResult.data.article` when using the list format. + +The other, more powerful option for the `provide` argument is to provide a `mapping`, as a simple object. A mapping must resolve to a plain object of string keys and context values. It might appear as: + +```yaml +provide: + inline: + article: articleResult.data.article +``` + +This would give the template a single root property "article", thus flatting out the template tree and making templates more readable. + +```json +"article": { + articleContents: 'here' +} +``` + +#### Template Engines + +The `engine` property must resolve to a string labeling a supported template engine. The only required template engine is Mustache, and its label must be `mustache`. An UPWARD server may support additional template engines. For instance, an UPWARD server may support [ReactJS server-side rendering][react dom server]. + +##### Example React DOM Server support + +```yaml +body: + resolver: template + engine: + resolver: inline + inline: react + provide: + inline: + document: documentResult.data.document + query: request.url.query + template: + resolver: file + file: + resolver: inline + inline: './build/RootComponents/Document.js' +``` + +The above configuration assumes support for a template engine labeled `react`. The underlying template engine could be a simple Node module: + +```js +const { createElement } = require('react'); +const { renderToString } = require('react-dom/server'); + +module.exports = (props, component) => + renderToString(createElement(require(component), props)); +``` + +Attaching such a template engine to a Resolver would be trivial. + +#### TemplateResolver Error Handling + +If the engine is unknown or not supported, the UPWARD server should detect this as soon as possible and send a 500 error. + +If there were any errors parsing the template, evaluating, or serializing the data, the resolver must resolve an object with an `errors` array instead of a rendered string. Errors must be formatted like [GraphQL errors][graphql spec errors property]. + +### ConditionalResolver + +A ConditionalResolver tests a context value for a particular pattern, and then yields to another Resolver depending on the match results. + +The ConditionalResolver is the only branch logic operation available in the UPWARD specification. It performs pattern matching on a context value using [Perl compatible regular expressions][pcre]. It can only test a single context value for each potential match, and it has no Boolean operators such as AND, OR, or NOT. All of these logical operations can be achieved through pattern matching, however. It takes two configuration values: `when` must be a list of `Matcher>>`, and `default` must be a resolver to use if none of the `when` conditions are true. + +```yaml +monkey: + resolver: conditional + when: + # All values are coerced to strings for regex matching. + - matches: request.url.query.grab + pattern: '^(true|1)$' + use: + resolver: inline + inline: "do anyway" + - matches: status + pattern: '^403$' + use: + resolver: inline + inline: "see" + default: + resolver: inline + inline: "do" +status: + resolver: inline + inline: 403 +body: + resolver: template + engine: + resolver: inline + inline: mustache + template: + resolver: inline + inline: "

monkey {{ monkey }}.

" +``` + +The above configuration uses a ConditionalResolver to create a context value `monkey`. The `when` list contains two matchers. They are executed in order. The first matcher tests if the request query string has a value `grab` matching the regular expression `^(true|1)$`, If the request query string contains `grab=true` or `grab=1`, this matcher succeeds and the ConditionalResolver yields to the resolver specified in the matcher's `use` property. The context now matches the object: + +```json +{ + "status": 403, + "monkey": "do anyway", + "body": "

monkey do anyway

" +} +``` + +If the request query string does not contain a qualifying `grab` property, the second matcher runs. This matcher tests if the `status` context value matches the regular expression `^403$`, effectively checking if the response status code has already been set to HTTP 403 Forbidden. The `status` resolver runs before the `monkey` resolver, though it is defined later in the document (see [Concurrency](#concurrency)), so the matcher tests against the value `403` (cast to a string) and succeeds. The ConditionalResolver uses the matcher's resolver, and the context now matches the object: + +```json +{ + "status": 403, + "monkey": "see", + "body": "

monkey see

" +} +``` + +If some other configuration provides a different `status`, such as `200`, then neither matcher in the `when` list succeeds, and the ConditionalResolver uses its `default` resolver. The context now matches the object: + +```json +{ + "status": 200, + "monkey": "do", + "body": "

monkey do

" +} +``` + +#### ConditionalResolver Configuration Options + +| Property | Type | Default | Description +| --------- | ------------------ | ----------- | --------------- +| `when` | `Matcher[]` | | | _Required_. The list of matchers to test against context. +| `default` | `Resolved` | | _Required_. The default resolver to use if no matcher succeeds. + +#### Matchers + +A `Matcher` is an object which can only be used as an item in a ConditionalResolver's `when` list. It must have the following properties: + +| Property | Type | Default | Description +| --------- | ------------------ | ------- | --------------- +| `matches` | `string` | | _Required_. The context value to match. Must be a bare string context lookup. +| `pattern` | `string` | | _Required_. [PCRE][pcre] regular expression to use to test against the value in `matches`. +| `use` | `Resolved` | | _Required_. Resolver to use if the match succeeds. + +#### Match context + +During the resolution of a matcher's `use` resolver, properties from the match object are temporarily added to the context. Using these temporary context values, resolvers can extract matching text, or capture groups, from the match itself. + +- `$match.$0` - The full text of the last matched value. +- `$match.$1` - The string captured in the first backreference the regex declared. + +The `$match` object must have additional numbered properties for each backreference. + +#### ConditionalResolver notes + +- Matchers run in sequence, top to bottom. They do not "fall through"; the first + successful matcher will exit the conditional. +- Matchers can only test against context properties; they cannot use a resolver as the `matches` value. +- Each matcher can test only one context property against one pattern. + - However, the pattern can use regex alternation to achieve OR-type logic. + - Additionally, a list of matchers need not each test the same property. +- The `default` resolver is required. +- To achieve AND-like logic, nest ConditionalResolvers to arbitrary depth. +- To achieve OR-like logic, repeat the same resolver configuration in several subsequent matchers. +- If the conditional becomes verbose, consult [Reducing Boilerplate](#reducing-boilerplate) for ways to simplify it. +- Though template engines with logical operators can be also be used to perform branch logic, this is not recommended; it can prevent static analysis of context value dependencies. + +### ProxyResolver + +The ProxyResolver acts as a "passthrough" to another service. It is guaranteed to resolve into an object with `status`, `headers`, and `body` properties from a logical point of view. In implementation, it may handle request objects more directly, for performance purposes. + +A ProxyResolver is an important part of the UPWARD philosophy: a PWA's UPWARD file must describe all of the network behavior that a PWA expects at runtime, and that includes proxies to various backing APIs. + +#### ProxyResolver Example + +```yaml +proxy: + target: env.MAGENTO_BACKEND_DOMAIN + ignoreSSLErrors: true +``` + +#### ProxyResolver Configuration Options + +| Property | Type | Default | Description +| --------- | ------------------ | ----------- | --------------- +| `target` | `Resolved` | | | _Required_. The URL that receives proxied requess. +| `ignoreSSLErrors` | `Resolved` | `false` | Ignore remnote SSL certificate errors (useful for internal communication among containers). + +#### ProxyResolver notes + +ProxyResolvers are special targets for static analysis. Using simple techniques, it should be possible for an analysis system to determine proxying rules by walking the UPWARD tree. This is effectively a _declarative proxy config_, and deployment tools can be enhanced to create proxy servers in front of UPWARD where appropriate. + +### DirectoryResolver + +Like the ProxyResolver, the DirectoryResolver delegates request and response handling to a static server. Unlike the ProxyResolver, it needs access to a local directory, which it will then sere as a public assets folder. Much like the ProxyResolver, this resolver exists to bolster the notion that an UPWARD file can describe the expected behavior of a PWA server-side site, in detail. + +#### DirectoryResolver Example + +```yaml +static: + directory: + inline: './dist' + +``` + +#### DirectoryResolver Configuration Options + +| Property | Type | Default | Description +| --------- | ------------------ | ----------- | --------------- +| `directory` | `Resolved` | | | _Required_. The local directory path to be served. + + +## Reducing boilerplate + +The above examples are fairly verbose, to make the workings of UPWARD configuration especially clear. The UPWARD specification is intentionally verbose in its canonical format, to enable maximal static analysis. However, An UPWARD-compliant server must also include features to reduce boilerplate. + +### Default parameters + +Many resolver configuration parameters have default values, so they can be omitted from configuration if the default is appropriate. + +In the first example of a [ServiceResolver](#serviceresolver) above, some config parameters are actually unnecessary. The default URL for a service call is `http://localhost/graphql`, and the default method is `POST`. MIME headers are automatically generated, so the following configuration would be equivalent: + +```yaml +documentResult: + resolver: service + headers: + resolver: inline + inline: + Authorization: env.BEARER_TOKEN + query: + resolver: inline + inline: 'query getDocument($id: String!) { + document(id: $id) { + title + contents + } + }' + variables: + id: request.url.query.id +``` + +Using the best practice of storing queries in separate files and storing reusable objects as separate context values, the configuration would likely look like this: + +```yaml +documentQuery: './queries/document.graphql' +oauthHeaders: + resolver: inline + inline: + authorization: env.BEARER_TOKEN + +documentResult: + resolver: service + headers: oauthHeaders + query: documentQuery + variables: + id: request.url.query.id +``` + +### Builtin constants + +The default context must contain some builtin constants for common strings, to avoid repetitive use of InlineResolvers. + +In the first example of a [TemplateResolver](#templateresolver) above, some inline resolvers are unnecessary. HTTP response codes, common MIME types, common template engine labels, and other useful values must be preset in the initial context, so the following, shorter configuration is equivalent to the TemplateResolver example: + +```yaml +status: 200 +headers: + resolver: inline + inline: + 'content-type': 'text/html' +body: + resolver: template + engine: 'mustache' + provide: + model: documentResult.data.document + template: + resolver: inline + inline: | + {{> headtag}} + {{> header}} +
+

{{model.title}}

+
+ {{& contents}} +
+
+ {{> footer}} +``` + +### Resolver type inference + +For any value which must be a Resolver or a context lookup, an UPWARD-compatible server should attempt to infer resolver types from a supplied resolver configuration object, rather than requiring a `resolver` name to be specified. Each resolver has required parameters that are mutually exclusive with one another, so a resolver type can be inferred from the presence of those parameters. + +| If parameter exists... | Then infer resolver type: +| ---------------------: | :-----------------------: +| `inline` | `InlineResolver` +| `file` | `FileResolver` +| `query` | `ServiceResolver` +| `engine` | `TemplateResolver` +| `when` | `ConditionalResolver` +| `target` | `ProxyResolver` +| `directory` | `DirectoryResolver` + +Resolver type inference allows configuration to omit `resolver:` parameters, which makes it possible to be far more terse. The example optimized configuration in [Builtin constants](#builtin-constants) could be further reduced: + +```yaml +status: 200 +headers: + inline: + 'content-type': 'text/html' +body: + engine: 'mustache' + root: documentResult.data.document + template: + inline: | + {{> headtag}} + {{> header}} +
+

{{title}}

+
+ {{& contents}} +
+
+ {{> footer}} +``` + +And the example optimized configuration in [Default parameters](#default-parameters) could be further reduced: + +```yaml +documentResult: + headers: + inline: + authorization: env.BEARER_TOKEN + query: './queries/document.graphql' + variables: + id: request.url.query.id +``` + +:information_source: _(Note that the `variables` object cannot be a resolver, as specified in [ServiceResolver configuration options](#serviceresolver-configuration-options) — it must be an object whose keys are expected query variable names and whose values are resolvers, so there is no ambiguity if a GraphQL query expects a variable named, for example, `file`.)_ + +### YAML anchors + +The YAML specificationsupports an [anchor and reference syntax][yaml anchors] which can also be used to shorten configuration files. While this can be used as part of legal YAML parsing, its use is discouraged by UPWARD files, since context resolution is clearer to the reader. Additionally, not all parsers support references in the same way, so the feature should be used with caution. + +[apollo-link-rest]: +[application shell]: +[pwa def]: +[js identifiers]: +[npx]: +[spec-shell-script]: <./test_my_upward.sh> +[yaml anchors]: +[pcre]: +[graphql spec data property]: +[graphql spec errors property]: +[mustache spec]: +[mustache partials]: +[react dom server]: +[topological sorting]: +[url spec]: +[regular file]: diff --git a/packages/upward-spec/UPWARD_MAGENTO.md b/packages/upward-spec/UPWARD_MAGENTO.md new file mode 100644 index 00000000000..1cb2b36fd29 --- /dev/null +++ b/packages/upward-spec/UPWARD_MAGENTO.md @@ -0,0 +1,3 @@ +# Why UPWARD for Magento PWA Studio + +Magento PWA Studio is meant to be cheap and easy to run; it should not be tied to a specific tech stack. A middle tier server is necessary to decouple PWA Studio from the Magento Theme resolution tier, which requires two-way binding in the filesystem. UPWARD allows us to require this middle tier without requiring a specific tech stack. diff --git a/packages/upward-spec/backing_services.png b/packages/upward-spec/backing_services.png new file mode 100644 index 0000000000000000000000000000000000000000..4207b00f6bb24760bb89dd1642fc3306e8c3271b GIT binary patch literal 19395 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 otherArgs.some(arg => arg === wanted); + +const useXunit = hasArg('--xunit'); +const useTap = hasArg('--tap'); + +if (useXunit && useTap) { + console.error( + 'Cannot use both --xunit and --tap flags. Please choose either XUnit output, TAP output, or no arguments for default human-readable output.' + ); +} + +const isPiped = !process.stdout.isTTY; + +const raw = useTap || isPiped; + +// Run tap and pass stdout. +const scenariosDir = path.resolve(__dirname, '../suite/scenarios/'); +const testProcess = require('child_process').spawn( + path.resolve(__dirname, '../node_modules/.bin/tape'), + ['*/tests.js'], + { + cwd: scenariosDir, + env: Object.assign( + { + UPWARD_SERVER_SCRIPT_PATH: providedScriptPath + }, + process.env + ) + } +); + +if (raw) { + testProcess.stdout.pipe(process.stdout); +} else if (useXunit) { + const tapXunit = require('tap-xunit'); + testProcess.stdout + .pipe(tapXunit({ package: 'UPWARD spec' })) + .pipe(process.stdout); +} else { + const tapDiff = require('tap-diff'); + testProcess.stdout.pipe(tapDiff()).pipe(process.stdout); +} +testProcess.stderr.pipe(process.stderr); diff --git a/packages/upward-spec/package-lock.json b/packages/upward-spec/package-lock.json new file mode 100644 index 00000000000..f1c7950a7dd --- /dev/null +++ b/packages/upward-spec/package-lock.json @@ -0,0 +1,1617 @@ +{ + "name": "@magento/upward-spec", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@apollographql/apollo-upload-server": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz", + "integrity": "sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0-rc.1", + "busboy": "^0.2.14", + "object-path": "^0.11.4" + } + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz", + "integrity": "sha512-QAZIFrfVRkjvMkUHIQKZXZ3La0V5t12w5PWrhihYEabHwzIZV/txQd/kSYHgYPXC4s5OURxsXZop9f0BzI2QIQ==" + }, + "@babel/runtime-corejs2": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.0.0.tgz", + "integrity": "sha512-Yww0jXgolNtkhcK+Txo5JN+DjBpNmmAtD7G99HOebhEjBzjnACG09Tip9C8lSOF6PrhA56OeJWeOZduNJaKxBA==", + "requires": { + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", + "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "requires": { + "@types/node": "*" + } + }, + "@types/cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.4.tgz", + "integrity": "sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw==", + "requires": { + "@types/express": "*" + } + }, + "@types/events": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==" + }, + "@types/express": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.0.tgz", + "integrity": "sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz", + "integrity": "sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w==", + "requires": { + "@types/events": "*", + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/graphql": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.12.6.tgz", + "integrity": "sha512-wXAVyLfkG1UMkKOdMijVWFky39+OD/41KftzqfX1Oejd0Gm6dOIKjCihSVECg6X7PHjftxXmfOKA/d1H79ZfvQ==" + }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, + "@types/mime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", + "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" + }, + "@types/node": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.9.4.tgz", + "integrity": "sha512-fCHV45gS+m3hH17zgkgADUSi2RR1Vht6wOZ0jyHP8rjiQra9f+mIcgwPQHllmDocYOstIEbKlxbFDYlgrTPYqw==" + }, + "@types/range-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.2.tgz", + "integrity": "sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw==" + }, + "@types/serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "@types/ws": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz", + "integrity": "sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "apollo-cache-control": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.2.2.tgz", + "integrity": "sha512-N5A1hO6nHZBCR+OCV58IlE7k6hZrFJZTf/Ab2WD8wduLSa0qLLRlCp3rXvD05+jpWa6sdKw03whW2omJ+SyT+w==", + "requires": { + "apollo-server-env": "2.0.2", + "graphql-extensions": "0.1.2" + } + }, + "apollo-datasource": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.1.2.tgz", + "integrity": "sha512-AbUxS7Qkz9+T+g19zKRJiA+tBVGVVunzXwd4ftDSYGx1VrF5LJJO7Gc57bk719gWIZneZ02HsVCEZd6NxFF8RQ==", + "requires": { + "apollo-server-caching": "0.1.2", + "apollo-server-env": "2.0.2" + } + }, + "apollo-engine-reporting": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-0.0.2.tgz", + "integrity": "sha512-Fe/1oxC8rUXRrBTMUiqs5PSb6hnMOJHuttJMhs83u5POfplc4QrKJZtEEU4Ui8mxeJGaGNWbWf+D4q645xdQLA==", + "requires": { + "apollo-engine-reporting-protobuf": "0.0.1", + "apollo-server-env": "2.0.2", + "async-retry": "^1.2.1", + "graphql-extensions": "0.1.2", + "lodash": "^4.17.10" + } + }, + "apollo-engine-reporting-protobuf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz", + "integrity": "sha512-AySoDgog2p1Nph44FyyqaU4AfRZOXx8XZxRsVHvYY4dHlrMmDDhhjfF3Jswa7Wr8X/ivvx3xA0jimRn6rsG8Ew==", + "requires": { + "protobufjs": "^6.8.6" + } + }, + "apollo-link": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.2.tgz", + "integrity": "sha512-Uk/BC09dm61DZRDSu52nGq0nFhq7mcBPTjy5EEH1eunJndtCaNXQhQz/BjkI2NdrfGI+B+i5he6YSoRBhYizdw==", + "requires": { + "@types/graphql": "0.12.6", + "apollo-utilities": "^1.0.0", + "zen-observable-ts": "^0.8.9" + } + }, + "apollo-server": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/apollo-server/-/apollo-server-2.0.5.tgz", + "integrity": "sha512-Li840fL17GGQWnTi6HpzmzgQb3MbBtJLmKzWgbXU9FJQsp1ZbiLnOgT136DeBf7n1gbvgLuxlLGgfYrD3QAwnA==", + "requires": { + "apollo-server-core": "2.0.4", + "apollo-server-express": "2.0.4", + "express": "^4.0.0", + "graphql-subscriptions": "^0.5.8", + "graphql-tools": "^3.0.4" + } + }, + "apollo-server-caching": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz", + "integrity": "sha512-jBRnsTgXN0m8yVpumoelaUq9mXR7YpJ3EE+y/alI7zgXY+0qFDqksRApU8dEfg3q6qUnO7rFxRhdG5eyc0+1ig==", + "requires": { + "lru-cache": "^4.1.3" + } + }, + "apollo-server-core": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.0.4.tgz", + "integrity": "sha512-6kNaQYZfX2GvAT1g9ih0rodfRl4hPL1jXb7b+FvQ1foFR5Yyb3oqL2DOcP65gQi/7pGhyNRUAncPU18Vo3u9rQ==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@types/ws": "^5.1.2", + "apollo-cache-control": "0.2.2", + "apollo-datasource": "0.1.2", + "apollo-engine-reporting": "0.0.2", + "apollo-server-caching": "0.1.2", + "apollo-server-env": "2.0.2", + "apollo-server-errors": "2.0.2", + "apollo-tracing": "0.2.2", + "graphql-extensions": "0.1.2", + "graphql-subscriptions": "^0.5.8", + "graphql-tag": "^2.9.2", + "graphql-tools": "^3.0.4", + "hash.js": "^1.1.3", + "lodash": "^4.17.10", + "subscriptions-transport-ws": "^0.9.11", + "ws": "^5.2.0" + } + }, + "apollo-server-env": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.0.2.tgz", + "integrity": "sha512-LsSh2TSF1Sh+TnKxCv2To+UNTnoPpBGCXn6fPsmiNqVaBaSagfZEU/aaSu3ftMlmfXr4vXAfYNUDMKEi+7E6Bg==", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-errors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz", + "integrity": "sha512-zyWDqAVDCkj9espVsoUpZr9PwDznM8UW6fBfhV+i1br//s2AQb07N6ektZ9pRIEvkhykDZW+8tQbDwAO0vUROg==" + }, + "apollo-server-express": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.0.4.tgz", + "integrity": "sha512-9mxcFpnTgQTmrsvVRRofEY7N1bJYholjv99IfN8puu5lhNqj8ZbOPZYrw+zd+Yh4rZSonwx76ZzTRzM00Yllfw==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@apollographql/graphql-playground-html": "^1.6.0", + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.17.0", + "@types/cors": "^2.8.4", + "@types/express": "4.16.0", + "accepts": "^1.3.5", + "apollo-server-core": "2.0.4", + "body-parser": "^1.18.3", + "cors": "^2.8.4", + "graphql-subscriptions": "^0.5.8", + "graphql-tools": "^3.0.4", + "type-is": "^1.6.16" + }, + "dependencies": { + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + } + } + }, + "apollo-tracing": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.2.2.tgz", + "integrity": "sha512-zrpLRvaAqtzGufc1GfV+691xQtzq5elfBydg/7wzuaFszlMH66hkLas5Dw36drUX21CbCljOuGYvYzqSiKykuQ==", + "requires": { + "apollo-server-env": "2.0.2", + "graphql-extensions": "0.1.2" + } + }, + "apollo-utilities": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.0.19.tgz", + "integrity": "sha512-pyVxizjIevHFfKhtc9FLEsGHmqiK0kHx1aBdJRUXDt+X+yjoVa/fVeCEo9t0NddGximemxxrQnq6lSkbIQvDlA==", + "requires": { + "fast-json-stable-stringify": "^2.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "async-retry": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.1.tgz", + "integrity": "sha512-FadV8UDcyZDjzb6eV7MCJj0bfrNjwKw7/X0QHPFCbYP6T20FXgZCYXpJKlQC8RxEQP1E6Xs8pNHdh3bcrZAuAw==", + "requires": { + "retry": "0.10.1" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "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": { + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "csv-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-3.0.0.tgz", + "integrity": "sha512-h58BzkfwYNY1gyfl6NUZe1OKxXy/Pn6ZeXlkz3fdLdg/r3Om+lgMySw9SxH7rDs8ARFFyIc6UI6fLnaeRkjNPQ==" + }, + "death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=" + }, + "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" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "deprecated-decorator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", + "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "diff": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", + "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=" + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" + }, + "events-to-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", + "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=" + }, + "express": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "requires": { + "accepts": "~1.3.5", + "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.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "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.3", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "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=" + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graphql": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.13.2.tgz", + "integrity": "sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog==", + "requires": { + "iterall": "^1.2.1" + } + }, + "graphql-extensions": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.1.2.tgz", + "integrity": "sha512-A81kfGtOKG0/1sDQGm23u60bkTuk9VDof0SrQrz7yNpPLY48JF11b8+4LNlYfEBVvceDbLAs1KRfyLQskJjJSg==", + "requires": { + "apollo-server-env": "2.0.2" + } + }, + "graphql-subscriptions": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz", + "integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==", + "requires": { + "iterall": "^1.2.1" + } + }, + "graphql-tag": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.9.2.tgz", + "integrity": "sha512-qnNmof9pAqj/LUzs3lStP0Gw1qhdVCUS7Ab7+SUB6KD5aX1uqxWQRwMnOGTkhKuLvLNIs1TvNz+iS9kUGl1MhA==" + }, + "graphql-tools": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-3.1.1.tgz", + "integrity": "sha512-yHvPkweUB0+Q/GWH5wIG60bpt8CTwBklCSzQdEHmRUgAdEQKxw+9B7zB3dG7wB3Ym7M7lfrS4Ej+jtDZfA2UXg==", + "requires": { + "apollo-link": "^1.2.2", + "apollo-utilities": "^1.0.1", + "deprecated-decorator": "^0.1.6", + "iterall": "^1.1.3", + "uuid": "^3.1.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "hash.js": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "dependencies": { + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + } + } + }, + "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==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "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-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "iterall": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", + "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" + }, + "mime-types": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "requires": { + "mime-db": "~1.35.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "node-fetch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "parse-ms": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", + "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=" + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "plur": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=" + }, + "pretty-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", + "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", + "requires": { + "is-finite": "^1.0.1", + "parse-ms": "^1.0.0", + "plur": "^1.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "range-parser": { + "version": "1.2.0", + "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": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "requires": { + "path-parse": "^1.0.5" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "requires": { + "through": "~2.3.4" + } + }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "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.4.0" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "subscriptions-transport-ws": { + "version": "0.9.14", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.14.tgz", + "integrity": "sha512-n1+mgupVdJn1MIls1ZhSJurJjc+islp7Tv9EIaEJ3HAd9DaINneKq0KRqOYNOrvUI7orVWGomEnlIxoudjfbeA==", + "requires": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "tap-diff": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tap-diff/-/tap-diff-0.1.1.tgz", + "integrity": "sha1-j78zM9hWQ/7qG/F1m5CCCwSjfd8=", + "requires": { + "chalk": "^1.1.1", + "diff": "^2.2.1", + "duplexer": "^0.1.1", + "figures": "^1.4.0", + "pretty-ms": "^2.1.0", + "tap-parser": "^1.2.2", + "through2": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "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=" + } + } + }, + "tap-parser": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.3.2.tgz", + "integrity": "sha1-EgxQiciMPIp5PvKIhn3jIeGPjCI=", + "requires": { + "events-to-array": "^1.0.1", + "inherits": "~2.0.1", + "js-yaml": "^3.2.7", + "readable-stream": "^2" + } + }, + "tap-xunit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tap-xunit/-/tap-xunit-2.3.0.tgz", + "integrity": "sha512-YVsURNvn1wfVUWb5wjansxhfbfeo2hOBTUbVgZoaMO8lyZzpiSi9IiZTZ7JG56m6A49LeWjfJIx/SnAre41V/A==", + "requires": { + "duplexer": "~0.1.1", + "minimist": "~1.2.0", + "tap-parser": "~1.2.2", + "through2": "~2.0.0", + "xmlbuilder": "~4.2.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "tap-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.2.2.tgz", + "integrity": "sha1-Xi9pcGEfB5x8+FfeHceqG0gN56U=", + "requires": { + "events-to-array": "^1.0.1", + "inherits": "~2.0.1", + "js-yaml": "^3.2.7", + "readable-stream": "^2" + } + } + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xmlbuilder": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", + "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", + "requires": { + "lodash": "^4.0.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "zen-observable": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.9.tgz", + "integrity": "sha512-Y9kPzjGvIZ5jchSlqlCpBW3I82zBBL4z+ulXDRVA1NwsKzjt5kwAi+gOYIy0htNkfuehGZZtP5mRXHRV6TjDWw==" + }, + "zen-observable-ts": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.9.tgz", + "integrity": "sha512-KJz2O8FxbAdAU5CSc8qZ1K2WYEJb1HxS6XDRF+hOJ1rOYcg6eTMmS9xYHCXzqZZzKw6BbXWyF4UpwSsBQnHJeA==", + "requires": { + "zen-observable": "^0.8.0" + } + } + } +} diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json new file mode 100644 index 00000000000..92937027c73 --- /dev/null +++ b/packages/upward-spec/package.json @@ -0,0 +1,37 @@ +{ + "name": "@magento/upward-spec", + "version": "0.1.0", + "description": "UPWARD specification, guide, and test suite.", + "main": "./suite/index.js", + "bin": { + "upward-spec": "./bin/upward-spec" + }, + "engines": { + "node": ">=8.0.0" + }, + "repository": "github:magento-research/pwa-studio", + "keywords": [ + "magento", + "pwa", + "specification", + "upward" + ], + "author": "Magento Commerce", + "license": "SEE LICENSE IN LICENSE.txt", + "bugs": { + "url": "https://github.com/magento-research/pwa-studio/issues" + }, + "homepage": "https://github.com/magento-research/pwa-studio/tree/master/packages/upward-spec#readme", + "dependencies": { + "apollo-server": "^2.0.5", + "chalk": "^2.4.1", + "csv-parse": "^3.0.0", + "death": "^1.1.0", + "graphql": "^0.13.2", + "graphql-tag": "^2.9.2", + "js-yaml": "^3.12.0", + "tap-diff": "^0.1.1", + "tap-xunit": "^2.3.0", + "tape": "^4.9.1" + } +} diff --git a/packages/upward-spec/suite/MockGQLService.js b/packages/upward-spec/suite/MockGQLService.js new file mode 100644 index 00000000000..e7ff6d1a97f --- /dev/null +++ b/packages/upward-spec/suite/MockGQLService.js @@ -0,0 +1,19 @@ +const { ApolloServer, gql } = require('apollo-server'); +module.exports = async function(schema, Query) { + const typeDefs = gql(schema); + const server = new ApolloServer({ + typeDefs, + resolvers: { Query } + }); + const { url } = server.listen(); + return { + url, + server, + async close() { + return new Promise(resolve => { + server.on('close', resolve); + server.close(); + }); + } + }; +}; diff --git a/packages/upward-spec/suite/assertOnResponse.js b/packages/upward-spec/suite/assertOnResponse.js new file mode 100644 index 00000000000..3de81a36007 --- /dev/null +++ b/packages/upward-spec/suite/assertOnResponse.js @@ -0,0 +1,73 @@ +const { inspect } = require('util'); + +module.exports = async (t, response, expected) => { + // lift up as useful a stack trace as possible for the most common case, + // which is a server-side error at runtime for an unsupported scenario + if (response.status >= 400 && expected.status !== response.status) { + const errorText = await response.clone().text(); + let errors; + try { + errors = JSON.parse(errorText).errors; + } catch (e) {} + if (!errors || !Array.isArray(errors) || errors.length === 0) { + return t.fail( + `Error: Expected ${inspect( + expected + )}, server responded with a NON-COMPLIANT ERROR: (Server errors should emit GraphQL-compliant error JSON.) Received status ${ + response.status + }: ${errorText}` + ); + } + return t.fail( + 'Server reported errors: ' + + errors.map(({ message }, i) => `[Error ${i + 1}: ${message}]\t`) + ); + } + + const responseHeaders = {}; + response.headers.forEach((value, name) => { + responseHeaders[name] = value; + responseHeaders[name.toLowerCase()] = value.toString(); + }); + + t.equal(response.status, expected.status, `status code ${expected.status}`); + + Object.entries(expected.headers).forEach(([header, start]) => { + const value = responseHeaders[header.toLowerCase()]; + if (!value) { + t.fail( + `header ${header} not present in ${inspect(responseHeaders)}` + ); + } else { + t.ok(value.startsWith(start), `header ${header} is ${value}`); + } + }); + try { + const body = await response.clone().text(); + if (expected.text) { + const msg = `body should match '${expected.text}': ${body}`; + if (body.includes(expected.text)) { + t.pass(msg); + } else { + t.fail(msg); + } + } + if (expected.json) { + let parsed; + try { + parsed = JSON.parse(body); + } catch (e) { + t.fail(e.message); + } + Object.entries(expected.json).forEach(([name, value]) => + t.equal( + value, + parsed[name], + `JSON ${name} === ${JSON.stringify(parsed[name])}` + ) + ); + } + } catch (e) { + t.error(e); + } +}; diff --git a/packages/upward-spec/suite/getScenarios.js b/packages/upward-spec/suite/getScenarios.js new file mode 100644 index 00000000000..dfd73633844 --- /dev/null +++ b/packages/upward-spec/suite/getScenarios.js @@ -0,0 +1,52 @@ +const { resolve } = require('path'); +const { readdir: fsReaddir, readFile: fsReadFile } = require('fs'); +const { promisify } = require('util'); +const jsYaml = require('js-yaml'); +const readdir = promisify(fsReaddir); +const readFile = promisify(fsReadFile); + +const dirsPromise = readdir(resolve(__dirname, './scenarios')); + +function getOneMatch(candidates, pattern) { + const matching = candidates.filter(candidate => pattern.test(candidate)); + if (matching.length > 1) { + throw new Error( + `${pattern.toString()} returned multiple results: ${matching.join()}` + ); + } + if (matching.length === 0) { + throw new Error(`${pattern.toString()} returned no results`); + } + return matching[0]; +} + +async function getScenarios(pattern) { + if (!pattern || typeof pattern.test !== 'function') { + throw new Error( + `UpwardSpec.getScenarios() requires a regular expression, or an object with a 'test' method` + ); + } + const baseDir = await resolve( + __dirname, + './scenarios', + getOneMatch(await dirsPromise, pattern) + ); + + function getResourcePath(name) { + return resolve(baseDir, name); + } + + function getResource(name, enc = 'utf8') { + return readFile(getResourcePath(name), enc); + } + return { + baseDir, + getResourcePath, + getResource, + async getDefinition(name) { + return jsYaml.safeLoad(await getResource(name + '.yml')); + } + }; +} + +module.exports = getScenarios; diff --git a/packages/upward-spec/suite/index.js b/packages/upward-spec/suite/index.js new file mode 100644 index 00000000000..a530c6166f4 --- /dev/null +++ b/packages/upward-spec/suite/index.js @@ -0,0 +1,6 @@ +module.exports = { + assertOnResponse: require('./assertOnResponse'), + getScenarios: require('./getScenarios'), + MockGQLService: require('./MockGQLService'), + runServer: require('./runServer') +}; diff --git a/packages/upward-spec/suite/runServer.js b/packages/upward-spec/suite/runServer.js new file mode 100644 index 00000000000..f09eb179c3b --- /dev/null +++ b/packages/upward-spec/suite/runServer.js @@ -0,0 +1,169 @@ +const path = require('path'); +const { spawn } = require('child_process'); +const { URL } = require('url'); + +const script = process.env.UPWARD_SERVER_SCRIPT_PATH; + +module.exports = async function runServer( + test, + configFile, + env, + customTimeout +) { + let terminator; + let timeout = Number(customTimeout || process.env.TAP_TIMEOUT); + if (isNaN(timeout)) { + timeout = 5; + } else { + timeout = Math.max(timeout - 1, Math.min(timeout - 1, 2)); + } + // Create a child process and resolve the Promise if: + // - the process exits (with any code) + // - the process stays alive and echoes a URL + + // Reject only if: + // - the process throws an error and cannot start + // - the process takes too long without echoing a valid URL + let server; + try { + server = await new Promise((resolve, reject) => { + let child; + const flags = { + crashed: false, + launched: false, + running: false + }; + let stderr = ''; + let url; + + function terminateClean() { + child.removeAllListeners(); + child.on('error', () => { + child.kill('SIGKILL'); + }); + return new Promise((innerResolve, innerReject) => { + child.on('close', (_, signal) => { + flags.running = false; + return signal === 'SIGKILL' + ? innerReject(signal) + : innerResolve(signal); + }); + child.kill('SIGTERM'); + }); + } + + try { + child = spawn(path.resolve(script), { + cwd: path.dirname(script), + env: Object.assign( + {}, + process.env, + { + UPWARD_PATH: configFile + }, + env + ) + }); + } catch (e) { + reject(e); + return; + } + + child.stderr.on('data', chunk => { + stderr += chunk.toString('utf8'); + }); + + if (timeout > 0) { + terminator = setTimeout(() => { + const message = `Timed out. Spawning a server with ${script} took over ${timeout} seconds.`; + terminateClean() + .then( + signal => ` Killed with ${signal}`, + signal => + `\n\nAdditionally, the process did not respond to SIGTERM, and had to be killed with ${signal}.` + ) + .then(notice => reject(new Error(message + notice))); + }, timeout * 1000); + } + + function emitServer() { + clearTimeout(terminator); + resolve({ + stderr, + url, + hasCrashed() { + return flags.crashed; + }, + hasLaunched() { + return flags.launched; + }, + isRunning() { + return flags.running; + }, + async close() { + if (flags.running) { + return terminateClean().catch(e => test.error(e)); + } + }, + assert(flag, expected = true, msg) { + const extra = msg ? `\n\n${msg}` : ''; + let message = 'server '; + if (!flags[flag]) { + message += 'not '; + } + message += flag; + if (flag === 'launched' && url) { + message += `, listening at ${url}`; + } + if (stderr) { + message += `, emitting stderr ${stderr.slice( + 0, + 50 + )}[...]`; + } + const status = + flags[flag] === expected ? 'pass' : 'fail'; + test[status](message + extra); + return status === 'pass'; + } + }); + } + + child.on('error', reject); + child.on('exit', code => { + flags.running = false; + if (code !== 0) { + flags.crashed = true; + } + emitServer(); + }); + + let outText = ''; + child.stdout.on('data', function waitingForUrl(chunk) { + const newChunk = chunk.toString('utf8'); + outText += newChunk; + if (outText.includes('\n')) { + child.stdout.removeListener('data', waitingForUrl); + try { + url = new URL(outText.trim()); + flags.launched = true; + flags.running = true; + emitServer(); + } catch (e) { + reject( + new Error( + `Could not parse first line of server stdout as a URL: ${e} ${outText}` + ) + ); + } + } + }); + }); + } catch (e) { + clearTimeout(terminator); + test.threw(e); + throw e; + } + + return server; +}; diff --git a/packages/upward-spec/suite/scenarios/001-unknown-config/only-status.yml b/packages/upward-spec/suite/scenarios/001-unknown-config/only-status.yml new file mode 100644 index 00000000000..62e205234c3 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/001-unknown-config/only-status.yml @@ -0,0 +1 @@ +status: 200 diff --git a/packages/upward-spec/suite/scenarios/001-unknown-config/tests.js b/packages/upward-spec/suite/scenarios/001-unknown-config/tests.js new file mode 100644 index 00000000000..7cb9935bc68 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/001-unknown-config/tests.js @@ -0,0 +1,31 @@ +const tape = require('tape'); + +const { getScenarios, runServer } = require('../../'); + +const gettingScenarios = getScenarios(/unknown\-config/); + +tape.test('Crashes if config file is missing', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./absolutely-no-way-this-file-exists') + ); + + server.assert('crashed'); + + await server.close(); + t.end(); +}); + +tape.test('Crashes if config file is unparseable', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./unparseable.yml') + ); + + server.assert('crashed'); + + await server.close(); + t.end(); +}); diff --git a/packages/upward-spec/suite/scenarios/001-unknown-config/unparseable.yml b/packages/upward-spec/suite/scenarios/001-unknown-config/unparseable.yml new file mode 100644 index 00000000000..d172ef309fe --- /dev/null +++ b/packages/upward-spec/suite/scenarios/001-unknown-config/unparseable.yml @@ -0,0 +1 @@ +!!!!THATasda SomE BAD yAML! diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/context-is-hello-env-is-world.mst b/packages/upward-spec/suite/scenarios/002-static-servers/context-is-hello-env-is-world.mst new file mode 100644 index 00000000000..9cd622813af --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/context-is-hello-env-is-world.mst @@ -0,0 +1 @@ +{{communique}} from a {{env.sender}} of external templates!! diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-context-inline-template-json.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-context-inline-template-json.yml new file mode 100644 index 00000000000..8f2b4c30348 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-context-inline-template-json.yml @@ -0,0 +1,15 @@ +status: 200 +headers: + inline: + content-type: application/json +body: + engine: mustache + provide: + - salutation + - addressee + template: + inline: '{"greeting":"{{ salutation }}","subject":{{>json-subject}},"shouldYouReallyHandwriteJSON":"no"}' + +salutation: + inline: 'Hello' +addressee: env.ADDRESSEE diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-context-file-template.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-context-file-template.yml new file mode 100644 index 00000000000..e866a071f1e --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-context-file-template.yml @@ -0,0 +1,23 @@ +status: + resolver: inline + inline: 200 +headers: + resolver: inline + inline: + content-type: + resolver: inline + inline: text/plain +body: + resolver: template + engine: mustache + provide: + - env + - communique + template: + resolver: file + file: + resolver: inline + inline: './context-is-hello-env-is-world.mst' +communique: + resolver: inline + inline: 'Hello' diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-inline-template.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-inline-template.yml new file mode 100644 index 00000000000..2a50b4c4026 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-inline-template.yml @@ -0,0 +1,10 @@ +status: 200 +headers: + inline: + content-type: text/plain +body: + engine: mustache + provide: + - env + template: + inline: 'Hello, environment of {{env.ADDRESSEE}}!!' diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-interpolation.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-interpolation.yml new file mode 100644 index 00000000000..859d939d030 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-env-interpolation.yml @@ -0,0 +1,5 @@ +status: 200 +headers: + inline: + content-type: text/plain +body: env.UPWARD_TEST_RESPONSE_BODY diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-file-shortcut.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-file-shortcut.yml new file mode 100644 index 00000000000..7d9a71c7bc9 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-file-shortcut.yml @@ -0,0 +1,8 @@ +status: 201 +headers: + inline: + content-type: + inline: 'text/csv' + x-is-cool-swords: + inline: 'yep' +body: './swords.csv' diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-implicit-resolvers.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-implicit-resolvers.yml new file mode 100644 index 00000000000..8a8e0acad52 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-implicit-resolvers.yml @@ -0,0 +1,6 @@ +status: 200 +headers: + inline: + content-type: text/plain +body: + inline: 'Hello World, concisely!!' diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-only.yml b/packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-only.yml new file mode 100644 index 00000000000..86468525b75 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/hello-inline-only.yml @@ -0,0 +1,12 @@ +status: + resolver: inline + inline: 200 +headers: + resolver: inline + inline: + content-type: + resolver: inline + inline: text/plain +body: + resolver: inline + inline: 'Hello World!!' diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/json-subject.tpt b/packages/upward-spec/suite/scenarios/002-static-servers/json-subject.tpt new file mode 100644 index 00000000000..41ad5524494 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/json-subject.tpt @@ -0,0 +1 @@ +"{{>renders-addressee-alone}}" diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/renders-addressee-alone.mustache b/packages/upward-spec/suite/scenarios/002-static-servers/renders-addressee-alone.mustache new file mode 100644 index 00000000000..afe4522bc35 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/renders-addressee-alone.mustache @@ -0,0 +1 @@ +the depths of {{ addressee }}... diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/swords.csv b/packages/upward-spec/suite/scenarios/002-static-servers/swords.csv new file mode 100644 index 00000000000..41cbb682e43 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/swords.csv @@ -0,0 +1,4 @@ +name,origin +claymore,scotland +jian,china +shotel,egypt diff --git a/packages/upward-spec/suite/scenarios/002-static-servers/tests.js b/packages/upward-spec/suite/scenarios/002-static-servers/tests.js new file mode 100644 index 00000000000..e46726439a3 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/002-static-servers/tests.js @@ -0,0 +1,220 @@ +const fetch = require('node-fetch'); +const tape = require('tape'); +const csvParse = require('csv-parse/lib/sync'); + +const { getScenarios, runServer, assertOnResponse } = require('../../'); + +const gettingScenarios = getScenarios(/static\-servers/); + +tape.test('Static Hello World with only inline deps', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./hello-inline-only.yml') + ); + + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'text/plain' + }, + text: 'Hello World!!' + }); + + server.assert('crashed', false); + } + + await server.close(); + t.end(); +}); + +tape.test('Static Hello World with implicit resolvers', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./hello-inline-implicit-resolvers.yml') + ); + + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'text/plain' + }, + text: 'Hello World, concisely!!' + }); + + server.assert('crashed', false); + } + + await server.close(); + t.end(); +}); + +tape.test('Static Hello World with env interpolation', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./hello-env-interpolation.yml'), + { + UPWARD_TEST_RESPONSE_BODY: 'Hello, environment!!' + } + ); + + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'text/plain' + }, + text: 'Hello, environment!!' + }); + + server.assert('crashed', false); + } + await server.close(); + t.end(); +}); + +tape.test('Static Hello World with env dep and inline template', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./hello-env-inline-template.yml'), + { + ADDRESSEE: 'Terra' + } + ); + + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'text/plain' + }, + text: 'Hello, environment of Terra!!' + }); + + server.assert('crashed', false); + } + + await server.close(); + t.end(); +}); + +tape.test( + 'Static Hello World with env, context, and file template', + async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./hello-env-context-file-template.yml'), + { + sender: 'planet' + } + ); + + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'text/plain' + }, + text: 'Hello from a planet of external templates!!' + }); + + server.assert('crashed', false); + } + + await server.close(); + t.end(); + } +); +tape.test( + 'Static JSON Hello World with template partial resolution', + async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath( + './hello-context-inline-template-json.yml' + ), + { + ADDRESSEE: 'deep space' + } + ); + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'application/json' + }, + json: { + greeting: 'Hello', + subject: 'the depths of deep space...' + } + }); + + server.assert('crashed', false); + } + + await server.close(); + t.end(); + } +); +tape.test('File shortcut resolution', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./hello-file-shortcut.yml') + ); + if (server.assert('launched')) { + const response = await fetch(server.url); + + await assertOnResponse(t, response, { + status: 201, + headers: { + 'content-type': 'text/csv', + 'x-is-cool-swords': 'yep' + } + }); + + const swordsCSV = await response.text(); + try { + const swords = csvParse(swordsCSV, { columns: true }).reduce( + (acc, { name, origin }) => ((acc[origin] = name), acc), + {} + ); + + t.deepEqual(swords, { + scotland: 'claymore', + china: 'jian', + egypt: 'shotel' + }); + } catch (e) { + t.fail( + `swords.csv is valid CSV, but server emitted ${swordsCSV}, which did not parse: ${ + e.message + }` + ); + } + + server.assert('crashed', false); + } + + await server.close(); + t.end(); +}); diff --git a/packages/upward-spec/suite/scenarios/003-request-handling/cyclic-dependencies.yml b/packages/upward-spec/suite/scenarios/003-request-handling/cyclic-dependencies.yml new file mode 100644 index 00000000000..86f6252f6fb --- /dev/null +++ b/packages/upward-spec/suite/scenarios/003-request-handling/cyclic-dependencies.yml @@ -0,0 +1,16 @@ +status: 200 +headers: + inline: + content-type: + when: + matches: + content-disposition: + when: + matches: headers.content-type + pattern: text/html + use: + inline: + inline + default: + inline: + attachment diff --git a/packages/upward-spec/suite/scenarios/003-request-handling/island-summary.mst b/packages/upward-spec/suite/scenarios/003-request-handling/island-summary.mst new file mode 100644 index 00000000000..e2e2d8b802e --- /dev/null +++ b/packages/upward-spec/suite/scenarios/003-request-handling/island-summary.mst @@ -0,0 +1,4 @@ +{{title}}, an island in the {{group}} +===================================== + +{{description}} diff --git a/packages/upward-spec/suite/scenarios/003-request-handling/reflect-request.yml b/packages/upward-spec/suite/scenarios/003-request-handling/reflect-request.yml new file mode 100644 index 00000000000..b4d9773e7d1 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/003-request-handling/reflect-request.yml @@ -0,0 +1,32 @@ +status: + resolver: inline + inline: 200 +headers: + resolver: inline + inline: + content-type: text/plain +body: + resolver: template + engine: mustache + provide: + - request + template: + resolver: inline + inline: | + {{#request}} + Headers: + {{#headerEntries}} + {{name}}: {{value}} + {{/headerEntries}} + URL: + {{#url}}{{#?protocol}}protocol: {{protocol}} + {{/?protocol}}{{#?host}}host: {{host}} + {{/?host}}{{#?hostname}}hostname: {{hostname}} + {{/?hostname}}{{#?port}}port: {{port}} + {{/?port}}pathname: {{pathname}} + {{/url}} + URL Query: + {{#queryEntries}} + {{name}}: {{value}} + {{/queryEntries}} + {{/request}} diff --git a/packages/upward-spec/suite/scenarios/003-request-handling/route-requests.yml b/packages/upward-spec/suite/scenarios/003-request-handling/route-requests.yml new file mode 100644 index 00000000000..5332023843d --- /dev/null +++ b/packages/upward-spec/suite/scenarios/003-request-handling/route-requests.yml @@ -0,0 +1,64 @@ +status: + when: + matches: island.name + pattern: '.' + use: 200 + default: 404 + +headers: + inline: + content-type: text/plain + +body: + when: + - matches: island.name + pattern: '.' + use: + engine: mustache + provide: + title: island.name + group: island.group + body: island.description + template: ./island-summary + default: notFound + +island: islandResult.data.islands:first + +islandResult: + when: + - matches: request.url.pathname + pattern: '^\/inmost-sea/([A-Za-z\-]+\/?$' + use: + url: env.EARTHSEA_API + query: './getIslands' + variables: + group: + inline: Inmost Sea + nameNormalized: $match.$1 + + - matches: request.url.pathname + pattern: '^\/north-reach/([A-Za-z\-]+\/?$' + use: + url: env.EARTHSEA_API + query: './getIslands' + variables: + group: + inline: North Reach + nameNormalized: $match.$1 + + - matches: request.url.pathname + pattern: '^\/kargad-lands/([A-Za-z\-]+\/?$' + use: + url: env.EARTHSEA_API + query: './getIslands' + variables: + group: + inline: Kargad Lands + nameNormalized: $match.$1 + + default: + inline: '' + +notFound: + inline: | + No such island exists here. diff --git a/packages/upward-spec/suite/scenarios/003-request-handling/tests.js b/packages/upward-spec/suite/scenarios/003-request-handling/tests.js new file mode 100644 index 00000000000..5ac57786863 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/003-request-handling/tests.js @@ -0,0 +1,34 @@ +const { URL } = require('url'); +const fetch = require('node-fetch'); +const tape = require('tape'); + +const { getScenarios, runServer, assertOnResponse } = require('../../'); + +const gettingScenarios = getScenarios(/request\-handling/); + +tape.test('Reflect request', async t => { + const scenarios = await gettingScenarios; + const server = await runServer( + t, + scenarios.getResourcePath('./reflect-request.yml') + ); + + if (server.assert('launched')) { + const response = await fetch( + new URL('/some/path?query=parameters', server.url) + ); + + await assertOnResponse(t, response, { + status: 200, + headers: { + 'content-type': 'text/plain' + }, + text: 'some/path' + }); + + server.assert('crashed', false); + } + + await server.close(); + t.end(); +}); diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors-schema.graphql b/packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors-schema.graphql new file mode 100644 index 00000000000..4f67b49cbd2 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors-schema.graphql @@ -0,0 +1,18 @@ +type Author { + id: Int + name: String + bio: String +} +type Article { + id: Int + title: String + text: String + author: Author +} +type Query { + author(id: Int): Author + article(id: ): Article +} +schema { + query: Query +} diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors.yml b/packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors.yml new file mode 100644 index 00000000000..5dd064b3029 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/articles-and-authors.yml @@ -0,0 +1,65 @@ +status: page.status +headers: page.headers +body: page.body + +articleResult: + url: env.LIBRARY_SVC + query: './getArticle.graphql' + variables: + articleId: request.url.query.articleID + +authorBioResult: + url: env.LIBRARY_SVC + query: './getAuthor.graphql' + variables: + authorId: request.url.query.authorID + +textHtml: + inline: + 'content-type': 'text/html' + +notFound: + inline: + status: 404 + headers: textHtml + body: + engine: mustache + template: './notFound.mst' + +page: + when: + - matches: request.url.pathname + pattern: '/article' + use: + when: + - matches: articleResult.data.article.id + pattern: '.' + use: + inline: + title: + engine: mustache + template: 'Article {{authorBioResult.data.author.name}}' + status: 200 + headers: textHtml + body: + engine: mustache + template: './article.mst' + default: notFound + - matches: request.url.pathname + pattern: '/author' + use: + when: + - matches: authorBioResult.data.author.id + pattern: '.' + use: + inline: + title: + engine: mustache + template: 'Author {{authorBioResult.data.author.name}}' + status: 200 + headers: textHtml + body: + engine: mustache + template: './authorBio.mst' + default: notFound + default: notFound diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/footer.mst b/packages/upward-spec/suite/scenarios/005-many-resolvers/footer.mst new file mode 100644 index 00000000000..99b9cdc53ac --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/footer.mst @@ -0,0 +1 @@ +
Copyright © Current Year
diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/getArticle.graphql b/packages/upward-spec/suite/scenarios/005-many-resolvers/getArticle.graphql new file mode 100644 index 00000000000..b563ec86628 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/getArticle.graphql @@ -0,0 +1,10 @@ +{ + query getArticle($articleId: Number!) { + article(id: $articleId) { + id + title + author + body + } + } +} diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/getAuthor.graphql b/packages/upward-spec/suite/scenarios/005-many-resolvers/getAuthor.graphql new file mode 100644 index 00000000000..05776180933 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/getAuthor.graphql @@ -0,0 +1,9 @@ +{ + query getAuthor($authorId: Number!) { + author(id: $authorId) { + firstName + lastName + bio + } + } +} diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/head.mst b/packages/upward-spec/suite/scenarios/005-many-resolvers/head.mst new file mode 100644 index 00000000000..bad62a74ab4 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/head.mst @@ -0,0 +1 @@ +{{#page}}{{#title}}{{title}}{{/title}}{{^title}}404: Not Found{{/title}}{{{/page}} diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/header.mst b/packages/upward-spec/suite/scenarios/005-many-resolvers/header.mst new file mode 100644 index 00000000000..9102bf4a433 --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/header.mst @@ -0,0 +1,2 @@ +
Page Header
+{{> menu}} diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/menu.mst b/packages/upward-spec/suite/scenarios/005-many-resolvers/menu.mst new file mode 100644 index 00000000000..446ce145f0c --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/menu.mst @@ -0,0 +1 @@ +Navigation diff --git a/packages/upward-spec/suite/scenarios/005-many-resolvers/notFound.mst b/packages/upward-spec/suite/scenarios/005-many-resolvers/notFound.mst new file mode 100644 index 00000000000..fe9a0b206ab --- /dev/null +++ b/packages/upward-spec/suite/scenarios/005-many-resolvers/notFound.mst @@ -0,0 +1,9 @@ + + + {{> head}} + + {{> header}} +

404: Not Found

+ {{> footer }} + + diff --git a/packages/upward-spec/test_upward_server.sh b/packages/upward-spec/test_upward_server.sh new file mode 100644 index 00000000000..6a68e455b2a --- /dev/null +++ b/packages/upward-spec/test_upward_server.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# This simple script assumes that the server will stay in the foreground, that +# it will echo its full host (e.g. http://localhost:8919) to stdout (with a +# line feed to trigger consumption of the URL) as part of its initial logging, +# and that it will gracefully exit on receiving SIGTERM, which are good # +# habits for a web server to have anyway. + +# The `exec` ensures that the server process will receive signals sent to this +# script, such as SIGTERM, which the test harness uses to gracefully close. + +# The `grep` ensures that if more than just a URL is echoed to standard output, +# the URL be parsed out of it. + +exec ./path_to_upward_server/bin/upward --config "$UPWARD_PATH" | grep -ioE '\bhttps?://[a-z0-9][a-z0-9-\.]*\n' diff --git a/packages/upward-spec/tiered_architecture.png b/packages/upward-spec/tiered_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..5c11f3683a7685186b64ec7bd360022be2e279ea GIT binary patch literal 26508 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%0DC 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 literal 0 HcmV?d00001 diff --git a/packages/venia-concept/.babelrc b/packages/venia-concept/.babelrc index 6ca049e72f8..296006f306c 100644 --- a/packages/venia-concept/.babelrc +++ b/packages/venia-concept/.babelrc @@ -6,6 +6,7 @@ "transform-class-properties", "transform-es2015-modules-commonjs", "transform-object-rest-spread", + "import-graphql", "transform-react-jsx" ] } diff --git a/packages/venia-concept/.env.dist b/packages/venia-concept/.env.dist deleted file mode 100644 index 3bb676ad450..00000000000 --- a/packages/venia-concept/.env.dist +++ /dev/null @@ -1,14 +0,0 @@ -MAGENTO_BACKEND_DOMAIN="https://magento2.vagrant" -MAGENTO_BACKEND_PUBLIC_PATH="/pub/static/frontend/Magento/venia/en_US/" - -# Control the filename of the generated ServiceWorker. -SERVICE_WORKER_FILE_NAME="sw.js" - -# ServiceWorkers are disabled in development, to avoid stale resources. -# Set this to 1 (or any string value) to force ServiceWorkers in development. -ENABLE_SERVICE_WORKER_DEBUGGING= - -# TODO: This env var can override the hardcoded product media path, which we -# need to hardcode due to https://github.com/magento/graphql-ce/issues/88 -# By default it is /media/ -# MAGENTO_BACKEND_PRODUCT_MEDIA_PATH=/media/catalog/product/ diff --git a/packages/venia-concept/CHANGELOG.md b/packages/venia-concept/CHANGELOG.md new file mode 100644 index 00000000000..8d1d3dc5adb --- /dev/null +++ b/packages/venia-concept/CHANGELOG.md @@ -0,0 +1,26 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +# 0.2.0 (2018-08-13) + + +### Bug Fixes + +* **dev:** MagentoRootComponentsPlugin dedupe fix ([bb8b152](https://github.com/magento-research/pwa-studio/commit/bb8b152)) +* **dev:** merge 'assets' and 'output' paths ([36d8157](https://github.com/magento-research/pwa-studio/commit/36d8157)) +* **dev:** optimize uglify output ([e7dca7e](https://github.com/magento-research/pwa-studio/commit/e7dca7e)) +* **perf:** Optimize logo.svg ([0a1fb6a](https://github.com/magento-research/pwa-studio/commit/0a1fb6a)) +* **routing:** use Link component ([d4004bc](https://github.com/magento-research/pwa-studio/commit/d4004bc)) + + +### Features + +* multicasting REST API client ([#164](https://github.com/magento-research/pwa-studio/issues/164)) ([2852e14](https://github.com/magento-research/pwa-studio/commit/2852e14)), closes [#140](https://github.com/magento-research/pwa-studio/issues/140) +* **checkout:** Enable order submission ([#173](https://github.com/magento-research/pwa-studio/issues/173)) ([666327e](https://github.com/magento-research/pwa-studio/commit/666327e)) +* **checkout:** Integrate live product, cart, checkout ([#140](https://github.com/magento-research/pwa-studio/issues/140)) ([1f60e87](https://github.com/magento-research/pwa-studio/commit/1f60e87)) +* **data:** Add live GraphQL data to product detail page ([#90](https://github.com/magento-research/pwa-studio/issues/90)) ([77b6bd6](https://github.com/magento-research/pwa-studio/commit/77b6bd6)), closes [#52](https://github.com/magento-research/pwa-studio/issues/52) [#87](https://github.com/magento-research/pwa-studio/issues/87) +* **dev:** app shell detects env from proxy header ([ac5b0b0](https://github.com/magento-research/pwa-studio/commit/ac5b0b0)) +* **dev:** log dev URL prominently after build ([#114](https://github.com/magento-research/pwa-studio/issues/114)) ([84fadde](https://github.com/magento-research/pwa-studio/commit/84fadde)), closes [#4](https://github.com/magento-research/pwa-studio/issues/4) diff --git a/packages/venia-concept/Magento_Theme/templates/root.phtml b/packages/venia-concept/Magento_Theme/templates/root.phtml deleted file mode 100644 index 802897e0ab2..00000000000 --- a/packages/venia-concept/Magento_Theme/templates/root.phtml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Venia - - - - -

- - - diff --git a/packages/venia-concept/babel.config.js b/packages/venia-concept/babel.config.js index 53883be8c3b..795b2d65050 100644 --- a/packages/venia-concept/babel.config.js +++ b/packages/venia-concept/babel.config.js @@ -8,7 +8,8 @@ const plugins = [ 'transform-class-properties', 'transform-object-rest-spread', ['transform-react-jsx'], - 'graphql-tag' + 'graphql-tag', + 'import-graphql' ]; // define default babel options diff --git a/packages/venia-concept/composer.json b/packages/venia-concept/composer.json deleted file mode 100644 index 32bbe464967..00000000000 --- a/packages/venia-concept/composer.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "magento/theme-frontend-venia", - "description": "Venia PWA Concept Theme for Magento 2", - "require": { - "php": "~7.1.3||~7.2.0", - "magento-research/theme-frontend-pwa": "*" - }, - "type": "magento2-theme", - "license": ["OSL-3.0", "AFL-3.0"], - "autoload": { - "files": ["registration.php"] - } -} diff --git a/packages/venia-concept/etc/view.xml b/packages/venia-concept/etc/view.xml deleted file mode 100644 index 8900c34abe0..00000000000 --- a/packages/venia-concept/etc/view.xml +++ /dev/null @@ -1,314 +0,0 @@ - - - - - - - 140 - 140 - - - - 152 - 188 - - - 110 - 160 - - - 240 - 300 - - - 240 - 300 - - - 100 - 100 - - - 285 - 285 - - - 113 - 113 - - - 75 - 75 - - - 100 - 100 - - - 78 - 78 - - - 240 - 300 - - - 270 - 270 - - - 78 - 78 - - - 265 - 265 - - - 140 - 140 - - - - false - - - 700 - 700 - - - 700 - 700 - false - - - 90 - 90 - - - 700 - 700 - - - 700 - 700 - - - 90 - 90 - - - 76 - 76 - - - 135 - 135 - - - 75 - 75 - - - 240 - 300 - - - 75 - 90 - - - 76 - 76 - - - 270 - 207 - - - 240 - 300 - - - 75 - 90 - - - 76 - 76 - - - 270 - 270 - - - 140 - 140 - - - 285 - 285 - - - 75 - 75 - - - 75 - 75 - - - 135 - 135 - - - 75 - 90 - - - 140 - 140 - - - 75 - 90 - - - 113 - 113 - - - 240 - 300 - - - - - - - - thumbs - true - true - true - false - true - horizontal - true - slides - - slide - 500 - - - thumbs - true - false - false - horizontal - slides - - dissolve - 500 - - - - - - 20 - - - - - hover - false - - - - - - 767px - - - - dots - - - - - - - 100 - 275 - 48 - - 166 - 370 - - 0 - - - 58 - - - 1MB - - - sw.js - - - Lib::jquery/jquery.min.js - Lib::jquery/jquery-ui-1.9.2.js - Lib::jquery/jquery.ba-hashchange.min.js - Lib::jquery/jquery.details.js - Lib::jquery/jquery.details.min.js - Lib::jquery/jquery.hoverIntent.js - Lib::jquery/colorpicker/js/colorpicker.js - Lib::requirejs/require.js - Lib::requirejs/text.js - Lib::date-format-normalizer.js - Lib::legacy-build.min.js - Lib::mage/captcha.js - Lib::mage/dropdown_old.js - Lib::mage/list.js - Lib::mage/loader_old.js - Lib::mage/webapi.js - Lib::mage/zoom.js - Lib::mage/translate-inline-vde.js - Lib::mage/requirejs/mixins.js - Lib::mage/requirejs/static.js - Magento_Customer::js/zxcvbn.js - Magento_Catalog::js/zoom.js - Magento_Ui::js/lib/step-wizard.js - Magento_Ui::js/form/element/ui-select.js - Magento_Ui::js/form/element/file-uploader.js - Magento_Ui::js/form/components/insert.js - Magento_Ui::js/form/components/insert-listing.js - Magento_Ui::js/timeline - Magento_Ui::js/grid - Magento_Ui::js/dynamic-rows - Magento_Ui::templates/timeline - Magento_Ui::templates/grid - Magento_Ui::templates/dynamic-rows - Magento_Swagger::swagger-ui - Lib::modernizr - Lib::tiny_mce - Lib::varien - Lib::jquery/editableMultiselect - Lib::jquery/jstree - Lib::jquery/fileUploader - Lib::css - Lib::lib - Lib::extjs - Lib::prototype - Lib::scriptaculous - Lib::less - Lib::mage/adminhtml - Lib::mage/backend - - diff --git a/packages/venia-concept/example.env b/packages/venia-concept/example.env new file mode 100644 index 00000000000..f1a86a796b3 --- /dev/null +++ b/packages/venia-concept/example.env @@ -0,0 +1,73 @@ +########## example.env ######################################################## +# +# This file is an example of how to configure Magento PWA Studio at +# development time and runtime. Use these environment variables for any +# settings which will change between your production, development, and +# testing environments. +# +# Copy this file to a file in the `venia-concept` directory called `.env` +# to activate your project. If a `.env` file is missing, or required +# variables are missing in your `.env` file, you should be notified. +# +############################################################################### + +########## Connecting to a Magento store ###################################### +# +# Connect to an instance of Magento 2.3 by specifying its public +# domain name. **REQUIRED.** Example: +# MAGENTO_BACKEND_DOMAIN="https://magento2.local" +# +# Use a particular website code when making API calls. Defaults to 'base', +# but for your PWA to act as a different "website" in the Magento admin, +# you can change this variable. Example: +# MAGENTO_WEBSITE_CODE="foo" +# +# TODO: This env var can override the hardcoded product media path, which we +# need to hardcode due to https://github.com/magento/graphql-ce/issues/88 +# REQUIRED, and automatically set here: +MAGENTO_BACKEND_PRODUCT_MEDIA_PATH="/media/catalog/product" +# DO NOT CHANGE THIS VALUE unless you have a custom static setup. +# +# These legacy environment variables from 1.x are no longer necessary: +# - `MAGENTO_BACKEND_PUBLIC_PATH`: Since PWA Studio no longer makes _themes_, +# it is no longer necessary to follow theme directory structure. +# - `SERVICE_WORKER_FILE_NAME`: The `sw.js` filename is suitable for almost +# all cases, and it does not vary by environment, so it should not be +# an environment variable. It has been hardcoded into package.json config. +# +############################################################################### + +########## UPWARD server production configuration ############################# +# +# The current PWA Studio production server is built with NodeJS; it is an +# implementation of the UPWARD spec, and is theoretically swappable with +# any other UPWARD-compliant server, with minimal configuration or code +# changes. Since `upward-js` is the current default implementation, the +# following environment variables configure `upward-js` specifically. +# +# Give the server the location of the UPWARD YAML configuration file which +# specifies its behavior. **REQUIRED**. For Venia, this is automatically set: +UPWARD_JS_UPWARD_PATH=venia-upward.yml +# +# Tell the upward-js server to bind to a local address and port on launch. +# Default 1 (true). **REQUIRED** unless you have a custom production setup. +UPWARD_JS_BIND_LOCAL=1 +# +# Tell the upward-js prod server to log the bound URL to stdout. Useful in +# testing and discovery scenarios, but may be disabled in production. +UPWARD_JS_LOG_URL=1 +# +# Specify a port the upward-js prod-server will bind to. If unspecified, an +# open port will be found. +# UPWARD_JS_PORT=8008 +# +############################################################################### + +########## webpack-dev-server development configuration ###################### +# +# Set variables for webpack-dev-server for editing and debugging scenarios. +# +# Set this to 1 (true) to force ServiceWorkers in development. +# ENABLE_SERVICE_WORKER_DEBUGGING=1 +# +############################################################################### diff --git a/packages/venia-concept/media/favicon.ico b/packages/venia-concept/media/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fd57e1d1a9e519dd9688ea82c31fe0d4bde78b91 GIT binary patch literal 15086 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 A0RR91 literal 0 HcmV?d00001 diff --git a/packages/venia-concept/media/preview.jpg b/packages/venia-concept/media/preview.jpg deleted file mode 100644 index ab50e6281e701758e2da3a5d4480287439b32f3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71727 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 diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index dd8d0880209..d7ecf32d61d 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -1,7 +1,7 @@ { - "name": "theme-frontend-venia", - "version": "2.0.0-rc.1", - "description": "Venia PWA Concept Theme for Magento 2", + "name": "@magento/venia-concept", + "version": "2.0.0-rc.2", + "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", "author": "Magento Commerce", "main": "src/index.js", @@ -9,19 +9,23 @@ "bugs": { "url": "https://github.com/magento-research/pwa-studio/issues" }, + "config": { + "serviceWorkerFileName": "sw.js" + }, "homepage": "https://github.com/magento-research/pwa-studio/tree/master/packages/venia-concept#readme", "scripts": { "build": "webpack --color --env.phase production", "clean": "rimraf web/js", "prepare": "npm-merge-driver install", - "start": "webpack-dev-server --progress --color --env.phase development", + "start": "node server.js", "start:debug": "node --inspect-brk ./node_modules/.bin/webpack-dev-server --progress --color --env.phase development", "validate-queries": "node ./validate-queries.js", - "watch": "npm run -s start" + "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { "@magento/peregrine": "^2.0.0-rc.1", "@magento/pwa-buildpack": "^2.0.0-rc.1", + "@magento/upward-js": "*", "npm-merge-driver": "^2.3.5", "rimraf": "^2.6.2", "webpack": "3.11.0", diff --git a/packages/venia-concept/registration.php b/packages/venia-concept/registration.php deleted file mode 100644 index 98fefc762f9..00000000000 --- a/packages/venia-concept/registration.php +++ /dev/null @@ -1,13 +0,0 @@ - 0) { + console.warn('No custom host provided.'); + } + if (makeCerts.length > 0) { + console.warn('No SSL certificate provided.'); + } + } else { + const { hostname, certPair } = await setupDomain('magento-venia', { + unique: false + }); + config.host = hostname; + config.https = certPair; + } + } + + await createUpwardServer(config); + console.log('\nStaging server running at the address above.\n'); +} + +console.log('Launching staging server...\n'); +serve(); diff --git a/packages/venia-concept/src/RootComponents/Category/category.js b/packages/venia-concept/src/RootComponents/Category/category.js index 3767f6f2655..8aff0206b2e 100644 --- a/packages/venia-concept/src/RootComponents/Category/category.js +++ b/packages/venia-concept/src/RootComponents/Category/category.js @@ -29,6 +29,7 @@ const categoryQuery = gql` } } } + url_key } } } @@ -56,7 +57,7 @@ class Category extends Component { return ( - + {({ loading, error, data }) => { if (error) return

Data Fetch Error
; if (loading) return
Fetching Data
; diff --git a/packages/venia-concept/src/RootComponents/Product/Product.js b/packages/venia-concept/src/RootComponents/Product/Product.js index ac4a08054a0..ce55db5fbc7 100644 --- a/packages/venia-concept/src/RootComponents/Product/Product.js +++ b/packages/venia-concept/src/RootComponents/Product/Product.js @@ -1,13 +1,13 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { Query } from 'react-apollo'; -import gql from 'graphql-tag'; import { bool, shape, number, arrayOf, string } from 'prop-types'; import { addItemToCart } from 'src/actions/cart'; import Page from 'src/components/Page'; import ProductFullDetail from 'src/components/ProductFullDetail'; import getUrlKey from 'src/util/getUrlKey'; +import getProductDetail from '../../queries/getProductDetail.graphql'; /** * As of this writing, there is no single Product query type in the M2.3 schema. @@ -16,32 +16,6 @@ import getUrlKey from 'src/util/getUrlKey'; * https://github.com/magento/graphql-ce/issues/86 * TODO: Replace with a single product query when possible. */ -const productDetailQuery = gql` - query productDetail($urlKey: String) { - productDetail: products(filter: { url_key: { eq: $urlKey } }) { - items { - sku - name - price { - regularPrice { - amount { - currency - value - } - } - } - description - media_gallery_entries { - label - position - disabled - file - } - } - } - } -`; - class Product extends Component { static propTypes = { data: shape({ @@ -87,8 +61,8 @@ class Product extends Component { return ( {({ loading, error, data }) => { if (error) return
Data Fetch Error
; diff --git a/packages/venia-concept/src/components/CreateAccount/__tests__/createAccount.spec.js b/packages/venia-concept/src/components/CreateAccount/__tests__/createAccount.spec.js index 006b317e571..06dfc297dd5 100644 --- a/packages/venia-concept/src/components/CreateAccount/__tests__/createAccount.spec.js +++ b/packages/venia-concept/src/components/CreateAccount/__tests__/createAccount.spec.js @@ -96,10 +96,7 @@ test('calls `onCreateAccount` when create account button is pressed', () => { const createAccountSpy = jest.fn(); const wrapper = mount( shallow( - + ).get(0) ); wrapper.setState(state); diff --git a/packages/venia-concept/src/components/Gallery/__tests__/item.spec.js b/packages/venia-concept/src/components/Gallery/__tests__/item.spec.js index 12c9bd48969..e92dd0bb383 100644 --- a/packages/venia-concept/src/components/Gallery/__tests__/item.spec.js +++ b/packages/venia-concept/src/components/Gallery/__tests__/item.spec.js @@ -25,7 +25,9 @@ const classes = { const validItem = { id: 1, name: 'Test Product', - small_image: '/foo/bar/pic.png', + small_image: { + path: '/foo/bar/pic.png' + }, url_key: 'strive-shoulder-pack', price: { regularPrice: { diff --git a/packages/venia-concept/src/queries/getProductDetail.graphql b/packages/venia-concept/src/queries/getProductDetail.graphql new file mode 100644 index 00000000000..f488d8a5b9f --- /dev/null +++ b/packages/venia-concept/src/queries/getProductDetail.graphql @@ -0,0 +1,26 @@ +query productDetail($urlKey: String, $onServer: Boolean!) { + productDetail: products(filter: { url_key: { eq: $urlKey } }) { + items { + sku + name + price { + regularPrice { + amount { + currency + value + } + } + } + description + media_gallery_entries { + label + position + disabled + file + } + meta_title @include(if: $onServer) + meta_keyword @include(if: $onServer) + meta_description @include(if: $onServer) + } + } +} diff --git a/packages/venia-concept/src/queries/urlResolver.graphql b/packages/venia-concept/src/queries/urlResolver.graphql new file mode 100644 index 00000000000..3b63d71c7dd --- /dev/null +++ b/packages/venia-concept/src/queries/urlResolver.graphql @@ -0,0 +1,6 @@ +query resolveUrl($urlKey: String!) { + urlResolver(url: $urlKey) { + type + id + } +} diff --git a/packages/venia-concept/templates/doctype-and-head-start.mst b/packages/venia-concept/templates/doctype-and-head-start.mst new file mode 100644 index 00000000000..efa899076b0 --- /dev/null +++ b/packages/venia-concept/templates/doctype-and-head-start.mst @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/venia-concept/templates/generic-shell.mst b/packages/venia-concept/templates/generic-shell.mst new file mode 100644 index 00000000000..c08e1436384 --- /dev/null +++ b/packages/venia-concept/templates/generic-shell.mst @@ -0,0 +1,12 @@ +{{> templates/doctype-and-head-start}} + Venia + + +
{{#urlResolver}} + {{#type}}Loading {{type}}{{/type}} + {{^type}}Not found!{{/type}} + {{/urlResolver}}
+{{> templates/preloads}} +{{> templates/scripts}} + + diff --git a/packages/venia-concept/templates/notfound-shell.mst b/packages/venia-concept/templates/notfound-shell.mst new file mode 100644 index 00000000000..a960933e380 --- /dev/null +++ b/packages/venia-concept/templates/notfound-shell.mst @@ -0,0 +1,11 @@ +{{> templates/doctype-and-head-start}} + Venia - Not Found + + +
+

Not found!

+
+{{> templates/preloads}} +{{> templates/scripts}} + + diff --git a/packages/venia-concept/templates/preloads.mst b/packages/venia-concept/templates/preloads.mst new file mode 100644 index 00000000000..83de0d1adf1 --- /dev/null +++ b/packages/venia-concept/templates/preloads.mst @@ -0,0 +1,3 @@ +{{#urlResolver}} + +{{/urlResolver}} diff --git a/packages/venia-concept/templates/product-shell.mst b/packages/venia-concept/templates/product-shell.mst new file mode 100644 index 00000000000..c467bffd955 --- /dev/null +++ b/packages/venia-concept/templates/product-shell.mst @@ -0,0 +1,17 @@ +{{> templates/doctype-and-head-start}} + {{model.name}} - {{site.name}} + {{#model}} + + + + + +
+ Loading {{name}}... +
+ {{/model}} +{{> templates/preloads}} +{{> templates/scripts}} + + + diff --git a/packages/venia-concept/templates/scripts.mst b/packages/venia-concept/templates/scripts.mst new file mode 100644 index 00000000000..ba17ecf7ee1 --- /dev/null +++ b/packages/venia-concept/templates/scripts.mst @@ -0,0 +1,2 @@ +{{^isDevelopment}}{{/isDevelopment}} + diff --git a/packages/venia-concept/theme.xml b/packages/venia-concept/theme.xml deleted file mode 100644 index 54ce08ba1e4..00000000000 --- a/packages/venia-concept/theme.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - Magento Venia - Magento/pwa - - media/preview.jpg - - diff --git a/packages/venia-concept/venia-upward.yml b/packages/venia-concept/venia-upward.yml new file mode 100644 index 00000000000..ae6ef1abcc5 --- /dev/null +++ b/packages/venia-concept/venia-upward.yml @@ -0,0 +1,124 @@ +status: response.status +headers: response.headers +body: response.body + +response: + when: + - matches: request.url.pathname + pattern: '^/(graphql|rest|media/)' + use: proxy + - matches: request.url.pathname + pattern: '^/favicon.ico' + use: favicon + - matches: urlKey + pattern: '.' + use: appShell + - matches: request.url.pathname + pattern: '^/$' + use: appShell + default: static + +proxy: + target: env.MAGENTO_BACKEND_DOMAIN + ignoreSSLErrors: + inline: true + +appShell: + inline: + status: + when: + - matches: resource.model + pattern: '.' + use: 200 + default: 404 + headers: + inline: + content-type: 'text/html' + body: + engine: mustache + template: resource.template + provide: + model: resource.model + isDevelopment: + when: + - matches: env.NODE_ENV + pattern: 'development' + use: + inline: true + default: + inline: false + urlResolver: urlResolver + +resource: + when: + - matches: urlResolver.type + pattern: 'PRODUCT' + use: + inline: + model: product + template: './templates/product-shell.mst' + - matches: urlResolver.type + pattern: '.' + use: + inline: + model: genericObject + template: './templates/generic-shell.mst' + default: + inline: + template: './templates/notfound-shell.mst' + +urlResolver: urlResolverResult.data.urlResolver + +urlResolverResult: + url: magentoGQL + query: './src/queries/urlResolver.graphql' + variables: + inline: + urlKey: request.url.pathname + +magentoGQL: + engine: mustache + template: + inline: '{{env.MAGENTO_BACKEND_DOMAIN}}graphql' + provide: + - env + +product: productResult.data.productDetail.items.0 +productResult: + url: magentoGQL + query: './src/queries/getProductDetail.graphql' + variables: + inline: + onServer: + inline: true + urlKey: urlKey + +urlKey: + when: + - matches: request.url.pathname + pattern: '^/(?:(.*)\.html)?' + use: $match.$1 + default: + inline: '' + +genericObject: + inline: + name: + inline: + "Hello world!" + +favicon: + inline: + status: 200 + headers: + inline: + content-type: + inline: image/vnd.microsoft.icon + body: + file: + inline: ./media/favicon.ico + encoding: binary + +static: + directory: + inline: './dist' diff --git a/packages/venia-concept/webpack.config.js b/packages/venia-concept/webpack.config.js index 5abae1ef013..c094748b134 100644 --- a/packages/venia-concept/webpack.config.js +++ b/packages/venia-concept/webpack.config.js @@ -7,17 +7,19 @@ const { ServiceWorkerPlugin, DevServerReadyNotifierPlugin, MagentoResolver, + UpwardPlugin, PWADevServer } } = require('@magento/pwa-buildpack'); const path = require('path'); +const pkg = require(path.resolve(__dirname, 'package.json')); const UglifyPlugin = require('uglifyjs-webpack-plugin'); const configureBabel = require('./babel.config.js'); const themePaths = { src: path.resolve(__dirname, 'src'), - output: path.resolve(__dirname, 'web') + output: path.resolve(__dirname, 'dist') }; // mark dependencies for vendor bundle @@ -35,10 +37,12 @@ module.exports = async function(env) { const babelOptions = configureBabel(phase); - const enableServiceWorkerDebugging = Boolean( - process.env.ENABLE_SERVICE_WORKER_DEBUGGING - ); - const serviceWorkerFileName = process.env.SERVICE_WORKER_FILE_NAME; + const enableServiceWorkerDebugging = + Number(process.env.ENABLE_SERVICE_WORKER_DEBUGGING) === 1; + + const serviceWorkerFileName = + process.env.SERVICE_WORKER_FILE_NAME || + pkg.config.serviceWorkerFileName; const config = { context: __dirname, // Node global for the running script's directory @@ -47,7 +51,7 @@ module.exports = async function(env) { }, output: { path: themePaths.output, - publicPath: process.env.MAGENTO_BACKEND_PUBLIC_PATH, + publicPath: '/', filename: 'js/[name].js', chunkFilename: 'js/[name]-[chunkhash].js', pathinfo: true @@ -130,12 +134,12 @@ module.exports = async function(env) { config.devtool = 'eval-source-map'; config.devServer = await PWADevServer.configure({ + publicPath: config.output.publicPath, serviceWorkerFileName, - publicPath: process.env.MAGENTO_BACKEND_PUBLIC_PATH, backendDomain: process.env.MAGENTO_BACKEND_DOMAIN, paths: themePaths, - provideSSLCert: true, - id: 'magento-venia' + id: 'magento-venia', + provideSSLCert: true }); // A DevServer generates its own unique output path at startup. It needs @@ -147,7 +151,11 @@ module.exports = async function(env) { new webpack.NamedChunksPlugin(), new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), - new DevServerReadyNotifierPlugin(config.devServer) + new DevServerReadyNotifierPlugin(config.devServer), + new UpwardPlugin( + config.devServer, + path.resolve(__dirname, 'venia-upward.yml') + ) ); } else if (phase === 'production') { config.performance = { @@ -162,6 +170,16 @@ module.exports = async function(env) { parallel: true, uglifyOptions: { ecma: 8, + parse: { + ecma: 8 + }, + compress: { + ecma: 6 + }, + output: { + ecma: 7, + semicolons: false + }, keep_fnames: true } }) From 011153722392e91921c2283defecdc19e65cb648 Mon Sep 17 00:00:00 2001 From: zetlen Date: Thu, 4 Oct 2018 09:20:48 -0500 Subject: [PATCH 03/22] v2.0.0-rc.2 --- lerna.json | 2 +- packages/peregrine/package.json | 2 +- packages/pwa-buildpack/package.json | 2 +- packages/pwa-devdocs/package.json | 2 +- packages/upward-js/package.json | 4 ++-- packages/upward-spec/package.json | 2 +- packages/venia-concept/package.json | 6 +++--- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lerna.json b/lerna.json index 5597efdfd18..c2719766c32 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.0-rc.1", + "version": "2.0.0-rc.2", "packages": [ "packages/peregrine", "packages/pwa-buildpack", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index 44c0b9eab1e..b130e00acfb 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -1,6 +1,6 @@ { "name": "@magento/peregrine", - "version": "2.0.0-rc.1", + "version": "2.0.0-rc.2", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index 6d4f651e279..1b7ac48ab0f 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -1,6 +1,6 @@ { "name": "@magento/pwa-buildpack", - "version": "2.0.0-rc.1", + "version": "2.0.0-rc.2", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-devdocs/package.json b/packages/pwa-devdocs/package.json index 2b0df5b27e6..d96db4e45d7 100644 --- a/packages/pwa-devdocs/package.json +++ b/packages/pwa-devdocs/package.json @@ -1,7 +1,7 @@ { "name": "pwa-devdocs", "private": true, - "version": "2.0.0-rc.1", + "version": "2.0.0-rc.2", "description": "A documentation site for Magento PWA", "main": "gulpfile.js", "dependencies": { diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index c5042b6de17..16e1abd7198 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-js", - "version": "0.1.0", + "version": "2.0.0-rc.2", "description": "Implementation of the UPWARD spec as a NodeJS server", "main": "./lib/index.js", "bin": { @@ -49,7 +49,7 @@ "traverse": "^0.6.6" }, "devDependencies": { - "@magento/upward-spec": "*", + "@magento/upward-spec": "^2.0.0-rc.2", "express": "^4.16.3", "jest": "^23.5.0", "supertest": "^3.1.0" diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json index 92937027c73..738ee80c11f 100644 --- a/packages/upward-spec/package.json +++ b/packages/upward-spec/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-spec", - "version": "0.1.0", + "version": "2.0.0-rc.2", "description": "UPWARD specification, guide, and test suite.", "main": "./suite/index.js", "bin": { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index d7ecf32d61d..83aed6605df 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -23,9 +23,9 @@ "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { - "@magento/peregrine": "^2.0.0-rc.1", - "@magento/pwa-buildpack": "^2.0.0-rc.1", - "@magento/upward-js": "*", + "@magento/peregrine": "^2.0.0-rc.2", + "@magento/pwa-buildpack": "^2.0.0-rc.2", + "@magento/upward-js": "^2.0.0-rc.2", "npm-merge-driver": "^2.3.5", "rimraf": "^2.6.2", "webpack": "3.11.0", From 26fc377ead5720f3280d3d1ecab4cd402c748364 Mon Sep 17 00:00:00 2001 From: zetlen Date: Thu, 4 Oct 2018 10:02:59 -0500 Subject: [PATCH 04/22] feat: UPWARD_MAGENTO documentation --- packages/upward-spec/UPWARD_MAGENTO.md | 77 ++++++++++++++++++ .../looser_coupling_and_similar_envs.png | Bin 0 -> 69748 bytes packages/upward-spec/many_to_one_ci.png | Bin 0 -> 80291 bytes packages/upward-spec/tight_coupling.png | Bin 0 -> 103384 bytes 4 files changed, 77 insertions(+) create mode 100644 packages/upward-spec/looser_coupling_and_similar_envs.png create mode 100644 packages/upward-spec/many_to_one_ci.png create mode 100644 packages/upward-spec/tight_coupling.png diff --git a/packages/upward-spec/UPWARD_MAGENTO.md b/packages/upward-spec/UPWARD_MAGENTO.md index 1cb2b36fd29..fc018a9af4b 100644 --- a/packages/upward-spec/UPWARD_MAGENTO.md +++ b/packages/upward-spec/UPWARD_MAGENTO.md @@ -1,3 +1,80 @@ # Why UPWARD for Magento PWA Studio Magento PWA Studio is meant to be cheap and easy to run; it should not be tied to a specific tech stack. A middle tier server is necessary to decouple PWA Studio from the Magento Theme resolution tier, which requires two-way binding in the filesystem. UPWARD allows us to require this middle tier without requiring a specific tech stack. + +## PWA Studio 1.0 and the Theme Architecture + +The initial architecture for PWA Studio fit the project files for the JavaScript application, both the view components and the build tooling, into the structure of a Magento Theme. This was chosen for several reasons: + +- Existing concepts easier to understand +- Might use today's extensions +- Built-in server side rendering +- Gives power to business users +- Scales up to enterprise and down to SMB + +However, big problems soon emerged with this approach. The main theme was that the coupling between PWA Studio and an instance of Magento was too tight. Problems included: + +- Difficulty connecting the instance of PWA Studio's theme with an instance of Magento in development +- Difficulty configuring Magento correctly to serve static files, and synchronizing that configuration with PWA Studio +- Discovery of how to precisely configure Magento to render the application shell +- The fundamental one-to-one binding of a Magento store and a Magento theme, preventing multicast +- Server-side rendering strategy that either led to bad SEO or required re-implementation of app shell UI + +Perhaps most significantly, there was a great disparity between the structures of the development and production environments. This violation of 12-factor principles meant that any deploy pipeline would be brittle and prone to unexpected failure. + +![Illustration of the tight coupling](tight_coupling.png) + +It became clear that a middle tier was necessary to separate Magento PWAs from Magento's existing rendering system, so that the only relationship between the two would be formal API contracts. Several options presented themselves. + +### Option 1: Use a NodeJS Server in Production + +Since the development server is a NodeJS process, we could recommend that production deployments use a NodeJS middle tier as well. + +| Advantages | Disadvantages | +| ---------- | ------------- | +| Similar to development environment | Dissimilar to other Magento production environments +| Fast, proven, and exciting to community | Different process model requires special ops knowledge +| Compatible with move towards distributed architecture | Incompatible with one of the missions of PWA Studio, to give lower-resource merchants and devs access to its features +| Server-side rendering | Isomorphic (server-and-client) React is harder to write and harder to bundle well for PWA + +The final decision came down to our reluctance to require the Magento ops and dev communities to master another advanced skill on top of all the others Magento 2 requires: the management of NodeJS process pools in production. + +### Option 2: Use a PHP Script or Magento Module in Development + +A custom PHP script, or an actual Magento module, would be easy to set up for the vast majority of today's full stack Magento 2 developers. However, it's a less traditional working style for NodeJS devs, and the tooling might be incompatible. + +| Advantages | Disadvantages | +| ---------- | ------------- | +| Familiarity in Magento community | Unfamiliar in greater frontend community | +| Compatible with Cloud | Requires extra PHP setup for many developers | +| Allows for monolithic, single-store deployments to use a PWA | Does not encourage service-oriented architecture | +| Closer to production environment | Incompatible with frontend best practices and tools | + +Ultimately, maintaining both NodeJS and PHP in the correct versions for a development environment seemed to be an obstacle to inviting new frontend developers into the Magento ecosystem. + +## PWA Studio 2.0 and the UPWARD architecture + +UPWARD aims to collect the advantages of the above approaches. It allows for different programming languages and technology stacks in development and production, but it maintains consistency by requiring that the frontend server be UPWARD-compliant and derive its behavior from a file contained in the PWA project. Development and production are more similar as a result. + +![Looser coupling and more similar envs](looser_coupling_and_similar_envs.png) + +UPWARD includes advantages from both prior options: + +- Supports NodeJS-based middle tier production deployment +- Supports all-PHP distributed architecture if necessary +- Supports monolithic Magento production deployment (pending an UPWARD implementation as an M2 module) +- Supports standard developer tooling with minimal dependencies +- Supports server-side rendering with template language extensibility + +In addition, UPWARD provides the following interesting perks: + +- In an excellent example of dependency inversion, PWA frontend projects can use an UPWARD file to declare their runtime network expectations, instead of having to develop a PWA around an existing middle tier or API layer +- The forced simplicity of the middle tier, with very little possible logical transformation, discourages implicit and undocumented hacks buried in the middle tier +- YAML files are mergeable, like XML files, so extensibility options are copious +- The new one-way connection from an UPWARD PWA to a Magento theme allows for many developers to use one Magento instance, radically simplifying the frontend dev's setup burden. + +![Many-to-one diagram](many_to_one_ci.png) + +More advantages to the UPWARD architecture will appear as it is refined and adopted, and as setbacks occur, we will refine the UPWARD specification in concert with our community. + +Progressive Web Apps are unexplored territory for many, and the best practices in the field are mutating very quickly. Like the GraphQL specification, the HTML5 specification before it, and the REST specification before any of them, this represents Magento's effort to help stabilize a technology sphere in which we are one of the first explorers. It may have been slower and more expensive to implement our PWA Studio middle tier as a specification, rather than a custom server, but we believe it will benefit us, our community, and the greater Web developer community for a long time. diff --git a/packages/upward-spec/looser_coupling_and_similar_envs.png b/packages/upward-spec/looser_coupling_and_similar_envs.png new file mode 100644 index 0000000000000000000000000000000000000000..8eae122b81de595bb6179f17cb5099ab34be88c8 GIT binary patch literal 69748 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 DeanH& literal 0 HcmV?d00001 diff --git a/packages/upward-spec/many_to_one_ci.png b/packages/upward-spec/many_to_one_ci.png new file mode 100644 index 0000000000000000000000000000000000000000..a53532e8c69c6283d52f585802ea3385a52fb593 GIT binary patch literal 80291 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 tYfEO>(2v^g|Fi7<k+L`PN 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ΠNw>=Juy`FZtO~vK%Et%uwUtYEU+HKCJMPd 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%0DXNK zAMf;KdDId)*%P9I_4~U0b@?!r880BLIiG0kVQ-g@>>z_}&))kDnjL~+WUxB#Z&R=I z=Vku;+nY&1CgMGt9h<^PPGpRGB_@RyKBkebFX#tCi`J3*|NEe>FoJ{ns7j%4hP(sO zRKR%%OruJ=30^HhIHfu|83*&|%loeriHMYaM4G<0=V}AYXtDt@z*xw*xO}v;;0&zU zE;+Uw9<}YM!ZU*ZB4fUE8z{2CvB95>yeyXpvnH~Y*P~`%5tU+dmH}yD8c_ht*~Fd zIa*v=8fVS|OBqRlbar)&&UlG=Sb=eq(XZXzXcH2(MfAt}@5@d~5tz*;U0n-AGpgZ- zNizP8@eHN)!&T7HGB5x+IXUBjUP&d9*KkcgCw==rhg*w%xBE@u9WGlpOYJw=kdSSm zbMhFQHH{O>@#WgRk6tM}Jc2yqHdHRY>ji2uXSB+UdL$~(AKy)T>ifCoC$%SF`*UCW zXx_Y5puakmQ%R=%#}d3AwzpUL)MIchpT#oB-wm6ZJTUvFG&B|L4!VJw!eYGi*@5gk zU`yr^R~29D<|!CgFz5qf60;E&gDLyEP2mi`(RKsg7k(*!-j?7qpur5+xVIyHyx@OX z$8B7%a`hS=ugg}o#s@=}hU`3vHhs4u^5l3^4oO*muj^WZ%4(q5x34Q4Qm1=$D#GD*5-Gbd zo>@Qhh^QbseGBASpT+7tpOD}t9+fEkt$~DhOcbS{`fWj}v?KlUvt$-c5$u=mj^d`H zv2o+BH-d*5&G0^S<>na(2Kjjv*Djto2g4jL`b1m13+y+RKnFVx7#zC#Gujq`-s3e; z5Is#r!v8tni8GpH&lk|@sP&EX&{&*~L_cyiN#Fb08}Ib$!;5lTKAO?OH$~(=H&5Md z%reLloEIIFQpC0!>1%Xrc1Tt3V=Ewi=?$h?4rzwPG%Sk8QbNY9k#D~)h{}A$b`L+# zVqd%bO5Qmnzq^C$k|WKv%iHcepmMrdEw&6h^crv$s7L$n3ejsk4;K zx2*P&*DyzI^mD1-KE9ZiSMx-Y=+bkWj7?7`FhSR{#0|CM>N?tXcXz)6U3Ei#s#i;! zK<-l|nhNNS_Zpu%Fe+zfcYx}!#FsB$9_i{@TZAn_B&WbC%L%liMd!$aQu}>pvBDV|5Uf#kC>EJQ%pjy) z>)!pcYoXKP73n88TkWpASM1N)S4y6nQWZJN>4<4(=owTwB+O^}4&J+z&h+JwaMipm z;r^0|Md{vQ0j*xu^BkYEEq!Oz(QAn5a&0}c<~ihAt;eHE&iKh%n+C1d4Dkh1X}2G( zZ;sa$l|S@oko~}@2TgBN{dw&TZ5-{nZ|~-zYFN~@Ut9V`T^}kwJ)7N<7ZY^KFPDzh z=+dCZZ6?WO!Mdm6(;O0pPyP-_5p_Vgg4rA3J*`rE_%QyNRok;@91SP`wxRp))_(nR z_Jz>BdGP|DVUzKxzc>OE<)8QYyFYo$inyCpd< zlMV(S$@Fom-I8%uA@|!!`hK~1MJ&5Sj)Oz2%B0nz=I-?3$xkA!!4mZupJOq-gC1r! zv1vB;sw!IT`N0x3tJMi9wWm21Z*q)%IT;#HKWu0PwcCZUPUpfjl06Gk9{nmkOAfhx zSw@`WGP0a4RVC+rG#wua2<Jr{Q;c#N==Ca679%(R&82b1eZ{owg zcAgNI!neW2Pydgsw+@Rc>f40@2N*&aKtOtE5ClQGJ0+#NyFFBEAETgMeOIjaY%0180wgN?~@Ey`GmT zV&E=xbhgG^VG4X%L-i85zzT#w5D0j~G$Z+JU4_O4ap2*VYek0#E;ij2^~ZtEnd<(y$$)uGS^KljqvW^C~4}uiH@qH_3dM?o`QIu|1~D z>C7bgQyQNxZW_Va<~A9TGy$JY!Jh_v-=~Pm%ONtTx?DER?=MGjulLntjs+gs4Lexq z=WDc=JRZgC25pjxWn6gN4rwCUdba*?>ML8zWA08B#hN+t=Wdw&F)_VX$;)Svv>Lnh z9P@Vl^UZwv`zLC~3oNGzB|%;~&ACFco#@nO#)W#Dl=%Ff-L$3w32Le15(aJSA*~rD zX~p9fk0~`WQziEzlkKa7QqsmRm})9X1D?(97e5ZB3J!AWUGRRKHB=hi|#-g-} zTzyG+f1Jxk$Zw+1S1_jPzI#JT&uc_@jgd}LAinQhZF|q*O2&idcLN-hgtk|?vyyz0 z3N|p`=Jg|74K&p;6l9sXcYfs;LFtP4wZ7L>FJ30_e)1Kitl6?tY7~i}`1pJQJ-0GG z8#Q?tCRvh9R{s6v3xDpCynm378s|9{thZvWd0aS_Q;2t~nj~?V#*trP4CA+{*Yqe|uI?V|vu0`IPm& z;McPF3~?kbt4s*Z=ML1%wH&{q$33lg!NKqDCJVkMn3- z^v?gf*UV{t8h_8A9a~Y!6Z`HopmgP(0y>MGL)TO7)bT~g23pto#omPaaUt<;Q83eQ zb^AIXqp=#h{G-fIjT*Y@I7Q3Tj*-m}^PH5&`J&>F6^WXhi=|ASJ`|Ye$H3`RQ4++| zvc9Jw&6*kNPe5-$)0yUtK7R43Y_kZHuiy3DAR%fc1HF++}PN!a@)tt zZjJdy={xLUtjM5j;f9)~*sH3aYXYcqc|#nw6U^0rKhj_`mFk?;HJ{H%R;$;{$hBTc zG_Efl%RUQt4(5py=>ezRTwgHPX)&3vZ#^Z16BM2UO*Bw)jE_^T)JU{XvU(T>B=#F! z#p`?L+2!+{#Fwha3?7g7#rxvsUXEw1V%GXf-;X4p^r99nrG9-?`Pos{PyiDP>GE;< zxsj{sesu(h(_NQ@GQ2iiQuY2g7gqFeZDAhJHu5{m&5HaLT{5x~?gOT|*U@d<)Mx|* z1Xk(0rsewY+3O3#5}?(k^!KA%>}VMR=NKt(toQbZ5|&!BJ}IWMg3+bXfdw9lC4yX* z|GB8VTB4?W=zd2xT8Z~33n!6jcXfBdcNVdfa3N#Q@#JuagE+%{wjLVo{$BN_aEp+} z#s>b@Ei!`bJ_`I2A(zUdB#W&EIl|tcZhp}+wMAxz$+Gu;ZBS}8j}$6+k&hZR!>;>F zonSra$EYxLS2Q*W%ZT#TiTbjp>pDBrxr4qP4)+~!KN;H%FJ7L;n3g3Zs&8Uf6z4f zGwZS^10R7$wJ%ClM}_hJ`pw*Rz08;D>Kc>9t}0fG6Cqu?s#cf2!Ai&PK0h+2;GBS4 zI3Mcp<~RI^IV*!%C0$mOn={eXH# zU3qfCAKL7@#%=-e-#xlNyIO%kxy_V(rE9y|;4FwZAXL&|Vr%HE(G2IW;_63jW4BrN z{wx*2%PeiTJ=wYsc{q0zF*gIPJP38A)%Bq;-(5EkZNJ#Lzi*=DYUXMc=dC%b+*JKv= zo>t9+mHGMaab4@n+c_=o*!KjkifLG8^U$)ltWfv%lMD{j*2IkR>Ul;a``8I7Ydjta zsd+3j);#^S5_$St_(QBtEeli9yc^G#kfU`<^;*PccIfNaW*Zj2G@z5PX#HZ#a;<3b zV6~ZiJ22aWkY|!PurDaZ`jIE28mcReY3KNR%E+(z?5C!m=k-u(nBPe&`$wJn(kXGN z$gfw{neqyaPbs_rAVgH4J#!@S6T#oW|6cFd*TXD}`Zqdp&({L z5a||f&Z^g6xb;_ZZ$S=n`|%U9z7OipGmDeJV4xU)_ST7o`reQCR-10o&2mrKEmW#epKrax?pRD{mCQ>s5xtRls@21O;!HNyOTWIGlv4{YWC4635X|6}im z@10+6%KxS%It#_rFy;cww=W}OW+&t9oz-vbBaSzjTHo#sc+?XMrT-`)<+lrTnQ_ma z&Unc6e4Vva9}|;Rak=tWfcemoM%?X{?uD0YsKVaG3j}rfa&3<%=QSh&FbV_Tb;1pqY6N_l zbyQm!b-Z8>At85G_`jxfovXDyk^Yz+%sH=>hJWSCeyJFh7p;v)cU2pai~bftw|$}c zR&!Va<=KEp=Ax>ginN49prAk?Hv(BB3O{c`x4-XamHHfQaDIlO*re!zyjX-Uo<1y$ zB4%}tL^m%sa?kT(bs97K@jv(FD#T&UnN(ZPlMn9J#o4J-j;mr0m_w8?;RC0z5IkC{ z*r;onQ~(>LnOK;Bii!$w z{AGHDgl*7$H8A(p*yXmR1FA5T9yxM%BgeqtKTmi2XQ{0Z-K^$-e@j*(hS>5i3{&ty zQO{!&m(mOXohR#b$D?6YEqIYA#<+X)btONjk4#2Pd-^FV<9N}2st+K8FcI1uK}+Z5 zKtABLt#0`@yC$Wh=5zT@%;UgeE7u)>gu-G3gHSo=SNZzLA58^=Iy903xc**|tweS3Mqql5&kdem9+D8xsnGbypa~Tn51qdjzmNP$GH2?=128 z?Yiv=V8iMIOtr6RbyjwmA2Ya}fBZ?rj+Xj>?;$CIewsE5xD+q_fbI-dJzXU7rVDOX zB-;4xitC}5XXe$*ecOC7>QY6mO#l9U9X^H~a=v7&JeRF1h2f?TfK&lkI26K&qv2lZ z0Q7M7l=8)qEoM0Gt~Fw^v`wX#vGifuiq*f0Z>uX)oY89EJg8r=`zXuPYtZch80R*p zwe8uhU;F4*8U*m24}Qc$4o1W8eQ^rWtUMo>3x3SI03fe{mxhECqCQkHMC_NAkw}97 zM4N3~9R1ST;Ht|NGk_!h=Pmr6c0uu@Q4`nd#_0tP-PP1{(nk$(2rb@>`?e zI!f@_YjzByPj?r)&Pse(c*LbRusmU&GgUgw$Cbo_S2jt2FS8#YsjTs!eGn=X*-=^M zKPGtDKzPx&vzV&2?hnpe>`s7JDm`)rAc4!WbaZu`fj8q=BC>-Cw*c9E1WX#S&>&dN zYKw$6gz72OJ76K_>4LV7<9&V8?~=MG4k(|vc=wiwhMfPe2|CU zW~^rA+%s=w@t1e^)A7ov8~xu5=aAD_(PuyigfZ2%yTm zxSvSvS%ao9-qpYCK*dANuUx4N0E*Yt1f0!=Rqwi5K^^rqN18yGr+*VCxP)`F8h}kX*huuw^5)EMMDv56{@Oz}1 zG2gD7_1wm_JFfQ-&;a@jqzB=?)6~$&t*Rp0 zt;-r{`N3!)@k|~vH#fJH(hF;k*^jxzvc+M}cIpbT*$;Sj2D z&#HN$B!}nD!`I44r{CrK-r5;LI6ibyh!H`^u!%+m9xHlIqI}F5<>b6OE(^#m;;rRd z+v(gD{E;KQtDi7>Pjh(4CG<(37l5aeI6y)e*nacd4x(RnVz}>t(MBCXs1P+5b=ly& z^ZP^DOJ?;4`^XfnbhXLJj!9g%MFk61(D=kcKhR!nGn~8IYl~*+S7dfaaTL@DA`q%H z|3iq~yMlqcN8+QgQ(AGB^&O4s16cm4m$S?ff*H9BS4V5nMxpRw^+m+Kx4(+XA12A+u1eIEubE zL@YvasLD1$B#47M_LWB66mG9W%u79YF=3;ArM@uMK=MapK`J|-@HkX1veu=4_>lVW zH1m4LGs6BHMpy)+%n8tT4vK~P-E zV|h2hVY{F+>sQz*=(SaN{)KBa7IviTs`2`?TYBm09K1!AzDkuFqcB|sdxlna9uFT4Y|%}sja zRNy%|OXcD|ND+r{{7m&d`%{ej<^tXt7mu-23$`!p-r?G^m0=wP6K1@All;reFcs}6 zB!1@QPzlV5qiMkSZTYG8&wI&S3~(l&hn5pL(^YODgYiqa4!fv8g5Px;WjC z-<$c@0;**WMCq=bpLPYI&tDNKKxwbKkvBT81z3hI3M|)EdA}J?=kU19C`glo(s&{0 zAg^G3Mj{P*s8CmZsZQfKBV_@*L|^Y~3|XPiNmqvx$-$qJBuPEQeD4>Q{{l(MhE;4Z zBdkQ15&rAGmxu!6@6TOVd?hFt8Vg~L z&lR^m)Lzlhwg?~Z!2T$LkBoL;1PKxU$|J1lVgnykci}(;EY$mqGn`MAQjWR=AE%pv zjM;gl2ot?ZCcWKNtC>G|Uy(I9*e$JP2AgexmC8a3lzGGU{%NU+(m@(DY(d<1)bZzR zjF${eEvvNDZoJM5e>Zzd7lVY4O8>n^DSYRl$skOLLdKg8jBhB~2VMy2nJgL7k-tb> zk0B{Z!j)B*u2^bhb=ffJ@81lw-)9+lsF}Ld`Pm5!msnsSf5-_rw?;ta5%j@swz7Rq z&mm;}?G}Y|d6g`{JPyt~19FaU{_=`X^l~+eRmMNw8~TSJa&n-mp~d8nz>ct%gA@fl z&P-~+!Un#;W}eYD!iDuv^`>f;ZF_^^)_A$X_mY7!APxbHN3d22S2g@v!~gXqP)R$> z$fw~4CImEyIR15K0whsFQVbULs=dGiCCG& z8%7Sjm8+26&BOp9ZLQ>V`FyS&y=_R8$~tXK zav14z%f(SX3ko68#bV6}!!CE(##Y*!13H!J&+lr=zmYp1HAw?}VZwH{hcJijq7jpm z?r&H224Z}Z&%RcASa3{GeRO;^Y$K2GL=-iatN0JOjRsRXcOEQfPpQBMFL(#wbIO;0 z?_u9?5$OI-Xcb8xH@7%V6*ww8)+%rL@hlrTRQ`=pR~DlebW({?B~BIa@#^oA#xXfL zY0s$4Ewa&RkOtsQT5S&diDl2PdzQ%u8~uup{Mu!lh1AIGPZXlV+1y3N-m!m$YJ(+ypt=^h54jzT>Vw!gavIW(~{OKmTtwlaj;;u8Hs#~`tQu~0&oF`f==Uu z_gn~$!Yid(KEv4p3;=9ua&{2`P_{gCxxt~I>{T=PQD`Zq*U8aDfKuW@S1s#Ec+_;v zU+SJSJZwGNQJKlpdp`p2iMLmau`^Y*b`XM0ygNh6MJ1473$6LjUq1cFmSqL4MJ)~u8C>|iEOjW5O7~xol8x^c(hlOE z9l*j~#Y_~QFxnwAV6e3dob-zwXq;9T;}XMUU-vhB~?oNjn} zb#9uBou3~TTRbKC&u+d@mf1C#a$>>i-w5itDe{2HzozJ>533gGT&{s%{xtFXRq7q7 zUaY@-TqP`M%U)l6r_;l%5;s06EMi{sIF(Y72;m)CoL-Bl8Led)TG`0t4Z+v*kukXu5-yFsVf$Vb!S1PXue z>WDUOPI2}+Qc7}?#~ZE9sd-3DGRm>UmbY83$_smdI`~)71f0s{zb#YBkj3uhJ=ZuD znrU8kU_y|43<MAXd1is z{=}DDWAfLjXrEp;p%u7<8&PltF@?aPy=ehF^&Rg{0r^cbkmEET=m$$kx9%={H@dt~ zE1gJBI5DAsL*%lr_lF6U*_x5HVbM3Su)uDnC5wi%Z;VHKSBuYQ^FDTw`J=g9DuCs_ zzt_TaRiNYuUkC4{vzZ2Br|HOA2^qLb%EdS|pTS%Xr@Q+;Yb~&)=ex!dvy1#4h_(9j zp7GGtZbSzMohg68H~c>niJz$m<)zRURtzMbF+#BdbYvtjBZupXzDO8{ww%5 zrPS2a)vk{+&XQzoCP_WpP1>GpD)QcWSf{Nd0bCURQzifuas~{*{lHpJz3hD+9iP*m zNV}j#0;myMO{^gWjJgx~lJfPM)`0^=YWUL=K}RM!k_YSzZfy??UTSuFTm zdM6KfdRtuxugSOv=gr8vLJNReoGaJQXsXwxNAj21%=$bze8?Mt?fos9ovfr9X!mzIVGt)!w&G>1>t>W%DoEMQ*2?a7~xV zo3;N@o8`u1S^RX9p~UR`CaVPMc-Wli4$q(sz{$y|vOLp2;Ri6T21f1rPhY=&C2ST1 zKfqK^HEpGDrmY|qJyrgb4Nq)SCZh_hr~XRKXbeRY3VRqO#WRJkd-`2p@`hY?$HmKA zpFA6{=BL0MS^D^NI@+SH+dt}%->C1OelXeIa{u3z^ku)VqXfqAFWwms z>cQKU>@MaOv=Fj+5o^c@cI=%f$wlIjPTSg?bQ#0s(9Nx$Ix)q)49Nw1TwR}U*cI2( ze~%3R`-VcDFC)F7L$qv}2FcykAww3A>-d`x+I8ja!gnYgZn`0l17$hud-F&>ChHGP z(@NTc>#Bm6HcQQO2(KMIUfNLyJDhJ$3}qepP5L0|tfs#jo1)*c=)7ZprLDBPG~cw< z$_)(B{1Bm2|8eqZ=U1}K)O6H0-@M)qFyG&hGEQIah%Cy#HqOE{#vj$47fwY;fgJ&&1j#0XwZeS;tI$fxywXs7;uk* z_8q&(>927=g?GRF$xs=QeX~+128oq*`4m3-5;?5dxvZwTnrU!B<5EOO$~=mJ-DJIK zzr04k8^Fe{ILoI2WH#K@s_Y&B_Mnk?@5k$w<@*4!@?jRPya5xF4s2AXo*Sbvtk^Vaj5+PI(bE@2xE5>321II)X9~;AsWq0-74qS;4uhc_$~mo}8wC-@Fv8 zQnN$76is;cPx7P)9K3U5geWQC<_zWDD-YyH^$iWxO*cy3dM&~ne>BqUg0J7r#mn!6 zwp{~4yR?%p6LOsFMzO}6;)_rp3Q;Q5H+%?$zll{1-IlZYo8)I%aQfP@5p{J-QKJ7{ zhgxB7P6L8=C=fd*!Ss?JZol@brR%0#tM2a-5xlp&v><5YUjb8uu>5oMFW=^_6k_e7%cym znUS$}9m3;v(WhpuR2~lkNrBoA4s1#yOS2fAq7=j9X7x~J$q#8S{TTSJ*sO8T2q;y6 z*p%OAgC9pUma)pK#K^smlqjn0mj(72I;aV#9B1-dqy7LXb3dwR>jWNuVAd+=OK%Qx zRnmb{TQislHB@#y7}U#?fS3$f35igYYVZ_zE3Qv=O6l{zAy>h)$`ErN6GGY7Gp`U{ zw+vEmp-0%kI5Y$*qa3oTc7#m0W0o6#JPc$~@GhjFe2q0q1|BO2!MUnya_O5ok0$A8DzA|Q|z z1j-=rB+N)YjcpZlhdURegI{K=`Zi=lI(Zt^SyIa;1gCDV5~h{T`1G$ z^kO;vaQ%WzMu)+r5P|rEX+Rf1fEelq&6^`>Dd~WO%IUtpho(l-ez(XK(Ip+x(ws6oIK40jdauPR@e#V!AWLe@ID9GP=I^ zyjcyCdt2B7kQSpY=R}WxM~*Ar4t`ioXrW+x0-8IL0JvYDzmS$p-}t3m-BY%``+R_k_M; ztu^{Gx&o*f>NiY-LH5;*bt|MJSVfuc?`e?V7HfG1BzniXcX>6d(@lyMl;hFM7xdut zPZ7yMUkF{p`e-v%zy7wTu3%)5C{C*fPZP#jnd0n zA`DRsY>oStS+{Aj@1Gp!KgO2?xuz`457@Zeq|ez8z-%D>WPLzsBLZ^2J*SBDzGX9X zYqpfkT>|F{i|7YX*$^W$-{^-b?hm8kez zTO&*Z{MV-&O5gDMu^7=$K+>Eo0_`%;VC8YBko^hZb`tW1Y5~_*o{0Sql$48zD&a1O zm?e&ps5Wp4WsklEa^mFLI)8;!@&i_#viy?9dDiSk=Vj&Z9?|haeMB8JB9tBPdJzvG zDve7vZ?0-E8D}d=$C##HpZv>nucRS(6jHRU5ILQzDaNnudxWPk7^!Q!^Y4zk2E_en zHcTJF+91ND2jn6U{a|M>$YixE;$3IfdgYHwveoC^q8yGu_|+B8#lgxxe-F89s+pL5 z@NEw7H3^VT@nmH3RvfMiw*z65Eqwbcl`DX}=c*HA-bk+-o3 zYs*iE%Tx--1X7%~#*PU3Jw5!_%+F`c)6Xwaq`DQ&XVseDvOV|w^xssNkX-sDkOHf) zv|ogezgz?yrWY{y3pqhYMdaz{=$Qlz5D-ON@^FL6L8NSB-=Vpbu+s>*TUu&b;xI@o z+|{gcY2HklCdifHn&p*sfO)e03l%V)ov@m7?&~Kg>?A)8h5v^ zy>c`@avBLDxh74iM#gOj$}rgp!Pip^Y!tKm;~EpM+?SC$Dcn}^WlzVNtoT1e(4`1m z<4qK*Gt4%N%W-kB$_l4?Z%TtiUP3VtmRlD?B>;I1hBHBSgZ8}=dD}~AB9heda3+f* zR;5uHy9`+yTcrF%@iQTt^gTP12<$x9C+w#XDP3(O+<-6JUK|35V~=(TZit&n0c=zo zHWh(xAewkMjsW?WW8TB$!`)@=ffRZo7sx`Ygpb-#+6mwZ-FWWWW+x^V zb~DFd5E=zk+z*KReAKKu`sMgDnC&_HJ;&e^9oa4HBYjvoi#^s_Rm#TJm&$YUWsR{k zOoP}E5Oz!;QGI2?ebA>!E< z--teER_^qSEeKLuB=g?Za|c?OHetTz@*goulMMzQ52;-N@k1id%)I0tuuZ;jS&9Uk zfp9S&Vn!3_5Dk%xAak@=-<2dCM1(}NF>Zy0);I;KK=CMOwme-Z-*NJSPGTxi>HWb~ zrzGUjcaRQ<6&8l$vhas)!eDCT05p77wo$MJNX58L_*+a5fm5&1GuKM`n7^sPqjiXQP`kHBE^HGt2#3V9VcHFn zU9EO>HwW#A2&G#agpH24N`4sm+yRZ4XxUtjyCugm6>ug%*ApI5QSYzY>m2jV0x}d}PMd@pIRsj|O2Y?U0Ll=>+S*J$>ZN#kHv0|Vg3qLI7bCngb z6|^IZIJ_$*WD%lyt3I4#RJKj9jztBQ7C8+BHAdL$`9-=xlZzzB6AagmdrbsJl*Z`0 z2#5PCAccaL3s@{KMJQg?-ocW`?4>ZZY^3BMHxLQ}eE9Q=pgXk5ykNyoIgkekAr?k) zPCW$XoD8BcaAE{uFd*c7ci@|5F4b85(??4c;TTAe175j^ScWihBR2?^@@M{*aQyj` zQHp!1^U^SqDgHi?h+Hhw8r0ui7r76*HDqEDBySjm*I|z6O|Nhi?Mhq4kRXZEmU1W+ z@tSO>6%lk!vmRQe!d>wc9!_U~m>E^W!qTh@HIM*zx7j#H61p>TFd;9{XuVwOWS3YyX|pcdrDpZ{Y$z{*2tg!w~dl8zyJOQ z!}|7iRHXBKeD0NA|Is7>hC7K|Pu06Yd6J<+s+3AB9|_~>_!Vx>Vq7U-~BxX2Sr7+gtnAv)y>CIqdQu3-NyJ! zb$~!-!KxrWR5d!rj~2gq_chuPBQY=6CEn13fQZhmS;e*#fzfAwO0F@c4y#IEVehw` zu5akLt-kvxY#}fuWq_PcP+P;S`>G)3Mk-Kdjk`25jgK(1!Tb;EP+>zQGgr=iA`f|l zcOIjErlbIa2+33WB5<1H_Ve-JUQ3PYiDXMy{hqy;x-9uZ(8jbSQ~Fo>SB9xV$It>X z)G($cg}GvDuSVU#NYf-euXcrD#$;Vc6m8sKlY`!I(TrvD9G_{O35Rs@6=HSP#VMeU z$L4wD*q7E;H7NQAK|qQIO0ZV#2yqzhSC!UG$=~3z8a7+zj!o>LJ;W*_!9#2?Mq?h+ z)7C%Gt%wB)Pb%nU?KKxkI55h$zB-nR_ZR)+-Q>>XSRv z*TFp&VhlS1?-+b_h$tbm(**Y$^!e@;>A%n4iz=_s^Rxbke|_`U%9wG?IOgfz$!deR z5<$ECqcJjNsV8_%<0IW5Z8_OYf{#HDpa0~_lN5;!V}SouToZJ^j~aXgQC%d*nk8=< z1hVIBG>&1}5Tf}_(oMoKnwg;ET4^6Dcz?J=!x(f6V$n=IHL7y56f8zhle8cR3sX4b zWmg6cJf(xd0denJN@+yfTn&Sk;79MG)~MJgaxX)~?&R3}sCuq2^oYUt;iPE}7{=fE z=TQz%Iq!FwiMFxPE_U)`30tVxzuWeNN0Ork%=h5*Z07Wb2(7i&5yIP(erkTpLV2zj z2zs%ey(m2_p1@GL7r#Eu2N5I)DkT~MLE!UC5OP{Bh+fD-yzSv7EQk^Xf_D`Ug~JX^ z4oWC000#h>x*}?QnQFi0-DTWxM=SeWX3pJ8Mr9t5j)@p~G`t`ybYS~9%DZ|w_8V}e zLSbn0`dZjY?&6xW9dZOc+NZ4ppTQB#; zfAX2j$Y9vIcEXC{#_~B9VOMQ|z7#hcUq2K}Bsp(ShU`1>lB{!qOm%*@f%W+W^4^14 zT@2g~0pG2f94Gh>X13V!1`l*cn4%DToYYtpT)Lp{4$P zbc6ckBUqN_1TMv@_v_rDceBo8y!2>6(EKytn2*K?j5}2_!>YQqu*ZcPAqIOu3sg1 z0?*u-bxb-z4GSi?)|>BB^Z$@9YL{;Ax82asfwGhWFB*sHu3@`Wt zNR0!;&k-XGrAAx4Z}O?Lh_@`2?v8}wX(B&T!7`)ouT;?(xF2Kl43 z^8w+adRFhcYQ*ruKbfrFVPW>*mB{tsJVqT^n~+qs7~2L2Rfz+@gS2@hW4tlieWxS5 z-|%Z{?2<}MYh#lDXq9-1gWjc2NFC3a`g67wxPb3;Y&#tBwTSzfiYPpa$O0behhiY{ zulaw_&^k&8XfY#3L<0?hD8s4t_MY7iKJ{a;^7J*z{E3FE&aWqp?aGSs?I{&~x%;uf z^$amDNNXX0q?JDc--GE26+YE-~0*ze5o;a)Zp1tk8#|&8oAI;%>JqI?TW$}pn z4w(}u_^b6`Xx*XH-@^IV&U;RKO^e1%Q(K$UILGVCmZhgX!}}#90ZFt1X$}1;fnG#} zjML=M4@t)`Dfj<*903#ESGaPHmsz}NCF+BEw(sMwnLBBffOF+_F=%&F_w<{PtAPQ` zfzUdJLboq&k<5FGnlri`+GXX4sg38;Nq2hq!?bg7#eGUYMf_jx6`?igD4Rlg7eOok zL7$a~Kdl{{3A5oL;zKT=*&GcyEC0{^G>VSp58Wu{gr6o2UV|k4Lk~+()U_)LcIxWG zYNDBN-MYio$zhrX^Rcq})a)Y(jfY5itcf-$gkxgTg<}SInRK+Xlh3=c z#WQ7IcVk(+1^s&EP4vUAqK*bc*in}Mqu$$Zof5zt&#}os;IX!Dj8tBoesGgQ0k*Od zt#VHD3skEZEhK|O_GuK>Xn08eHU^HXx+D&t45toX5}FL*Dr%v?^<>WE@p+dVngubo zo#D`(uY3M-+84Z&D_?2>CB8!nmNs ztk-E@p)>EO?mvPYfEs2(pqKN8TuGU<(F)9_4feN=&>q=s^kbq879PDhji&|59_P(3 zNa?s0-=PUSD*t+?Fvo*hUS~7QfO%A;kP{#MjYG=PvH0R}Mw`c)P}4|+_&&6I$=dC| z%d(UlNIB!CvIQYBWsPAlP!mK=;ZjKhkLFdS%o=Ibh{VBeACp8_M@R;#Z^S=>8OM}m zA9lEP4#QSW!iNjFi6RqR>VwdiUGG{gFs14E_rAC~{tw&y z!jTMN2P9DoXn0F$zdqevXgChxB3<)#a<qTmX_%0Or-zX)meh+BT(Tf%ov`Z1VrS zI#Uu#9f66L3D8=z6omzqp*v!!rKOC#W`KkgVC>of#_s=#a(EHmnS~0;&~O^~kd|_T zoN65COBf|n;x?lnO?)V^0$&I$irfhu*~oLXp<^?Qbpea9vxj5v3W4v97&G_(?|&Ei z1X518A?Ei~K}ADDEWyCbu@J^w`v}bS{S$RQ7(lBrUQXKQUN;VWkbDjgWs!W2GJ@Z9 z3RUzEfkD4T?pSrw)QLOI!mk0q{-71s%iYx(QUI+ZJrLyZ110e}59Q}15BV7gApB=C zAr4Rx0WMU*!=v%N&O9Kb-Cg=~?^e#~C{ViJ$pI9dYqt9S`IN!dKR)ccZLquwruu+j z@_IoPCOcg*M@8LDJ^ro?w?60iB5fTbg*3s(>#NC_I)F|`th3Wxwjs!%ZUJEI-?o5P z(QrORBFph&;LOAt^WlEW$Kxm_*xvt1bg(D~7f_wHuYFcjgf{&9@=epnNVge-gy${& z+AOtfN*|EMly%dE@b{XU5y4^`OGTYg_kBr9Su#_47T{lIYBG!Z!kuxSX-!UW$TM)` zs4fk3&TInY4NI?hR#$Ho5*}U-&@-Wh)Rl&OKWr8$RCxfw)KvQ-cJ<~cr6Z8P+Ou2B z6?3?nd)x+jo8*5VElrSe%uS|%&wOzG-@h_Avw(Noy7>l}58Phl!7%{r%*F{C{z+Zr z{tRzf_AHmhqYISWfYgUGlxrnXo2z=hvbz8*BP#$2(!YC$U0PHcv{~pu+2)G55V1~s zK%m)Nq470RrT_-h_&X5O-;YCE=q$mR?lHnB2TuIgjC}Cte?N)z%O|O%qYorvva53-%eWXF3<1R0DL{kCG|x6OJ6`ZQz%ymALf^kH zlR$7S_I$YhA>JkxlkudrciH7y)!Zx+lSDF|*5l+HvDj+fN<6FoP7)(oR!fTrkZq=7 zeU|78$D$10ra&bJkh;&5ZF~|0i54$wro~$iKjMHNBGAq75x@gsqofR$vz;bo>hp(x z#n|5tq$e@C|cKjz6YV$WHotmhYs4?V`>$m%E=!n|yKrz-p2#Ac<0-i)JOy8GzUQXro=(GJ)@_zFSW70H9_If9ysjqm$q9 z0ovN1Xb4m!TqWr<@)l}!>&d$aW916MZDqfBl(LdfbgaElde_B?V|n&ImYeY62kb|o zI?^Tut5})w4;v7a)QC7on*DVaL|TH9fntM~W@D1J2S?UtDCukoZke}5To)%Q#H z`6rh$iFn=p5$>NQ=Ql&5H~8D_Fr|7t=;Yj-@+d413QAvlGs-Yf9SIG_Kxajb1S^R2=wpx zDazQ8%E~u06S65KF{~LkNOxzyXQ30Yb|qn6lA|vQCekX{u{J0snUQ&)1Po^JUMI-n zOyV}E2x3N3PM_pFKWvZJn2)H0`0BM>988@j$mB-y?E7&c$c4j+`1H!_n(RgG zt0<`$*?rUS-&46@`^@*oCi$$>^sam)09{P+FLqOf+%)$N9tl)2S?66&8s!N1EdE+gteB(l7pIn8AD!L%3}e=)Z3I+dbJ~@1 z@7eyC0<}5PH7s!hj_*MAGc;Ljg1UAs@`bVcn4gMX8&&<)GQ2Ac?uq$pd zS?Bw1UN*#UgX-s#I@%`>pcv$1PxaB%_MOfzP93+0am$GpIRlj-0$=_kH_7wQ29n-#(}BgiiwHh=%pI)&JZ1y)coFH= zK7m`RfCK88#yw@P^s^!qLK~)EBlti$R($W~u)%ZM9C1zj)2rg))5|=31U~s>es1pS zU9nNPlzeJCWF1M1Kria;aN9l=9i<8QwOVZ=F%61Jz9|CbX(szX;WE%qLMw2Z8K9>g zMBxvK&bbBHr%eD+uS937((~u*(i}mIq&xpZQ$n-7#uTy%SbD3O)B{FygFYqv4f0Q* z>O3|4Kc^IwFd##NY|#nukD1#EbRFne=92BAYTlgY#|mKM2?1^mHhfSe1z_UoEd8kA zWA!eMl#%EX8i1Hq-PC5ifYHrYP73k{x8090Kwr3U>7?1xEp)-zfT$AD%E<}T6I=sT6<6G2cil{Fu)fsTO^+q z%tgNV@9uJcTcBphMZmqGH4+YwjAOA(WG(QR)b*4!=7n6h3DZz^MBWsSBqFBz+I_Cb z27!&prgfnnZ2Ov&MQQ9?jB%vU|9_;tbx>4o12;@8u=EnruuFrqAl=(XFGqU|$eiB|$26P-M zL1VDou~b?YckcJ)O=*lxZ|S)73QN}<3I%xtLffemfVS3L&;8jz5mf^UyuY3To23Kq*z&7Pw72Nk}7)# z$pa(|B46H8gti?~oZVdQHJUcu-Rv3qvtI!&`0hB_Au=cf9$3&SpQ)?XYtKXgijncV zD~YZgUIwGm%YDxvobjVG$P4rq3%yX(mh=fI>D&_V5_vkC3rqs^|Epxf3hQ_jqLnaR z6D0rK#Kg%(uC4cAD8eksJKVwA+>z%r#VTY6*kxGv^0#U@NkkTnsF7>>p&>VK zE>K$1csr$S2>P z5Kwk6wWF4k=X3$`y#4?^*4wOc6s`c{O7RjW`8^Oxte0&{kEsSIlvS|QWWYfvv-m5>$!BwzThdt#5jXroHQ&Pi>w$S~wWzd9&2MgHdeGU%* zgu9Pi(VLq{!%uMRiN=Ni^V@{;r}5k2+*_+RV3S!}0hxIN$h(s*kuCrwi|bggd<(Ql8r&RX zF@!Co+L%o0|{U3l({WK0Ysm*c}UVcsS0CFQ^45_ zdmC=DHUmDOZ^|rKSZ;{SO7i?L2RuL%`>=P+Mus{$g>MTBcU{-Ay$lNbT8U-210H*4 zc$SgNS(lQ^eai7(#ATMWeflI-Hr(@JvY#oBRHYc8K-#hiAZPzBsp7x=zbR9;0G4!2 z0lhwPNn?y957iF92jSTh>%Tz!bjiKDWZGO4u>m3IS!oA=2(q-)ZJ{2bEi00%Fhd$e zOjbE3r(%6KB(Yf31ieu=>=Cf?3o?a8V7186LC!V-V#Bfcl`U&o+r9S7b5Bk?daZd# z&^R%~`#^-^3xqa2&GvMAQjhWks{1Hnn&uO>MI!o6jIk(RQ-Knka~T>OFiy(nN~a-Snfv`@o{M z69(IEttY=b;Muf@l%U&nN@BSluJJ;Om4U6 zeUT+kM6K2Zc8*Ox5ofgqbUUN=k{%X{!yR;=BM2zyFO{+(*`-MWYZeiUw~_AV-Jj_f z1J>Esp7EXhOV_|iAoD&i=H%%QzI|-~?Bw(z9g6oCEl(gf-nIx^AF19ChUGyPaL4IE z+`!r72XoU6mQRybJo%`O)JbalupC|a2#uSfrJITOt&avnlP^gUL>1JH&EU5!K+SI! zOcEDxb(;Bs=8RfE#(^;g+>O`OhizBD!_2-WSQR1@fouk8b(>}JPYsw2`X!Iz^y9iEJ171fF9XlPW@X9;m(z2%W8|80V&pSWFySZg1xxyi zr~r7m3!n0rgGKNsJPb7euRXQtc<$X{gmv9UC!Y8~`$xl+a(Mhq@@}*VrGg02%mJ1>84!8jweCz;U z(1ixG1+uCa*Z^4sm6EziI{Ct5(|HW7S>i6$(q*Ubg8_hT93IFU`(BDAWG~u3WE-nf zx?f6%_6Q>IMvmmc&&D?60{+8)?@z-Y;ydsLvGnnYau03E(D!FH!v#t7Z+k_-YcRj}vvqbs2BySasp~BQ{Ri6fjV#-I*(mO5`E3b+g&7ISiw+fA^*ydMl%EJ=4N zwBJ}RMf?~a&LU}A#2lQ*qOl`sb|iSzVj#60b*$^%y=aX+*=(9UCx1=kalJElTQrJg zx8NM8P^*UPDC=~)>U`S~t!*zQgLL0NWW%Q|Q%<6~T@{%EuRZNg(UGnJI3HVG|i|HGHNYfZ%vtmnq zNx0L}UqMgp2w*+d3qU0jbp*vDihcv`JGy5XqK;iqy+A9u<;OX5T@E9$C$~?%Mtl?)X(gKn7J|nXom0-g>S>F=G0Gq(8Ivm8aE26`gx*hi*M7@$ zY-Xp3$J%u|M|Cj!$X9%jnl%TK!XUED_Z_~qcarVyWJYMtLja!o78^ZP4Xz9~^Id3( zIK2VthlROF-Y^ETcaXX&;^xY^fWEi1giE%u({?Vs3JZN`kgQ0bL`vSt^4UE3HTQAW zy(`cG#whk0IP@3pyGbQd_&C0;>4#k$o2 z0JxflKTPWUNI~7gE^W)Ldk{^*9f{s8tb|rcmU{`?TocF0h(hDjH+hXz&|TbU@%53~ z|M)Ko%>aU7u)GhEypOI>hLl#qBoFs{Ny$Ckdfrk(U#Phei}!gnvUw ztC6k#&9ux-PWMp7>9&H2L0}Z2Yw+l906>iAX0*&6@)VY%Rq zb=WweRgCwOW$AK%(vp~3lT!Bs>N+seRonlq&F$DL7Bv-kYuKtZ^&5DWr=7IH%}*F1QHC5{)|NjtIKWtO$f6x_d1*$Z6MuBazXd?akXyk)d%|oXotywvV&g zXSW3CBL@?z+3Yu%CvSSq`gD?89LH-mIM*FSk~{<(Smiqci{=msl$SGwo)Ciuor2df zy1S3icih-(l5oS`?>s*B8yMusz>8Hk|N1wjC{YF)hSp%+ftQwnz%E}QFAJrt!b`&+ zBZ}?qS1b46`TYu9LC2*QQtYMbX`qU~Yys3fS0&m=?x9EH;0Zjkn7!YkMfe=FQ^q6B zE<)(!T)T2&({LtZBXaL+PbH!XvyufKBe}?WS`F;sA7F-A_%4hjM2vWKmbSF4!iN+) zRZiJ#K(=|vt0fj(!p8e5X^Q?EK;kIlk=Y}%MchL-V5&2my(uVpdY+PS4x1>u#m;=k z(M&9Ky1&(sAykcuMtSc#J@cZw`5UPeOi9X%ai5f41KD?tQ3`z5=>S&~i#qNt!&^HH zwH)0CPVmz`LoqtspZxE!Lcn7gk4AAzNGtp!)*w@V&u6zHLEqzVzjDgQBoD+^|F|d} zg-6GuRtby@k+)=!r@<%C43X$TAPjiN81wt(d>HZH8=k^kih-urI#oJg!UYU&JwkMY z@Az7L&oh44zW5%;8goYY=2bcX4Ghj1*W$&W%f63ZSq)GO08;%0dVooUrFzlmQdT+#%V+o#TBC6OyDM&Of zq8t$1=A5>jCYP>N8cf0xBg#0-StkQy8X*>2cxUKTqf}hGE6xm@1Dw*n<_1ocmuY2* z4))0<_bMBXDCJ8Fr}p{F=KwO&lfBo@SY1?mk{y7#CR!QB8KZLyyKz>5jgrj23YQV0 zsk)>vajzSA&8&Ok*xLUe_-!i+(lsEFsQ^qx8UvtSbWsXv*68aK#u#)H zEC{znfV?LAa?Gt#;G!^&j|IA8LIikcwtiam0mVJqEd(gJ{gR z{}n{!fae3Ne2%Ou2JS%?iaeq{Y}7mbAD9?rKzI+c5VC0@AyPufMJ_A0Jz@d|Ceouo z&B1s$CSlLvo-m=L6x~v6IbBtG*(zbwAR@8#vQ>I>g+A;A%=BO@p!F)sH+mtGj-+2f z%Ib>cJ4W#g$J)9f%qTwq_?olM&*}c->Hhf(76A#aOTzXY$dgO|#^ySi$ROnlwps_) z*s^olF8s`CxSvg$!ToHASE!goN4g}d43lWQ*>R2sCr{DXli-q-o`+-9Fny%u{H|62 zY=*9zpFUA2u*D?x0HQ{wF}}bf3oPAj**W%ABl!V~NYCQwmg(J8G*LQJA0sbVgJcKm zu$4WW^P2v0Irn>nYzi6F3FgG&M8_tHwMy*A&Jfa6l^0?AO(QIZVwhKiU~--bibgp4 zWqj*?;`ons1CmA1sPD5PxYPin7T+dDI64=BfUJL1YN@|U)mu7lCGw}b6(-tA8KH$^ zwj90W}5}!VHw1D)R|0q-mzva+{;u65jDz);VBN~6~QB`7r z>BX$!+p4~fi;<-m$pQ(Wmm@u5Ec51d+xW#kdii%LZ^1%h2hDK+@N!uqY@V4{>cYk* z!h&xo5F$`?XsGbu@25|SiiQWkQTn(g9;LhEQ~$qfzrO_`5JvNlCm$lh9uox}e}raQ zh#A!UowIUYqUyrg+S$Lsm13CG?3G~qD)%Ooi)Pmz66?2DYucABWvPg%&zruj+*rya zm!%q|Wdsz6 zDm``IGe)?pYpP(j=fNh8LD$Yu`WkD)^d%k2%u@b4!Bb!bXI)`LbrKP8m>2za0 z>~2$;Zn~iBv_YC9V??pF&_tjqIY%(D>kjEkqO8`rZFWM7Qt|u%Gw9mBUze`@&9#=F zxiR@v{s5)06MWO0?)=-3=Xw0WlWHuy*YxBGpZO}A%Yd~oQZ~5eLE^=O5?>mNIFqmc z%$wbDXe|LrmPtwl`299r;7*v$d^f38UYBKSZLp3NXO${Oo0sr1*)of&O5`6-;}LZ- z<8PRg(VpU7Kl-jI0yK~37U=qZeh-&cywx_Hkk4nZVy{{c<)-j)fN2bNUd(-uXsWLG zird-S`$*ZX(sIG>d&)an9-Uu!ClajEu|4`N)70 z)#9(NOCRD5S~eG6k(2Ga0Q$0~y{=^jh4Y@|A&$aZTEnq^t@eIk&kel%PD1C}_wfl# ziRl%99O+R87y-;^GWE4_neL#pobPeU}Az_d*B&Ejyh1ik)%)8_G zGN;)AKH$aO3`KK`yCBwIQ=+CCa;Br*&c>* zhq*o=rm$k8IBKII`-$M~WS)ZswW(tV#{n=wO{90uI!29|%vdUXO$E9aB!Qt7FDnm$ zI@JjY;r(!#mnh8IrhE2P`|+Z}HSySkN5PVS>mr>o`~$hG!fAp7t0d0}dei3d%;Q)b z5e@+fI-P(|LRO4LS|5b<>rq`0Rv=3vh5xfFT?7ugi%P%DU7eKZVXDy}^ikS;C-{jt6f4{?U z0O|f=>X+3+94*$+8^aX2&vDUPro$U8ACQ}KI3;H$*;_nVhFYIxg72uChl{alf%)hPBC4#uHZ(3uy7cN9Mk36mf$1)bg< zD~uR8i^`tUa}iKHP=$b2$~qYYHAus87ek?3G32(nv=myxV>ArdwtS*FAAB1O-q_+( z)&X|c;i>^s23~Fg+yl9a(6ngjVamcMfcvMkrsqD*jKaUO_06r^@<2;cefVg?hDyNW zgBbq&I^viJG`D0QodI@zPef4kiG{^&$`kfaOsvJcWB6%qKKh3(5hG;5|KrQ^Tp&$1 z3?(Gxnfdcba6h^3(2SJJ#{|0TVdaSn{L~f<`^Uo zWF^TFEh>1vea|4CZ+g1{9>GF4QMPI~FLuoxdH(JUCCEX5pnqi&>Bo0TcluFj`E%@- zf&WaYvP+CjM;Q>bA*J!-tcI*v7@1OWnVZU5Ro2|3 zvndn}O?in)^*?V|hCHm!&8Ip?;%bH}Ln9j+xMmy#G>Cs6@;d8&#{PNJziJE?8@^P0 zoZ{Omn6`J1puk)ps^CS;{NQl+(Yjr7Fphpd{PFph56FCxDZ8j4D{~cuK6#@ ze+hXd+otBlJDfoXoN>Wu;sdZ%LFl%u`nRZM>=EM3mLeW6aKdUZ1js@DmU4fdy%fHTz^Cs#LPWMDU!zrvQp_wi{|OA@z+S$o;3Sbv zGW!_b|7AO|`X5z|EH}v8rT~F5E;T;gn`UPJsclvqJX z)$=DlfS*Q7KtFd4w&!VuPX23`$iKU19tZFiz5%v0xn=NTNNXsA*I5(>r+$9egvP^LmC`xppBVr)Eb z=lk0dMoV8t0AUeA9b@(o%^js8_nRyRi%oAfU+Up3zj=p^+5r6hSKg{`%W0k}LRH;^ z=XiL%AoPVgBe5P}3yQ**#~)k(2k$>;WX{;w#Tz8>PBI2G)*b!3M)n( zm98Qz$$l!(A~Vcm>;?-yCno{qwxK+RD)G)B@5#QJwr`MH z)9K5NIXZj+OL}O-T+rRksTxXgYs}7C%wh%>`nQattVO_zBW?%J{HXPRVylo;1vHmC z_=><}wSDdJ*6_0q&NA?uenm7)pU}skCzVWJVSH^L&LIkMlz4bXRt0cYNcH2%m7Ok;rU`|VGW~7!T~EySB?H8bfX)iaqa$S zzOZNZWFf^f$Nx|b!0J>Ad7|-&KOzY1zPQ-q2U!yO0;l(7z`QF6d?aq?uyALx$&pvk0(0@;g16ydj1T=Z;(uc`r&6Eg- zgqH(Xboe2%z60a{(^;gfWl`uBFb9|bg5}v%7t!w@1z-ti68y;)+nF{_(I`k$uEVW` zn0Bll{l>pg6M8ibV78h98XRaEG$V>_6U06Q`RE4<&GxP!QZm3x=z-+5RrXFw>Mdf! ze@g%3F!6?&?sg^4e(JlMxU-lRbVkBO;cfdNhACJV$J^@*;JK5 z{*0Mcbw8xjeKbZDO<|K2s$iv*Nxs_y-QCbi|E_sWAIq(=_QnAp=3W^w42)nBV> z-KM^#NWZ*f*%-b+%-$w(1<5tk9r$^;{!ZCqk@_UTFjYY-QB_7LY$nJIihdFt&K3>< z;}WXYd1TbtQfm+lrB_CoPR171M;iRvHSjCC96cI&R&Oc#PDSmUfGr@~@P9>?vLJa? zG!gFAD^4!1im53BEG=9{!}3tRg~peKaC1$LpXB-=7JsIn4bKh!UnBT>G8*9#pc9;! zD6?#J&H2cH&mcz|{XS~FW^}of#9d6_#dF-;cR!qr3;(N+0_ppLqa%MU<+gsX+Jbbfq(sfe$Ls@adZFw{C)@+CVO0t$Wn=LvUKtu6>4)9PfaSO{Igv^rKIy;{gVCT1nHp!tz zMn>QO0scbo1zhP>#A6ZDU#nvjTzp*BRaJU!z2mbvPdk+a(Zk~_c4`}3Ze3y|R(>~@ z@EX@S#J{95W-b~P7Z<-?^sEj)2WhBjl^w?s*gH2`17$>IG60t82*mn!#OaOLrAN_K@S50citX+zk%>YYpeLv8jxG(0hnR>@_V7T${$7O06 z5d}I47#F?1Sw8ehX0+@c*zEhp?*R??%a?1`DBfy71vW8RUQv9uUucX(G%u1Z@-Pd| zJW{clOwA;7{EIZ|>FYk`8`}!--8n1X7JrBVMvj^J`9)E76css+1s2VSblI+FbNwvE zyn0i3ylf{@TU!AWcbVA?cYpe{JpKcJADb3urGTYd(eJ}LRs!nXy)T(e{~ zt^QJ_9)?mfl{ZCo5dTwdMEizeC;pf*3Hzifv&Ds zuU=i$`5KGTb6_w*Tro(c8C8A|D9xXOY`sky{3l~RRCrz<+cg5O|74BZ%GffuBr}9u?v>Z|E+Nyxp z5le16K#ofFLTl7nw+GQ+_zH)FgkcMNof9-o8Kl{wA`${7zzBK!mie@H?rxUo0kr(b zkB8$+CR;pGK(cEMWwFmf%6sWQhTcPhL-p&_0_HI$EHcaB|@fvCB`<&NUDeQ0qgZE@(-_v&sqc^DS(syqe(%x^<1hhJ# zUPkYeFh_d%b`feedr*)dc|t_j~_@hwW!y?@cmA>+t%Oi?gNV4 z@bK{IbU6v2i&pV|0_Z9fNfU3urIQJ4nGM*Z{~#Gqpp`4pZrp2Cjl8`mk>I`YyWR>C zZ;#KKWUBjvQ+W>eUGJ7IJP$DlHPEd%KL$ebm6-0;y>za(={KzDln_VUZP)d8liAmW z>-7JvR01(&2Z!r?8qfO!O$O0q|9tYsjrH;Ht$T>T zZNJRz(CdEFQV*TNUqB13_}PcP90wZzZ}c?&>i_j!L%4v6!Q%55kL(4NrjsgmWH8n- zZ{(5@`2vn6>+fe6C>`7)TxsGWgc-)l$ZR zjbcWxg3|9v9Gt2MQ>+X!|FvgoAbBMivZNH|X+WZoR&fY4xk5s28DR^d)izNx8>Oo0mwf#F$HRpQa&W&8G~jul|97qY`yg<4qu-g6MBp_tG5WrY zmkZE~DN;I_s@*RyEy=*c5gmK;=YKV`=GyZ=@Vx?$*Pq-I&H=}bSojnZhbuimeez^_ zZtkAC4*X=cw~TBxqj(XRrxiJXuN_<@`rv1CW37 zEEBjkU{tn|qOUGLVi|<=*Ex?u4)rK!# z{BoSG>P?^%vjB_{$Cy`^j1Jy_f~N_cE_zcKXo(b2+vV^1^XJebnxoEh=Y71YrYA+N zb}SXi=;Lj63n!Nc&p`zVz_&2+;ybVEKc8#{0}q^c76<@T<=ncCn%V(lwx!bf^A|6C z&K^ta*^h0JjeT%PWU^ky!xC^C9`GpO-|dXQ-aqAIGIW}9q);-|Is*~r z1SgrLQ>k)WXXkV{E}0YDa&v3z#`iQoIpI8yq~9#yPXgGS79UrGh}X!$W^Vp+qVEit z4GjU=&s=T*;=qFT0#t13prfvScu^LAAYjv%b>KsGnF&K*Sy|CDGz1oZM-ih=(S*Zi ztAGQcF~=SkC%?@DG>(gDG(*8_WP9&>=Fu-7(QkdaeRC#L>NZMw?Xd;DA7fMwz^fN# zj42+}Mmis%gBOLZ+9vPs zw(-b3m>g{Pol(d^w~0ER3P4A{+rg4k3NN>c2{@~rJIMuu+IoTBLQB9!R0a&~eujYK zCs&(4OSS>Ua0LKUUL4NLR|5$)eyf=_4jpmSfel%6x2M%6O*hNzGBu0^*eQYzL&L*T zxd3W%amWi$z<}MNu1oQ+($tZ_&>x9+CnauCl<2$0GmX_HWVpH0f$ndZj2FYnr=<5jZF(&%1pS-B0*1g>Ep7}A9Ti>uTQV|71|9EXr2;5gX z6Ic9oPF0-L$r4@om<%AJy@vMZH~iW-Ph0`>(ln4KMk%h5!F!Sm2-{6;VeZJ)`>Y>) z7^oYFtY4zNgF6B?oNXX@OAiiT$0Br_NSXt5ntO@t%Wm4*3B-~600)0=nIYb+`}FA| z7R^|}=+BpiuV4S5ln3_aUxNBzeGn>mX&0G2$*YYGp8?_*vySOtg-u$b%*;$--(y?8 zz_QC5P7hDW&4!=%?dZa8NWv)*U^=wEXsxJwmN*hK5ctJ!EAcUMl(6Gm7#+aE(H3!U~0v6$vqJ>wj(A)XW zqCy~n=sv;tG63QDQ6LU$2|$bk&1cRU&ZPW+)AO}(LOW1sx&{m^k%Tp)dquywmN+nf zd%dvCy*p35+qa0@@5kzM+|jU6lNaIv5|)G=Cd^XUv<@X@ZqF@Ed1(aUSsjVcy_p3> zjDjMT1+P__e+Ko!ZxJ9qna`IbJ~?Z>>!Fm}6mB11HX6gi-ic}hLz+|-cmOvv?Sl<4 zrG0*ts8QLq?n-s;yE&&f)nuC3$AN(})N!x!+J-8TRbCvW;mVxGOzr3mjZ zeDNwR;C4g!XDwpz+8vp1v z6WP(Je|zq7dj4$7vHi~#cW=?!yCy=m^G^awzsurbPqih>ax&^9+IX^w)f>EuX&2ic zFvZ?D(e>mPy5kSOOr4~ zKS~F}7iaK^PCpNax@zZ2&)~<(y6c)0hdC-jdwOV>WWppb6x$%}h57l-vB|RJE<2LM z?}o9t?%RKt#gZtUoWKe>#908QhmK#G^u+p4+j1@v>4E|}9G0mCcWnSNB#^eBlpB7H zO(M^&9>6Xe&?F=1SJ`XopPTK%SiLlJG$IvWn$Hy@t4M;Vu6V`%YT|E}(Fbw2biZAK z`h%Q=Z}=N)EggmX3s@Z*Z!&QCcu*qV`iGEDl<_8_f6wbsF6K{Z{4wf2ePcGcm9xzD zz|2OfAZ^y$Kck1&(h`yYu_{1;gy!70=K9DS1K-q*2RjZEXT_DbQ`zS=yVssIP^f#z@cOT4cd>nKkHc6C_jC+^q|`4gzrH4tQ(V`nX5Ij7MuR;WP+h5GxzX29%I0TrRz1wo7HGmR9yWb=Qys=z5mm%&%K+*CD$J8sVKFg zi`Nx|9xHU&5>t;wB|0sS6Vem#9-y~9WFjXibKLU$iO5Br!9~V_U9xcnqShDK*42B2 zl?lKNuwTa!H{$1vBhx${NMADm-!?->2Ly|!RQ-u`aR`h6{H4i4&IIm;%mG+l848>8 zeQgcRrj#>f;OI=L6E~`+p>gt|iYTT03p z82add9v`x64^rXa<*fn)rjyKxk`|y>O`+kxzBR`@?E6eEjv<+mlJd;qVCc#*giJ=A z39)k{9x(2fN-&2<{^{MAoH|)IrVnD>M{i?@f~t zsBr03AK_;qe$Y2QnlT{@?+s>cJ8zJDnuh~)y)E`_2N|yraGocT5VAn#BCFR&@7q+M zb($Zs(aDdw&l>8+d8Bz~T|2C%TiTBtF2Z^Wdt=fHv$!Sv_oFF^c(nftiJDhagu%5@qLGM)v$NPS_jJ7MIvT=v3quRJ1Wuh#i`Fs6sd z4>5{IE5X};>i?_1W<0>$jS^+a^^&K$BU1TlJB4rCU#m#!xGPK>IWnzRedFEjayG42 ziW_lpy8k{+*z1;V+>Zax>mRSTkNO)*d+$y%r_bK@W{XVgl>~G-=5GD*=@zcPF)hxY znD_hKm-Yhwh0I3gGWTw#T*c;$Atix83>~z=zedv`nAC?uk@Hzn@M77kt0H-g{Y;Er z^3|(5;M84IE!y=(8d_KTO}Jy@rFa1D+r&&z?m8w zFMl?ccQW|>o%LCxhc3i>kr%t9;yh_@NJZ}m*igkSR>{o=` z)1LhWLrq=_J*Q5p_1Mz8!)T_D$&tlQ9WspWuiks%#z%3w!rF!Zwo5#m&KPi>?0v>J zNliA`NY-`QjHQ%hO8Y&Z(t$-tO=CPl7LT1CqFu+rNh?*CnlkH*dX5Z2yf8=U@T0vi zANDRtZnc@C;d0uysIB0x=|-z|oLQjF%E-2zSW?u!n0z#D=##i2#)z5n=qzB^4?6W? ze8AqmX4QDUFFk!SS%I}GU@Iei-nTr8D86Fxrd{vF0*#6GIiErK0Po1ysaAEzW-jAf3_;<_H$Z}xTT=AK;Odq9mL#EuAc#| zh{a`$tK*OT+r)PlUusXy8@&Ac`|9SZxytSb`Hj1iZgiZt7dHlIA^kR zlXKF!Zu?7Y3Xw@5Ef?!drc#iCB*TKnCAGH<=IOiHe1nw zQmS>ukKr9A^Gpggp&hteliID3vu1yK0*z^P>v>9g#-a`ytncJ%OP*mU44vIp(RCf6dR>BPTRO#LOBz$`7GJ1#%}?K*5R;H?eumUDo&ZhH2ur6 zy2#tR<`+_V^@SIq#-6D~&z`Au^k=KJr(fly>+3b-gXlielcuDg-o2wPPO(j{wjxCZ zcZgdC+WvJ*#Ic-S*IdjLhsUhlD7|FMfl6{g1SHwLtIWQ)j}nly0^TI{7=V_^5vjug zKMel$#eT7-ts*)Y7sMcYzF%uCwFS}2icNqNDv5k;Qdia&O}C-iqRC>l`T4;)TGG4E zoUtG*0qdo`BGH=Ij<|t$A8dKThCe4j#5AQL7C48?eje7glW@rwN}Dkln*@STPHnTv*6YwGGINZu*N0$FV>T5-Sg zT$K7bLqq#zzY!guAWVEs?bhd`boA{+2cs(oH`Qkq=%dpWlMoyb4I<(?974zB6vmN(w z__L+7K8BN{7i&AIWO}j1ysnnMi`i(jHi?DCuM!=NEOCnysNsKqJ&eFdr@U^##S-^} z;9pZvH%9ugr#M+Gw23!6KagvF^e(0kC-6fw`JY(CyvX#ZMc6bo2G4q(87)S_(mDMR zZNuc_2b7P)NqB9LIUa-#!G`pW0c?BQYR69^n>J&U%op^l{?@ebcpX6x5-!^L0vFn8 zoZPbR0Gru~eAF3LKg}OykQ(<3x{`lEB7_&Hz~FppQ%2%E&r=dmt2fPk37lTS^zQ37=N;k;IbHzr3C#d19jad+*p_=|}pWB3S;YhhC!S z_AUPPp!?_-Q4PWnQbe-7YkZ^7IKGsNYyLD}Pt5?&(S;F$vC1p(*EFx#7TMsM^5=v@ zJ@!yOp<2sCI_b@}6k4i1aY8n&>~+-gVL$*WgmFf|LK0H!6wUB?p9L~P(60@`I>U`e z7)6v_?;Fks?p;dI7ji939_+UgU#$r@YWz`N18rqmJ+LQ2$NZh1W+U}v6A}9{Y}CS=c6p#6lHph?x>a|N{6QXK+ybv+K5(Y#@9Y0YA&q?O;KB#)nJajT4#O|p{ZOS3DCyjCCW2REZ$YLQOaXFzjK2&ZN*^}0= zkFEMPaFLOdj@D#}#uojdhg=VhFQW7}x`&l@Lyjxm0iK~U3q|)q^z#5%6@gq&>dlep z$qBrb2;}Zxy}KM)lbFL|>vB!csjBiE=jicBfB&n2Id4QiVK(3>z}e$R;Wy95cy7w) zjKlGBcE2cZx5Yj@3V53><}p@#teNv@@@ZC1B3k z!d$voo^y~3l;$;Bwp=M(zRiCa*j+&VV~Qr`c1sUsLrMIw$< z%V)0$9?(COs|l++;lu#GnPm06ifo}a!0+m^lRWIX=^c~EB=NW2@{(DpXusJbgc93{ zN+X?Hz=XS=M9MgSSfZ~dK7%6kHQ?vCjfjF)J>A3AeR)1kMnZTd+(tw}ruYhZ>R{1s z9!F(CmE39-bxgW+tMu`E5Dl9XX}7(jXK`JNi5oiRn{0l&nyEz|?$3Skgc?NY>E7ef z3J?JX4%P6CJ}(3sir_eB(9&^JMuc3b#BHF4%bK=3uM^y(l>77VqzN(Y^DNKB z&9;M-+0EnjbjQBO#VBEao9tN4>ZY_I|0e9V#HY(7^ASp6IjmsznF~_dI{SrdNs-@v zo-pgua`%jLt+UGbn+vU@Y3q&mqNZM3wYz`}GfKCuov24xUH}eFJzMp{wG8y!n_ZeI z+^AcU@;tf-V7pYgM?9HQ(ViI#nL1XsUY$*@63Kq7`!i0LbyIiWP8a;MjRYq{@Q+8e<)l{8lU zM5?^ml_P7#d`XR>?Fwa5?Wf|tpI+xmS%w$R?iRF|Yk#S}%pWDbG{ed4^N7EJsHSB3 zOTj%BMhd8+r zo}teWk?v>EZ=9;>d^~OQp?b;&>g@5#x%vWsZBojKh^Y-8TKgrrc+lT%&lfpT@yBHi z^gOECru_&bLp0D3{>C{2@j%Nngw+IaAjo8LX3PIWd_d?y#aFiVof<@wvwSjM!&cAX zw-bY>C^CD;278;~?xh0kk*cV5DI|>1cRh{h#o~(6K-fzYpLP`@rWWn_Q^*gu zHg)OaW5KF5RE_H$u3Sf0A`1y6`bG50d~dq=D!P&*<&1JvE2C7Csn ze{`9iA1Wc-pX0lWYglFRJ@#0*{cM@9&a1(#o_c{@mdAa`PdSdxX~|f0i#>O8K8*Ug z=z{OfZ`!5g%w0_Aa&5Frj1y^>Qr`~+%sqIwfQ(7>fh0)AEK4UgR`P7bP3O`!;MrHL z-ItM4Wuuo8j7_LlUTX~g>@^*W((rb0uxxOa+2OFEi&Y%t%C>MP>YvDpCkLtL1ZI-7+wZ4T$kGm#f^nsT%s@B9g8#cnP?*f^Ql zrHO_~FOe-dj-fJzuX6MQ{dG#?C5Mbk!#?-yc~qqGxhMZddBZxe#eUkB5@(VdXER!^8&%JU zss`T~mL2K{e)i%C>zBQYmQ5v@uZ|3^dA4WUkv>bOC-Em~-4%EzEy88@cT0Y7RAc&i z>38R23V*7f{G#*T3~)?uN`1q~*tk_BO>2qjaOd}~%*)F&O=T{?(I8F9T8!dZ7_OZb zqMB<(sfD})dkqfPa_w9_$u3yx3q^x5`I3?ruAy7)2Ei-#X9C>Sj2l5q&Y>R7UY>j8 z+H({k#%C_IVzHwlMcB=!yN4`u>)J;3CCu#7em}nMGd4+4j=Vfi1#)8kA?UzC7?lFH z8K!mK%@2F}r}8oVc2ox$G}P#JzhwBJRHi;D*yc?IKH>D|&nKbBITP$yKF0ZL#?QC5 znRwlLr$?lPO9BLJffwFj<;nDZ$meu%Uun6SM$|O(NrzkU@$GpYu6R!S`Al_5{S`eiqU+%^2 z=l0y=ReWs0;rD=pNut`#j%$t+8FX$*+~Q}}e@41b!=Uv8VkA7PlK+>f#KzF>8o=)S z<5r05I^Di*;T<2H!Vm!xNzY35-57|*knP{drK3rMqnsAIoaZ8%W%t8yh%a$h5q{5p z`(Xgjz)3d1TuGtwAt3=eh%J5aOC%d@MusyN)O(=6TRxlP1d5Kr(@;;CGTf^(r+m$K z-fh-icjwJz^A8~y62dyLTIZcWCuwFV-01vbO?x`D#%+6}6MAB~h`R-?%*UyEo^2DW zz7RHV-uyloyqTyt+nnc5v#VauEE`5V*vh`7cqt)ou%}KvqY{tMtJ)ZL+jd#A|FG2J z$_3o|Dy831(fCdM+?~xZ_5WD1AY1~MY+s(2CBI_^6Acb->z(=Ryd}kd2-o|CDZ43&QNj2sfAsakpEGn}N_tN#$7%S+CzsW*0*6*Ej#e*(eUL^r z&+(x1j|L6(^wJ+tQckzUkk#Yse9Ie_wJPrgh&jVr&z*Sc9)+~Ve<&vFxOL{us65!Yia3#N&>!I)gSr$<+LRUP2eIF>2D5~eDLp`m^FdtGs7~v zM!#_B?S)cqPycGI3OG$B)ZzE@zwtE$;Fwp)?msF>muX~Ugy9>51%*$)YTVYQfO;TD zp#OLFQV^&mmOkoKiU`IADq@ZV0eh$QshG|yU;_)oSWwLyJ`uV$F{2nC}_pE2hw?cfE0pFq+`h+Xtt1k z-}dGKS6%GXjGhwAch+}{N9O;uciqu&bzd8qFrtkTy$qt{B}znR)I_3_U@$~U(V_&A z=-r5(fH5?WbdjCJlgfPBkC;>^#*x+Rw-sL3QF1&=5DO|?Y?h`d{a97mE5%IJ7x#0MM>gC1`NVjP3=B-|HF8)y`!8}^V^dDbPaSb5 z2eqW8Fv{&aR|EOIMjpcI%&eBSiCsNpZOqU#PijMDIEU9adp-`^5#>EJ6$x@Rx>?MVPVf^xx!8c3estHs6MahiRGR%#e6E{3eKR#?< zWWP6m1>c*f&Pz0QqQ2_svU(7k!X*dynVeJH0wXJ}9YqxL>?I-jY^>p~!skkt(!bNt z()wH>W$uA`0MvjEYL2`E5oK;)^f{&<7xr2H*GeX@1UQQ0h(HrvsWApy$ zT7_HD=nH|aD)e@f!)j~Nsgu%g+*@u5KS(UM1M767nO0}5&5pUvJ~F=AhH=GVF8q#D z!N(aEjv1CmZ271H3GtzjRrlU$Uwb2#q~T``Mm6Jq=T(e*P6`iZR%+xMb&;kDXvNPC z2eeAZiDf!J78P~%-Gc!UqGYFfeM25<+(jZcO6^CdUtQBovIBB*g)I>V(`)7TKz0U3 zZDU_`ZQ#*U2e(clFSobMGZ)qiBOW9lFJjlx6ZXcHBgDxVgx2Cl7}H8zXSD0^B*jT# zVF@y>yU1$@d2~o;itP2)7>;rPf53;UGn_KHVvh-Nja1c{^(}&@w&#acR8$O@zC$Dw zS!g}69DF}Ip{f>Dm!>RTpiynV#4hdKf!f8pRyln+-QLx{et+whk^Pqok0gW`=4TKJ z_fLPG6M8SA;4&Fpj<8s`lAFxjFcMd}>fSe8<5&BH>Vhi;#WE-d)7VW-IESNh^D##!)muq3 zycfAx*MX>u1JJR$T;+vXF=RJi0SF6}4WV_gbHtQXGxgZ#QToBOGs?8@RhnetnbGit zX6iQ^`@2mFrWm4{+4Onh&jFX_nY-6JAD7Hc^ptgkr)@;bCW(~DwjbHz)Gfk`cpP`{ z9q~=C5zCO341V+ZyT-=q{$|2r#k~<>xq>Q&<0;43`eYnt%H&b~8jhWeN!2e`r4!@g zzL;CQ*}IdFnD_~GzdEFvZ<%F8JR@gbm`JYA_yOeWkgV|L$R$Dv`EE@+b-0~pdSXmi zC~MS_Tt(9|hh@F->8`YIM`^Zc=vf+`(s>f0r5VLSa##$d&7+Gx%yJEmckQL68N0ie zR_$%XR{D{<1ck-0N;?3lofSR9m6qv{XDj#-3yP>usj0F4a3x-NYja%q=v_JcUWY2* zu*Nka=CPdNHnG89vNqRD}aZN zGV5}bO@7#V#c+9T7C~grt}vY4biUG^Hh1#$+=WcKAI=v` zNhE5!93K55;%g4TIL|hW#0GRnrmJgcM176W{~}M=LNL*&w#(({BKj&LY=}R;N4HY! zgB~^9hU<*gD}#RkwE>Ip^LRJ4v-95{5=0p&-%XQoZ+pw4@6kyzuS!m26%9PYA7EbbgezyFZ3{oB=wO{uDm{#gp60vqg)q495&)wNLXas? zkY7_$#uBUf)B$QGYH`2Pecs!xxjyfK&K!F?f^1WLoTx>DX7VIDP{7JGj4U=l+;&lZ z^Y-$vJIkHnWXYkRogi1(OwTUEyN^FmLl9_?4?M-<+x4=p$qGEHX_KltrDb*5U2&A=9>u0s+TXj zQQv2|h3^)^sbzct%^p=PcL$k>&{f?9i}JD7W4Qrdt>oDt3vd7u5D>_FQuuCi*qc*n z3)iQeD);4-wptAPdN1z^Z>0RhYz2v=)2IWWn6Gb+7hi3607Yt4uurVoes}22o#BbK^*D!SKye%zU z=ol!8pKe)><)9^Z0syr!Q{4GQSFUS`wBi6)w0@t`+Ff}ZS=rv+?o*4t4Nya00lQ^c zvp+QCuGf99we&Fd70xuLT3;WA-vb5|W{f(m4`;&K_s3A+=KT@iev2cAOe}(d49+U)P!&Yv7T2 z7As;GKsS{qWl??ob)dxSWu$J5>WmjqcG_i3gJ1^$b2xQM=u?z?Oc4f7DJTO;6C}Og z?OJFc;aD@Qhe)A&<1KRldIaEPu}~vrGS9f_JlRMllbhdaP*lOR^l1PBkKYb^gMDNp zm3TkG#}D9cJT*EON2>C&vtL8f!79DhcN&S-0Mx55!nt-INcLxy%W)0jj2`|v6DYzm zV*G=<`rMguD=>;R=Nvoci1l>_v!KF8N!BIRVhfIyptI=C72pxdH+Vi?`BacDjYiotDd9H`IN%dJ$&XB8c zqbl@coflQx%JaWQi8LW4$1SD5R|;b6yJz9NY|)fSh>f7Q%GJiWh>oO%C#dSk-e>#p zH0t&fYQ}uhc)?}Ij-wRknH$fT}NXCY_Km*~z{!6k6V#5pOw+xRDf5wsEeJqQ%TK#s^Je;y{UX>#+Uc3;Ll<9NWV{cue`_om`sCTOW^>=It7GRm zz7})RP?PyBGx%BB_vNq0(+~%!DL2X>uqo&HopR%;)9Za&KJ-PyWhenkbmj<&+|E){ zi}LK;h5Nh%XvwnY&Bm^U7^^!CA5;nnxvD2tURO|yd2{JHJI&kOdE-JvQZ9k%r(~C# zJxe|Ig>LpS{*+igc{>%G;EA@75bO-a{4q0;;7p-4@m{ukAP6*0Aw!S5{;$P%zuv#@ zvuz>_NL~pya_aFipT(YT5fRxt!I}|yw2`Dpg{dgHkUv~eiUvMBR^~V|m-iRi7~9g~ z6Uo9v&jzE2XNHm0NtTJVkZhI$v>ubSJD!3oxnd^h!CbD9Sh6Y0R44*9w$ zZI#3ZDl(x%u*|Jup<@z@-dL7E7G$mSQ4CN%-1h?Act<}w0jV6x;WI(2a~FR&X(*oX zghR_m%^d!$%&!@LK&^ep@?HKnLx+^S5D3R_z5w@_^SrpdNToz&gq7w ztW}r=o9wNxg;1&xj`Ht0+9!$WL+G+L(VT$oGnP{@NHkLm-T4}!sJsT_A}yC_*|jj> zEoMoJBx{^gQ9P2XlN>W9dvy}ssj-(ViEwJT^E280qY@$yBgWu^1uFAvS|&`+J=B0T zJ|dVrBD(UFWB0WmjU#j4nP$@Xgqc*Y&Z;`gke`M(1L-8mN57 zM~oGA*Dls62sw74wsWaM*x=dD)49bzk;xEj7DD}g!+qfgXIn?O#rv~~i06-;-$#}! zXtIGA+`kc`6ECZaPiw8=sZ@|whiUshQu3F+#po2|{<$%PY;-X2yd`T_+e3j}j4YfSGl^ga z!0n>O#_&${2eU`pS~>i_=7~hEL(PWAoPaK~c{5VicYk|qTTY59o+p?-4Vwx!Nyi?( zRpEP)vg=Iey45_;_*(Dfn_h2_3C_-N$T2F|up%L&bG&ubvC*Izp{)Kpp9X9XfV!(X zjm)*FS}2l=#My+B>Bq*$FOIY$q~J(ZHA~BM4|x?>%FTQywodmvVE94z#goG4P(b!m zI22Nq9XuDqzK|yg^!^@aK7T$4D04Lru{%KKVkS=lo(r;?gP+?I79c0$=!QkY=#`0; zRzaR*0Ltt@B>=JP1IFi$OOX4u{k`2Xi12aiYofxKj_(Ss zDNrwEFu`@Zm^~{lKJ9c|`BS0r5cWjaE1S+_=`zbE;&zb0$_QKKKd?-{;&LN1gGgG7 zVRgg_BqPa3HX6+P!cc^q|FY<_)D1O8Y6<3sclWObFMQ0>DLFzyi5Hc|vSGRq%-BZ~ zM)^M4g__RRULdX%6cA`P^+d3Px4yc?jh0eVSHG)3rF0D4x(w$Pl#N`sv=jvU!<9lw z5mv^T>$^LDc?eX$=R>Hi!=&PU##M|-Untf-0K}NzkxC`>x;=IQq2mF8VH89WH}`*8 zR^}OT!GoXCRRstofL<1n%VP4R9A%IUBt%u_c<@A)jG8ErfF!b`kr0a z0_lyLU-AK)td2UDfI)Ueb%$DR0*Jnu!(FsjW*=Yo@P4U%FsGj2%&DqlHm9ySPE5#^ zQk3gqcwG5H7*`yJ>l$qGX_eeS{DTLdj#APy1d~nO4qTRiA8#QLb-WIGNsneySTS5H@xvpVSGbpX>}WMmU8)(3rs>WR!{pM_czN2o@duRSAZ^n zkf%P8sb$n6PYG>d$;s)BIMXG+nam&w6M^?~V-bHrYN2B-c$PA5XDQ0KKm&fpDcVR$ zD{|`j{xID>O-$REgW8E@Hjk=wl_`ubca1wdy-8Hn)%tR0`fm;v7h)G$Fm=)HAzUKk zFa+%g>9Jr$#;56E#)g};=rG68=&M+s^8prLJSkyDeN)m5lYE6VM_X5zuut>n*8sEX zcl1j;n>@=^S)gac_j@h=wBv{=a09Cy;&-19QUcI5ih>B>??Oy^#ajdkhijDMUXyH! z9LxeCHTDt_^Azph;#oH%>TkeB2>Dm1lBHc+NXTa$H}kEYXJy~`s={x}E5p;3x-l>0 zmq+{i=!gh#1`IY@A@TH^SVcG~tl?;)+soqOVzmjCM7u_X`+-|G9EFG*!*+ornxm%n zpn=Fpb=?o_*sqaD0Y^;QYNGc@^+^m2^s8|Iooak*A1n5|CGgOOpDyAvOooov*)}7_ zZfG?r+YKhMYmw8nUnrmV9$2+tagc2&%x6EY4f9m<-@5tZ80PKxu&Kzpb>|vppf}gp zTJtZ@oC`W1KYS46;rVQ6Yq9V_A z|80&R-asz=oZ=rpsm~+NaHerBH5yz2q10+GTQgOAo}j!H&p)ptP8*QmKG^GiJ~(Ip zjJa^9!0m>(K2RQttN?=KfARU5dFCtm_kmY6c5x{Jq-Rynnio4<&PK3MN;bRYuNgB2|S5NjZ!>-oAZnc=__T zQ}W)Yv%>Gen~4IRJv#v?a>c-l^d~vhGLa?7&GupYSyA3NK;>#qv@tv|{uUO%P)T(f z7#ILD*gT6rL^PBiKN58LI(0w;kN?$GsCNJmBt)B<4vo|EhIU5x@JUM#nD$%E7Q6rb zYiJ_bFe`KXyKNI7;Et<&`=}$+f0lp%5pqFQ>5^FMrnixi5sS6&r_j^co6ogT1Tb7H zAd~N&Cdm4D@*pRmYVi)vj|)(_Y;61`PY%dbmpphtH&o|WN987BQ<_10Xk&rZ^FXnK zjAPgffr?yx1cI+9(6Ry0pmIS2rDsnbKKi|7e=hg>acZpXL{Jidf6V0N=XY)o0oETV zl&68GEz&-ii=V_kqzt_I<&v$FQ#r&JQySUY+Ct$PfP?dX%jMmle_&L8?fflh=nvxK zJp-UrQv2)IBEeKs-VhHkPbu#5t4gBZG5@c~Kal|iaqws*=;`Ud^E>|i_umqr?~?4z zPuR3~FP}bD@d!Ws?25s(SmTK%d}@1w@V2x!D6vo&N$O)T$yCmY^+B|J+BWpt@VW*A z??d_#eaON`S6tGy<|X z!&Rk#w77VV0%UWBV^)>OdwP3KR8*RxZhTky?caV))oIe^+$CFE+aj=NnXNqmN6N3M z_ukQzId_v~=CD>fdJhhu>nP#a@`WXl!f?*4N8VpFWuyQZ!J3X6|!M z=Ai4*>yd@{moN1Wz0Jl1Ma^RzEt`mI;qqnXus_N=U~?nAPE*0=jHr=R%W)@-iyi z-zK}D0H+f8nfxv5H~%qb#c)t00qP)PyuxSkC+~)TOXy;mT-3rj{R#7fQtM@B2jK{XFU}>9Ua~9!%~u1T*ax&wZmk{ zX#y_Az(0rc2>}fUpBfx&sg0)_ObISpGzs~d78hp;b~_M!v3m9D)#&$+?i{7v zn3XbK#PSPRU_P;djg3|1cwHZK1c)&rUpuQsv&JnE-aULbRd_%)11c{s4^Z2s?d|PB zrA6~wS#MG$X$y&{c{T`ZB#mbo4~+&9pu~k(ZzQqr0#M!RaiH|>Rv=1C5luj1Y;1gM zZ|4s8<$r})&}IvGjRY5DfyyaaT1ST_NYl@|=bbolqJOx;^~NyHWpuJBkuw)irT#tF zVA1Iy=R$Nq?%`p4Jac2%me==th2NiLWwE$!fed@A^V5reY-xaY(mUlnI5d<8awlCi zDi%b|I+rg3Hg@?MV%*EH={JnctAi<0}Z3;Rh7xrF!uDSdkO5oBB z)YLAQ^eq1| zqFqfeA}S>~{Cqv^nU9uAD0vZx*Gw!e1Hhr%R8KF?tm0;7!NA<@KPKFl7tzy5l0)vg z_-STl`w1-FA{>7~OKWw?8<_X2xQ~#^%&$24$1lN>0RYSaY#8c0vvP=yV|aKtXAbG~ z3a2j7>JeL1TCAnPxkHck&Iy)bh!=Uo-^)I|$Ruue={zAl9bJFNBQanf;^X6Er}H}g za9YYbNV^a!y}lPYIX6~5y#XgGI{llGOpoQg%0#8-z=870I_XKXs|V?pAMZAu4^i3} zcHvynchGe32dW=z zz*FkPGSBTiOgl7itl})ZIZP;L>Gc=TW~gOH9((V&fFZt~*u}+#QYfLNKm z-sVr&vxdMjPkij{oqk$D-T%a%tDbP4nVEU#df$!jzx679-5DtXSB-)!Xo=tVEWhF! zuT2v#ukENodq>AIC@L-R+qDNiaVBd0KVpho(3PCt?qDfGfrpw}YZUW|VK*(Us4+u5 zy$Kb}Sbw&{p#cIMWT0ZVriILv*NBLi7)g|qHm-^@G_fnIwssU03T%K4-i%KN`L}++ zn70Od%r^}nFmAWM14{%POkO!90mn`Oq8%tS2cd-TUTSZzp|x@K?IPecw_L}(&HpLe z{dC=MDk42@??o72<543VR9izxz!`?epr$TBdmx2_1f-vMLEEJy21$V9c=_Rjz5>%6 zV72cuWw$#2`#w8pb^7o__(CP_G(D?ziXA#hlLQ~^fa9YMWS z0&sGZL@Wby<%8T-=MH-!=PX!;HXbw6R^{Sh?LMB`+ui*sPZpOALq(+M1AwR@OcfqBi`S?YPxRR8`9+S(iR8A}D`5C7Pf1klSaY>s3W zZ@Y_WE(6QPb2%`R*ixl1uwLdO2J^LbyBa?kF)FjRnzla-chzEaSh1)B8N@9Y6gCyq zV$c8rIPn3rw#j#fBT@epqkg`1t{}y3cp5mmm=?SJ4HQVcHh?AoV3Z$6xkVw9Tnb{owW?Nbey8A><0@5LBR&UyJ2f4XR=hat_$W zT)9-D{(~uTu=R_ykaodT6PbX(>~up&bv=y3*9NFj@6R12n{t7K4?s**ijfq`s(Cun zHiAom(*2wHF0j-6IG3lVFt~Sqt!=ASW4oPYPGgH9oxp!CRLrE7fGVv*=XKyoeIsK8 zQAN8=?|c3oj;YcIaCY8&FTJ8r+%|HX-RWwwZ@*Z~YTm z>|YaNvu6wl{;-aPC!SD$w=_QW*Mq}XDDs2sXYjq}D}Oq24N%?r|IcIpuguRs2fl;D fUqAzLY5&L!VWS#V^h_54__}abTQy(VBJh6zxZy@r literal 0 HcmV?d00001 From 37ea5276de800c9c2591fb9b0370f78729ddcb32 Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 05:17:06 -0500 Subject: [PATCH 05/22] fix: upward-js npm misconfiguration --- packages/upward-js/bin/server | 2 +- packages/upward-js/package.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/upward-js/bin/server b/packages/upward-js/bin/server index 378cb4cfe69..74348e2e845 100755 --- a/packages/upward-js/bin/server +++ b/packages/upward-js/bin/server @@ -3,7 +3,7 @@ require('dotenv').config(); const config = require('../lib/envToConfig')(); -require('../lib/server.js')(config).catch(e => { +require('../lib/createUpwardServer.js')(config).catch(e => { console.error(e.stack); process.exit(e.errno || 1); }); diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index 16e1abd7198..1226c3bcd02 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -6,10 +6,10 @@ "bin": { "upward-js-server": "./bin/server" }, - "files": [ - "./lib", - "./bin" - ], + "directories": { + "lib": "./lib", + "bin": "./bin" + }, "engines": { "node": ">=8.0.0" }, From c8c7a5bd96159ccf0a687802bccd90bbd1b08e4d Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 05:18:25 -0500 Subject: [PATCH 06/22] v2.0.0-rc2.0.1 --- lerna.json | 2 +- packages/peregrine/package.json | 2 +- packages/pwa-buildpack/package.json | 2 +- packages/pwa-devdocs/package.json | 2 +- packages/upward-js/package.json | 4 ++-- packages/upward-spec/package.json | 2 +- packages/venia-concept/package.json | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lerna.json b/lerna.json index c2719766c32..22ebbe74cb0 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "packages": [ "packages/peregrine", "packages/pwa-buildpack", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index b130e00acfb..7e307061e6b 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -1,6 +1,6 @@ { "name": "@magento/peregrine", - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index 1b7ac48ab0f..999ecd6225e 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -1,6 +1,6 @@ { "name": "@magento/pwa-buildpack", - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-devdocs/package.json b/packages/pwa-devdocs/package.json index d96db4e45d7..8c47e9661eb 100644 --- a/packages/pwa-devdocs/package.json +++ b/packages/pwa-devdocs/package.json @@ -1,7 +1,7 @@ { "name": "pwa-devdocs", "private": true, - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "description": "A documentation site for Magento PWA", "main": "gulpfile.js", "dependencies": { diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index 1226c3bcd02..2673b4cdafe 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-js", - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "description": "Implementation of the UPWARD spec as a NodeJS server", "main": "./lib/index.js", "bin": { @@ -49,7 +49,7 @@ "traverse": "^0.6.6" }, "devDependencies": { - "@magento/upward-spec": "^2.0.0-rc.2", + "@magento/upward-spec": "^2.0.0-rc2.0.1", "express": "^4.16.3", "jest": "^23.5.0", "supertest": "^3.1.0" diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json index 738ee80c11f..cccdf55f471 100644 --- a/packages/upward-spec/package.json +++ b/packages/upward-spec/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-spec", - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "description": "UPWARD specification, guide, and test suite.", "main": "./suite/index.js", "bin": { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index 83aed6605df..1d61416cea9 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -1,6 +1,6 @@ { "name": "@magento/venia-concept", - "version": "2.0.0-rc.2", + "version": "2.0.0-rc2.0.1", "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", "author": "Magento Commerce", @@ -23,9 +23,9 @@ "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { - "@magento/peregrine": "^2.0.0-rc.2", - "@magento/pwa-buildpack": "^2.0.0-rc.2", - "@magento/upward-js": "^2.0.0-rc.2", + "@magento/peregrine": "^2.0.0-rc2.0.1", + "@magento/pwa-buildpack": "^2.0.0-rc2.0.1", + "@magento/upward-js": "^2.0.0-rc2.0.1", "npm-merge-driver": "^2.3.5", "rimraf": "^2.6.2", "webpack": "3.11.0", From d1ce4aa5bedd5d19ebd7de72859488b4d1411f08 Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 05:58:49 -0500 Subject: [PATCH 07/22] fix: Replate npm-merge-driver with .gitattributes - Removes the `npm-merge-driver` that may be causing #326. - Adds a `prepare` script, which autoruns on `npm install`, which removes local git config for npm-merge-driver. - Adds a .gitattributes file instead, which configures Git to treat package-lock.json as binary, so it does not attempt a dangerous text merge which might result in an invalid lockfile. --- .gitattributes | 1 + package-lock.json | 407 ++-------------------------- package.json | 2 +- packages/peregrine/package.json | 2 - packages/venia-concept/package.json | 2 - scripts/update_repo_environment.js | 36 +++ 6 files changed, 54 insertions(+), 396 deletions(-) create mode 100644 .gitattributes create mode 100644 scripts/update_repo_environment.js diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..fd5994a6297 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +package-lock.json -diff diff --git a/package-lock.json b/package-lock.json index 07c26b5ad8e..2b5738fe951 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10632,9 +10632,9 @@ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, "enzyme": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.6.0.tgz", - "integrity": "sha512-onsINzVLGqKIapTVfWkkw6bYvm1o4CyJ9s8POExtQhAkVa4qFDW6DGCQGRy/5bfZYk+gmUbMNyayXiWDzTkHFQ==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.7.0.tgz", + "integrity": "sha512-QLWx+krGK6iDNyR1KlH5YPZqxZCQaVF6ike1eDJAOg0HvSkSCVImPsdWaNw6v+VrnK92Kg8jIOYhuOSS9sBpyg==", "dev": true, "requires": { "array.prototype.flat": "^1.2.1", @@ -10667,9 +10667,9 @@ } }, "enzyme-adapter-react-16": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.5.0.tgz", - "integrity": "sha512-R2LcVvMB2UwPH763d5jDtVedAIcEj+uZjOnq0nd1sOUs6z8TDbyHDvt8VwfrS4wMt7CawoyPmH0XzC8MtEqqDw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.6.0.tgz", + "integrity": "sha512-ay9eGFpChyUDnjTFMMJHzrb681LF3hPWJLEA7RoLFG9jSWAdAm2V50pGmFV9dYGJgh5HfdiqM+MNvle41Yf/PA==", "dev": true, "requires": { "enzyme-adapter-utils": "^1.8.0", @@ -10677,7 +10677,7 @@ "object.assign": "^4.1.0", "object.values": "^1.0.4", "prop-types": "^15.6.2", - "react-is": "^16.4.2", + "react-is": "^16.5.2", "react-test-renderer": "^16.0.0-0" } }, @@ -12017,9 +12017,9 @@ } }, "flatmap-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.0.tgz", - "integrity": "sha512-Nlic4ZRYxikqnK5rj3YoxDVKGGtUjcNDUtvQ7XsdGLZmMwdUYnXf10o1zcXtzEZTBgc6GxeRpQxV/Wu3WPIIHA==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.1.tgz", + "integrity": "sha512-lAq4tLbm3sidmdCN8G3ExaxH7cUCtP5mgDvrYowsx84dcYkJJ4I28N7gkxA6+YlSXzaGLJYIDEi9WGfXzMiXdw==", "dev": true }, "flatten": { @@ -19533,381 +19533,6 @@ } } }, - "npm-merge-driver": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/npm-merge-driver/-/npm-merge-driver-2.3.5.tgz", - "integrity": "sha512-MUxE26ZdDWAc+wlqwyOEIhRH1EdaIXCWSZbqAQ76dUkz3uSrxrLhfgQ3nb3oZbqC5e4NyLcCdzTSDVwkisoJpg==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1", - "yargs": "^10.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mimic-fn": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "which": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.1", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "yargs": { - "version": "10.0.3", - "bundled": true, - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "cliui": { - "version": "3.2.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - } - } - }, - "yargs-parser": { - "version": "8.0.0", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - } - } - } - } - }, "npm-package-arg": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", @@ -23449,9 +23074,9 @@ } }, "regexpp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, "regexpu-core": { @@ -24807,9 +24432,9 @@ "dev": true }, "spdx-correct": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.1.tgz", - "integrity": "sha512-hxSPZbRZvSDuOvADntOElzJpenIR7wXJkuoUcUtS0erbgt2fgeaoPIYretfKpslMhfFDY4k0MZ2F5CUzhBsSvQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", + "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" diff --git a/package.json b/package.json index ce276f97cee..ac3bfbed4a9 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", "danger": "danger-ci", "lint": "eslint '@(packages|scripts)/**/*.js' --ignore-pattern node_modules --ignore-pattern storybook-dist", + "prepare": "./scripts/update_repo_environment.js", "prettier": "prettier --write '@(packages|scripts)/**/*.@(js|css)' '*.js'", "prettier:check": "prettier --list-different '@(packages|scripts)/**/*.@(js|css)' '*.js'", "stage:venia": "cd packages/venia-concept && npm start; cd - >/dev/null", @@ -89,7 +90,6 @@ "nock": "^10.0.0", "node-fetch": "^2.2.0", "nodemon": "^1.18.4", - "npm-merge-driver": "^2.3.5", "npm-run-all": "^4.1.2", "prettier": "^1.13.5", "prettier-check": "^2.0.0", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index 7e307061e6b..435c33a69dd 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -20,7 +20,6 @@ "build": "babel src --out-dir dist --ignore '__tests__/,__mocks__/,__fixtures__/' --source-maps --copy-files", "clean": "rimraf dist", "danger": "danger-ci", - "prepare": "npm-merge-driver install", "storybook": "start-storybook -p 9001 -c .storybook", "storybook:build": "build-storybook -c .storybook -o storybook-dist", "watch": "npm run -s build -- --watch" @@ -38,7 +37,6 @@ "babel-cli": "^6.26.0", "babel-runtime": "^6.26.0", "danger": "^3.9.0", - "npm-merge-driver": "^2.3.5", "react": "^16.4.2", "react-dom": "^16.4.2", "react-redux": "^5.0.7", diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index 1d61416cea9..ddc894ce85b 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -16,7 +16,6 @@ "scripts": { "build": "webpack --color --env.phase production", "clean": "rimraf web/js", - "prepare": "npm-merge-driver install", "start": "node server.js", "start:debug": "node --inspect-brk ./node_modules/.bin/webpack-dev-server --progress --color --env.phase development", "validate-queries": "node ./validate-queries.js", @@ -26,7 +25,6 @@ "@magento/peregrine": "^2.0.0-rc2.0.1", "@magento/pwa-buildpack": "^2.0.0-rc2.0.1", "@magento/upward-js": "^2.0.0-rc2.0.1", - "npm-merge-driver": "^2.3.5", "rimraf": "^2.6.2", "webpack": "3.11.0", "webpack-dev-server": "2.11.0" diff --git a/scripts/update_repo_environment.js b/scripts/update_repo_environment.js new file mode 100644 index 00000000000..8a99b614e4c --- /dev/null +++ b/scripts/update_repo_environment.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const execa = require('execa'); + +let config; +try { + config = execa.sync('git', ['config', '--list', '--local']).stdout; +} catch (e) { + // assume we're not in a git repo and there is nothing to be done + console.error(e); +} +const driverLine = config.match( + /^merge\.(.+)\.driver\s*=\s*(npx )?npm-merge-driver/m +); + +if (driverLine) { + const npmMergeDriver = driverLine[1]; + console.warn( + 'The current Git repository is still configured to merge package-lock.json with npm-merge-driver. npm-merge-driver has been removed from PWA Studio. Removing from local Git config...' + ); + execa.sync('git', [ + 'config', + '--local', + '--remove-section', + `merge.${npmMergeDriver}` + ]); + console.log('Removed from .git/config'); + const attributes = fs + .readFileSync('.git/info/attributes', 'utf8') + .split('\n'); + const lineDriverRE = new RegExp(`^.+merge=${npmMergeDriver}\s*$`); + const toKeep = attributes.filter(a => !lineDriverRE.test(a)); + if (toKeep.length < attributes.length) { + fs.writeFileSync('.git/info/attributes', toKeep.join('\n'), 'utf8'); + } + console.log('Removed from .git/info/attributes'); +} From 060e18faa5559187525cc69fc811ab34d94fb10c Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 07:48:20 -0500 Subject: [PATCH 08/22] fix: do not force https in UPWARD fetch --- .../src/WebpackTools/plugins/UpwardPlugin.js | 12 ++++++-- .../plugins/__tests__/UpwardPlugin.spec.js | 28 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js b/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js index 582307d15de..a692a08b99b 100644 --- a/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js +++ b/packages/pwa-buildpack/src/WebpackTools/plugins/UpwardPlugin.js @@ -2,10 +2,11 @@ const debug = require('../../util/debug').makeFileLogger(__filename); const fetch = require('node-fetch'); const path = require('path'); const https = require('https'); +const url = require('url'); const upward = require('@magento/upward-js'); // To be used with `node-fetch` in order to allow self-signed certificates. -const agent = new https.Agent({ rejectUnauthorized: false }); +const httpsAgent = new https.Agent({ rejectUnauthorized: false }); class UpwardPlugin { constructor(devServer, upwardPath) { @@ -79,8 +80,15 @@ class UpwardPlugin { async networkFetch(path, options) { debug('networkFetch %s, %o', path, options); + const { protocol } = url.parse(path); + if (protocol === 'https:') { + return fetch( + path, + Object.assign({ agent: httpsAgent }, options) + ); + } + return fetch(path, options); // Use the https.Agent to allow self-signed certificates. - return fetch(path, Object.assign({ agent }, options)); } }; diff --git a/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js b/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js index 547f1d8c3b6..179c0be5adb 100644 --- a/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js +++ b/packages/pwa-buildpack/src/WebpackTools/plugins/__tests__/UpwardPlugin.spec.js @@ -216,3 +216,31 @@ test('dev-mode IOAdapter uses fetch', async () => { }) ); }); + +test('dev-mode IOAdapter can fetch unsecure URLs', async () => { + const devServer = {}; + const app = { + use: jest.fn() + }; + + upward.middleware.mockResolvedValueOnce(() => {}); + + const plugin = new UpwardPlugin(devServer); + plugin.apply({}); + devServer.after(app); + const handler = app.use.mock.calls[0][0]; + handler(); + await plugin.middlewarePromise; + + const io = upward.middleware.mock.calls[0][1]; + + io.networkFetch('http://example.com', { method: 'POST' }); + + expect(fetch).toHaveBeenCalledWith( + 'http://example.com', + expect.objectContaining({ + method: 'POST' + }) + ); + expect(fetch.mock.calls[0][1]).not.toHaveProperty('agent'); +}); From 3de70ca51a7245feb209d5c9a1ea8209d441b561 Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 07:54:56 -0500 Subject: [PATCH 09/22] v2.0.0-rc2.0.2 --- lerna.json | 2 +- packages/peregrine/package.json | 2 +- packages/pwa-buildpack/package.json | 2 +- packages/pwa-devdocs/package.json | 2 +- packages/upward-js/package.json | 4 ++-- packages/upward-spec/package.json | 2 +- packages/venia-concept/package.json | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lerna.json b/lerna.json index 22ebbe74cb0..731334e72bc 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "packages": [ "packages/peregrine", "packages/pwa-buildpack", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index 435c33a69dd..027b60d0c8d 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -1,6 +1,6 @@ { "name": "@magento/peregrine", - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index 999ecd6225e..69c7cc1b0e1 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -1,6 +1,6 @@ { "name": "@magento/pwa-buildpack", - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-devdocs/package.json b/packages/pwa-devdocs/package.json index 8c47e9661eb..fbdfea52e44 100644 --- a/packages/pwa-devdocs/package.json +++ b/packages/pwa-devdocs/package.json @@ -1,7 +1,7 @@ { "name": "pwa-devdocs", "private": true, - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "description": "A documentation site for Magento PWA", "main": "gulpfile.js", "dependencies": { diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index 2673b4cdafe..86baaa23ed7 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-js", - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "description": "Implementation of the UPWARD spec as a NodeJS server", "main": "./lib/index.js", "bin": { @@ -49,7 +49,7 @@ "traverse": "^0.6.6" }, "devDependencies": { - "@magento/upward-spec": "^2.0.0-rc2.0.1", + "@magento/upward-spec": "^2.0.0-rc2.0.2", "express": "^4.16.3", "jest": "^23.5.0", "supertest": "^3.1.0" diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json index cccdf55f471..b219e35a1b4 100644 --- a/packages/upward-spec/package.json +++ b/packages/upward-spec/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-spec", - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "description": "UPWARD specification, guide, and test suite.", "main": "./suite/index.js", "bin": { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index ddc894ce85b..465af1997ac 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -1,6 +1,6 @@ { "name": "@magento/venia-concept", - "version": "2.0.0-rc2.0.1", + "version": "2.0.0-rc2.0.2", "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", "author": "Magento Commerce", @@ -22,9 +22,9 @@ "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { - "@magento/peregrine": "^2.0.0-rc2.0.1", - "@magento/pwa-buildpack": "^2.0.0-rc2.0.1", - "@magento/upward-js": "^2.0.0-rc2.0.1", + "@magento/peregrine": "^2.0.0-rc2.0.2", + "@magento/pwa-buildpack": "^2.0.0-rc2.0.2", + "@magento/upward-js": "^2.0.0-rc2.0.2", "rimraf": "^2.6.2", "webpack": "3.11.0", "webpack-dev-server": "2.11.0" From 06e2f907826586d2b399271784b59545ff4031de Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 08:04:00 -0500 Subject: [PATCH 10/22] fix: update package files so lerna publish works --- packages/pwa-buildpack/package.json | 4 ++-- packages/venia-concept/package.json | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index 69c7cc1b0e1..99282d2583e 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -7,9 +7,9 @@ "description": "Build/Layout optimization tooling and Peregrine framework adapters for the Magento PWA", "main": "dist/index.js", "scripts": { - "build": "babel src --out-dir dist --ignore '__tests__/,__mocks__/,__fixtures__/' --source-maps --copy-files", + "build": "npx babel src --out-dir dist --ignore '__tests__/,__mocks__/,__fixtures__/' --source-maps --copy-files", "clean": "rimraf dist", - "prepublishOnly": "rimraf dist && npm run build", + "prepublishOnly": "npx rimraf dist && npm run build", "watch": "npm run -s build -- --watch" }, "files": [ diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index 465af1997ac..66b696d3be5 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -1,5 +1,8 @@ { "name": "@magento/venia-concept", + "publishConfig": { + "access": "public" + }, "version": "2.0.0-rc2.0.2", "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", From e7dc3e7d3ba3e7fc9a582444e9bdb30332fa5ddd Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 08:08:46 -0500 Subject: [PATCH 11/22] v2.0.0-rc2.0.3 --- lerna.json | 2 +- packages/peregrine/package.json | 2 +- packages/pwa-buildpack/package.json | 2 +- packages/pwa-devdocs/package.json | 2 +- packages/upward-js/package.json | 4 ++-- packages/upward-spec/package.json | 2 +- packages/venia-concept/package.json | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lerna.json b/lerna.json index 731334e72bc..067633a9398 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "packages": [ "packages/peregrine", "packages/pwa-buildpack", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index 027b60d0c8d..b69adf4169f 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -1,6 +1,6 @@ { "name": "@magento/peregrine", - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index 99282d2583e..d3d3780315f 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -1,6 +1,6 @@ { "name": "@magento/pwa-buildpack", - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-devdocs/package.json b/packages/pwa-devdocs/package.json index fbdfea52e44..a01fd5e2322 100644 --- a/packages/pwa-devdocs/package.json +++ b/packages/pwa-devdocs/package.json @@ -1,7 +1,7 @@ { "name": "pwa-devdocs", "private": true, - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "description": "A documentation site for Magento PWA", "main": "gulpfile.js", "dependencies": { diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index 86baaa23ed7..7457e5ceb03 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-js", - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "description": "Implementation of the UPWARD spec as a NodeJS server", "main": "./lib/index.js", "bin": { @@ -49,7 +49,7 @@ "traverse": "^0.6.6" }, "devDependencies": { - "@magento/upward-spec": "^2.0.0-rc2.0.2", + "@magento/upward-spec": "^2.0.0-rc2.0.3", "express": "^4.16.3", "jest": "^23.5.0", "supertest": "^3.1.0" diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json index b219e35a1b4..58dc5b64476 100644 --- a/packages/upward-spec/package.json +++ b/packages/upward-spec/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-spec", - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "description": "UPWARD specification, guide, and test suite.", "main": "./suite/index.js", "bin": { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index 66b696d3be5..2c8aefaec5a 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "2.0.0-rc2.0.2", + "version": "2.0.0-rc2.0.3", "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", "author": "Magento Commerce", @@ -25,9 +25,9 @@ "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { - "@magento/peregrine": "^2.0.0-rc2.0.2", - "@magento/pwa-buildpack": "^2.0.0-rc2.0.2", - "@magento/upward-js": "^2.0.0-rc2.0.2", + "@magento/peregrine": "^2.0.0-rc2.0.3", + "@magento/pwa-buildpack": "^2.0.0-rc2.0.3", + "@magento/upward-js": "^2.0.0-rc2.0.3", "rimraf": "^2.6.2", "webpack": "3.11.0", "webpack-dev-server": "2.11.0" From 875084eb03d3eccfffd6c93ae661cca0e2115f96 Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 09:00:06 -0500 Subject: [PATCH 12/22] fix: package-lock --- package-lock.json | 1131 +++------------------------------------------ 1 file changed, 72 insertions(+), 1059 deletions(-) diff --git a/package-lock.json b/package-lock.json index 138fed9c0b8..96e44d27d37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1504,936 +1504,15 @@ "traverse": "^0.6.6" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "bundled": true - }, - "arr-flatten": { - "version": "1.1.0", - "bundled": true - }, - "arr-union": { - "version": "3.1.0", - "bundled": true - }, - "array-unique": { - "version": "0.3.2", - "bundled": true - }, - "assign-symbols": { - "version": "1.0.0", - "bundled": true - }, - "atob": { - "version": "2.1.2", - "bundled": true - }, - "auto-parse": { - "version": "1.5.1", - "bundled": true, - "requires": { - "typpy": "^2.3.10" - } - }, - "base": { - "version": "0.11.2", - "bundled": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "braces": { - "version": "2.3.2", - "bundled": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "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.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "bundled": true, - "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" - } - }, - "class-utils": { - "version": "0.3.6", - "bundled": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "collection-visit": { - "version": "1.0.0", - "bundled": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "component-emitter": { - "version": "1.2.1", - "bundled": true - }, - "copy-descriptor": { - "version": "0.1.1", - "bundled": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true - }, - "define-property": { - "version": "2.0.2", - "bundled": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "eventemitter3": { - "version": "3.1.0", - "bundled": true - }, - "expand-brackets": { - "version": "2.1.4", - "bundled": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "bundled": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "bundled": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "bundled": true, - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "bundled": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "follow-redirects": { - "version": "1.5.8", - "bundled": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "bundled": true - }, - "fragment-cache": { - "version": "0.2.1", - "bundled": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "function.name": { - "version": "1.0.11", - "bundled": true, - "requires": { - "noop6": "^1.0.1" - } - }, - "get-value": { - "version": "2.0.6", - "bundled": true - }, - "has-value": { - "version": "1.0.0", - "bundled": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "bundled": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "http-proxy": { - "version": "1.17.0", - "bundled": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.0", - "bundled": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.10", - "micromatch": "^3.1.10" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "bundled": true - } - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "bundled": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "bundled": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "bundled": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "bundled": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "bundled": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "bundled": true - }, - "is-extglob": { - "version": "2.1.1", - "bundled": true - }, - "is-glob": { - "version": "4.0.0", - "bundled": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "bundled": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "bundled": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-windows": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isobject": { - "version": "3.0.1", - "bundled": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true - }, - "map-cache": { - "version": "0.2.2", - "bundled": true - }, - "map-visit": { - "version": "1.0.0", - "bundled": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "bundled": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "mixin-deep": { - "version": "1.3.1", - "bundled": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "ms": { - "version": "2.0.0", - "bundled": true - }, - "nanomatch": { - "version": "1.2.13", - "bundled": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "noop6": { - "version": "1.0.7", - "bundled": true - }, - "object-copy": { - "version": "0.1.0", - "bundled": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-visit": { - "version": "1.0.1", - "bundled": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "bundled": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "pascalcase": { - "version": "0.1.1", - "bundled": true - }, - "posix-character-classes": { - "version": "0.1.1", - "bundled": true - }, - "regex-not": { - "version": "1.0.2", - "bundled": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "repeat-element": { - "version": "1.1.3", - "bundled": true - }, - "repeat-string": { - "version": "1.6.1", - "bundled": true - }, - "requires-port": { - "version": "1.0.0", - "bundled": true - }, - "resolve-url": { - "version": "0.2.1", - "bundled": true - }, - "ret": { - "version": "0.1.15", - "bundled": true - }, - "safe-regex": { - "version": "1.1.0", - "bundled": true, - "requires": { - "ret": "~0.1.10" - } - }, - "set-value": { - "version": "2.0.0", - "bundled": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon": { - "version": "0.8.2", - "bundled": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "bundled": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "bundled": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "bundled": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "bundled": true - }, - "source-map-resolve": { - "version": "0.5.2", - "bundled": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "bundled": true - }, - "split-string": { - "version": "3.1.0", - "bundled": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "static-extend": { - "version": "0.1.2", - "bundled": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "to-object-path": { - "version": "0.3.0", - "bundled": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "bundled": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "bundled": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "typpy": { - "version": "2.3.10", - "bundled": true, - "requires": { - "function.name": "^1.0.3" - } - }, - "union-value": { - "version": "1.0.0", - "bundled": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "bundled": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "unset-value": { - "version": "1.0.0", + "http-proxy-middleware": { + "version": "0.19.0", "bundled": true, "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "bundled": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "bundled": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "bundled": true - } + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.10", + "micromatch": "^3.1.10" } - }, - "urix": { - "version": "0.1.0", - "bundled": true - }, - "use": { - "version": "3.1.1", - "bundled": true } } }, @@ -12313,25 +11392,21 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "bundled": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "bundled": true }, "aproba": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "bundled": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "bundled": true, "optional": true, "requires": { "delegates": "^1.0.0", @@ -12340,13 +11415,11 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "bundled": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -12354,35 +11427,29 @@ }, "chownr": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "bundled": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "bundled": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "bundled": true }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "bundled": true, "optional": true }, "debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "bundled": true, "optional": true, "requires": { "ms": "2.0.0" @@ -12390,26 +11457,22 @@ }, "deep-extend": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "bundled": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "bundled": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bundled": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "bundled": true, "optional": true, "requires": { "minipass": "^2.2.1" @@ -12417,14 +11480,12 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "optional": true, "requires": { "aproba": "^1.0.3", @@ -12439,8 +11500,7 @@ }, "glob": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "bundled": true, "optional": true, "requires": { "fs.realpath": "^1.0.0", @@ -12453,14 +11513,12 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "bundled": true, "optional": true }, "iconv-lite": { "version": "0.4.21", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "bundled": true, "optional": true, "requires": { "safer-buffer": "^2.1.0" @@ -12468,8 +11526,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "bundled": true, "optional": true, "requires": { "minimatch": "^3.0.4" @@ -12477,8 +11534,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "optional": true, "requires": { "once": "^1.3.0", @@ -12487,46 +11543,39 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "bundled": true }, "ini": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "bundled": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "requires": { "number-is-nan": "^1.0.0" } }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "bundled": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "bundled": true }, "minipass": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", - "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", + "bundled": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -12534,8 +11583,7 @@ }, "minizlib": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "bundled": true, "optional": true, "requires": { "minipass": "^2.2.1" @@ -12543,22 +11591,19 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "bundled": true, "optional": true }, "needle": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", - "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", + "bundled": true, "optional": true, "requires": { "debug": "^2.1.2", @@ -12568,8 +11613,7 @@ }, "node-pre-gyp": { "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz", - "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", + "bundled": true, "optional": true, "requires": { "detect-libc": "^1.0.2", @@ -12586,8 +11630,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "optional": true, "requires": { "abbrev": "1", @@ -12596,14 +11639,12 @@ }, "npm-bundled": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", - "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", + "bundled": true, "optional": true }, "npm-packlist": { "version": "1.1.10", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", - "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", + "bundled": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", @@ -12612,8 +11653,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "optional": true, "requires": { "are-we-there-yet": "~1.1.2", @@ -12624,39 +11664,33 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "bundled": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "bundled": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "requires": { "wrappy": "1" } }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "bundled": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "optional": true, "requires": { "os-homedir": "^1.0.0", @@ -12665,20 +11699,17 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "bundled": true, "optional": true }, "rc": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", + "bundled": true, "optional": true, "requires": { "deep-extend": "^0.5.1", @@ -12689,16 +11720,14 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "optional": true } } }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "optional": true, "requires": { "core-util-is": "~1.0.0", @@ -12712,8 +11741,7 @@ }, "rimraf": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "bundled": true, "optional": true, "requires": { "glob": "^7.0.5" @@ -12721,43 +11749,36 @@ }, "safe-buffer": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "bundled": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "bundled": true, "optional": true }, "semver": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "bundled": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -12766,8 +11787,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "optional": true, "requires": { "safe-buffer": "~5.1.0" @@ -12775,22 +11795,19 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "requires": { "ansi-regex": "^2.0.0" } }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "bundled": true, "optional": true }, "tar": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", - "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", + "bundled": true, "optional": true, "requires": { "chownr": "^1.0.1", @@ -12804,14 +11821,12 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "optional": true }, "wide-align": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "bundled": true, "optional": true, "requires": { "string-width": "^1.0.2" @@ -12819,13 +11834,11 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "bundled": true }, "yallist": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + "bundled": true } } }, From b4a261caeeb3176977fda448c27c3f7dd3b5f2d4 Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 09:02:15 -0500 Subject: [PATCH 13/22] v2.0.0-rc2.0.4 --- lerna.json | 2 +- packages/peregrine/package.json | 2 +- packages/pwa-buildpack/package.json | 2 +- packages/pwa-devdocs/package.json | 2 +- packages/upward-js/package.json | 4 ++-- packages/upward-spec/package.json | 2 +- packages/venia-concept/package.json | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lerna.json b/lerna.json index 067633a9398..89994d90136 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "packages": [ "packages/peregrine", "packages/pwa-buildpack", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index b69adf4169f..6cb72d3c381 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -1,6 +1,6 @@ { "name": "@magento/peregrine", - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index d3d3780315f..be7f85316f4 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -1,6 +1,6 @@ { "name": "@magento/pwa-buildpack", - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-devdocs/package.json b/packages/pwa-devdocs/package.json index a01fd5e2322..62c74162b3f 100644 --- a/packages/pwa-devdocs/package.json +++ b/packages/pwa-devdocs/package.json @@ -1,7 +1,7 @@ { "name": "pwa-devdocs", "private": true, - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "description": "A documentation site for Magento PWA", "main": "gulpfile.js", "dependencies": { diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index 7457e5ceb03..f7e44ad9b52 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-js", - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "description": "Implementation of the UPWARD spec as a NodeJS server", "main": "./lib/index.js", "bin": { @@ -49,7 +49,7 @@ "traverse": "^0.6.6" }, "devDependencies": { - "@magento/upward-spec": "^2.0.0-rc2.0.3", + "@magento/upward-spec": "^2.0.0-rc2.0.4", "express": "^4.16.3", "jest": "^23.5.0", "supertest": "^3.1.0" diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json index 58dc5b64476..548e8e0d075 100644 --- a/packages/upward-spec/package.json +++ b/packages/upward-spec/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-spec", - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "description": "UPWARD specification, guide, and test suite.", "main": "./suite/index.js", "bin": { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index 2c8aefaec5a..51316b9d810 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "2.0.0-rc2.0.3", + "version": "2.0.0-rc2.0.4", "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", "author": "Magento Commerce", @@ -25,9 +25,9 @@ "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { - "@magento/peregrine": "^2.0.0-rc2.0.3", - "@magento/pwa-buildpack": "^2.0.0-rc2.0.3", - "@magento/upward-js": "^2.0.0-rc2.0.3", + "@magento/peregrine": "^2.0.0-rc2.0.4", + "@magento/pwa-buildpack": "^2.0.0-rc2.0.4", + "@magento/upward-js": "^2.0.0-rc2.0.4", "rimraf": "^2.6.2", "webpack": "3.11.0", "webpack-dev-server": "2.11.0" From 96009e7a8a0d9f28bb6e6ee4285193624773ea07 Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 09:11:53 -0500 Subject: [PATCH 14/22] fix: was not caching generated certs --- .../pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js | 4 ++++ packages/pwa-buildpack/src/Utilities/setupDomain.js | 1 + 2 files changed, 5 insertions(+) diff --git a/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js b/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js index 4822c35123c..7af0e10e73a 100644 --- a/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js +++ b/packages/pwa-buildpack/src/Utilities/__tests__/setupDomain.spec.js @@ -181,6 +181,10 @@ test('refreshes an expired cert', async () => { key: 'yes', cert: 'diggity' }); + expect(setupDomain.userCerts.set).toHaveBeenCalledWith( + `custom-823.${setupDomain.DEV_DOMAIN}`, + expect.objectContaining({ key: 'yes', cert: 'diggity' }) + ); }); test('passes errors from denied root or bad parse', async () => { diff --git a/packages/pwa-buildpack/src/Utilities/setupDomain.js b/packages/pwa-buildpack/src/Utilities/setupDomain.js index 68ea02cc109..bbaf596c92c 100644 --- a/packages/pwa-buildpack/src/Utilities/setupDomain.js +++ b/packages/pwa-buildpack/src/Utilities/setupDomain.js @@ -123,6 +123,7 @@ async function setupDomain(customName, opts) { ); if (secure && !certPair) { certPair = JSON.parse(output)[0]; + await userCerts.set(hostname, certPair); } } catch (e) { throw Error( From 8f672c2da08771d9434823a67d457e41bf14cd3c Mon Sep 17 00:00:00 2001 From: zetlen Date: Fri, 5 Oct 2018 09:12:43 -0500 Subject: [PATCH 15/22] v2.0.0-rc2.0.5 --- lerna.json | 2 +- packages/peregrine/package.json | 2 +- packages/pwa-buildpack/package.json | 2 +- packages/pwa-devdocs/package.json | 2 +- packages/upward-js/package.json | 4 ++-- packages/upward-spec/package.json | 2 +- packages/venia-concept/package.json | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lerna.json b/lerna.json index 89994d90136..6ae05056548 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "packages": [ "packages/peregrine", "packages/pwa-buildpack", diff --git a/packages/peregrine/package.json b/packages/peregrine/package.json index 6cb72d3c381..7805589fbae 100644 --- a/packages/peregrine/package.json +++ b/packages/peregrine/package.json @@ -1,6 +1,6 @@ { "name": "@magento/peregrine", - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-buildpack/package.json b/packages/pwa-buildpack/package.json index be7f85316f4..c7bd6d12087 100644 --- a/packages/pwa-buildpack/package.json +++ b/packages/pwa-buildpack/package.json @@ -1,6 +1,6 @@ { "name": "@magento/pwa-buildpack", - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "publishConfig": { "access": "public" }, diff --git a/packages/pwa-devdocs/package.json b/packages/pwa-devdocs/package.json index 62c74162b3f..9c5b7df1ea9 100644 --- a/packages/pwa-devdocs/package.json +++ b/packages/pwa-devdocs/package.json @@ -1,7 +1,7 @@ { "name": "pwa-devdocs", "private": true, - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "description": "A documentation site for Magento PWA", "main": "gulpfile.js", "dependencies": { diff --git a/packages/upward-js/package.json b/packages/upward-js/package.json index f7e44ad9b52..a657316ff55 100644 --- a/packages/upward-js/package.json +++ b/packages/upward-js/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-js", - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "description": "Implementation of the UPWARD spec as a NodeJS server", "main": "./lib/index.js", "bin": { @@ -49,7 +49,7 @@ "traverse": "^0.6.6" }, "devDependencies": { - "@magento/upward-spec": "^2.0.0-rc2.0.4", + "@magento/upward-spec": "^2.0.0-rc2.0.5", "express": "^4.16.3", "jest": "^23.5.0", "supertest": "^3.1.0" diff --git a/packages/upward-spec/package.json b/packages/upward-spec/package.json index 548e8e0d075..4b186e14aa9 100644 --- a/packages/upward-spec/package.json +++ b/packages/upward-spec/package.json @@ -1,6 +1,6 @@ { "name": "@magento/upward-spec", - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "description": "UPWARD specification, guide, and test suite.", "main": "./suite/index.js", "bin": { diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index 51316b9d810..2f922b6cad5 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "2.0.0-rc2.0.4", + "version": "2.0.0-rc2.0.5", "description": "Venia PWA Concept Storefront for Magento 2", "license": "(OSL-3.0 OR AFL-3.0)", "author": "Magento Commerce", @@ -25,9 +25,9 @@ "watch": "webpack-dev-server --progress --color --env.phase development" }, "devDependencies": { - "@magento/peregrine": "^2.0.0-rc2.0.4", - "@magento/pwa-buildpack": "^2.0.0-rc2.0.4", - "@magento/upward-js": "^2.0.0-rc2.0.4", + "@magento/peregrine": "^2.0.0-rc2.0.5", + "@magento/pwa-buildpack": "^2.0.0-rc2.0.5", + "@magento/upward-js": "^2.0.0-rc2.0.5", "rimraf": "^2.6.2", "webpack": "3.11.0", "webpack-dev-server": "2.11.0" From 981eda64fd1ce197131f10c906e3c35ada11db8c Mon Sep 17 00:00:00 2001 From: "Kristof, Fooman" Date: Sat, 6 Oct 2018 04:10:46 +1300 Subject: [PATCH 16/22] Less assuming wording (#327) Possibly not trivial unless you deal with this all the time --- packages/upward-spec/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/upward-spec/README.md b/packages/upward-spec/README.md index 87bbb6b695a..5cb469d2050 100644 --- a/packages/upward-spec/README.md +++ b/packages/upward-spec/README.md @@ -94,7 +94,7 @@ An App Shell is purposefully minimal, and so is an UPWARD server. It is meant to The declarative format of UPWARD means that an UPWARD-compliant server may be written in any programming language and run on any tech stack; therefore, a PWA can declare the URIs and behavior of the network endpoints it depends on by including an UPWARD file. -### Simple example +### Echo Example This example definition file echoes request data as text back to the client. @@ -134,7 +134,7 @@ body: ``` -This trivial example demonstrates the initial properties of the context object, populated by the originating HTTP request. describes a server which always returns status 200 with a single header, `content-type`, and a text body which is a plaintext summary of the GET request properties. An example request to such a server results in: +This example demonstrates the initial properties of the context object, populated by the originating HTTP request. describes a server which always returns status 200 with a single header, `content-type`, and a text body which is a plaintext summary of the GET request properties. An example request to such a server results in: ```sh $ curl 'http://localhost:54422/head/shoulders?and=knees&and=toes' From e36e4f2f7cbec8ff30b2efb0e1d14731c77eb3ed Mon Sep 17 00:00:00 2001 From: James Calcaben Date: Mon, 8 Oct 2018 05:43:34 -0500 Subject: [PATCH 17/22] Update Venia Setup docs for version 2.0 (#333) - Update the Setup docs for version 2.0 - Add info to Setup docs about installing sample data (will need to update once #329 is merged) - Update 'Venia theme' to 'Venia storefront' since it is no longer a Magneto theme - Add troubleshooting entries --- packages/pwa-devdocs/src/_data/top-nav.yml | 2 +- .../src/_data/venia-pwa-concept.yml | 6 +- packages/pwa-devdocs/src/index.html | 8 +- .../pwa-buildpack/troubleshooting/index.md | 20 ++- .../src/venia-pwa-concept/setup/index.md | 156 +++++++++++------- 5 files changed, 122 insertions(+), 70 deletions(-) diff --git a/packages/pwa-devdocs/src/_data/top-nav.yml b/packages/pwa-devdocs/src/_data/top-nav.yml index 139f3e3ec68..9b46eeab9ff 100644 --- a/packages/pwa-devdocs/src/_data/top-nav.yml +++ b/packages/pwa-devdocs/src/_data/top-nav.yml @@ -7,5 +7,5 @@ - label: UI Components url: /peregrine/ -- label: Venia Theme +- label: Venia Storefront url: /venia-pwa-concept/ diff --git a/packages/pwa-devdocs/src/_data/venia-pwa-concept.yml b/packages/pwa-devdocs/src/_data/venia-pwa-concept.yml index 9e79ccb49f5..6b081c472bd 100644 --- a/packages/pwa-devdocs/src/_data/venia-pwa-concept.yml +++ b/packages/pwa-devdocs/src/_data/venia-pwa-concept.yml @@ -1,9 +1,9 @@ -title: Venia Theme (Concept) +title: Venia Storefront entries: - label: Overview url: /venia-pwa-concept/ - - label: Venia theme setup + - label: Venia storefront setup url: /venia-pwa-concept/setup/ - label: Simple REST checkout flow @@ -97,4 +97,4 @@ entries: url: /venia-pwa-concept/component/sort/ - label: Title bar - url: /venia-pwa-concept/component/title-bar/ \ No newline at end of file + url: /venia-pwa-concept/component/title-bar/ diff --git a/packages/pwa-devdocs/src/index.html b/packages/pwa-devdocs/src/index.html index 172cc27fa2f..87908cdf2b7 100644 --- a/packages/pwa-devdocs/src/index.html +++ b/packages/pwa-devdocs/src/index.html @@ -18,9 +18,9 @@

Overview

@@ -56,7 +56,7 @@

Tools and Libraries

Learn UI Components

- Use, extend, or remix Peregrine UI components to create a unique Magento PWA theme + Use, extend, or remix Peregrine UI components to create a unique Magento PWA storefront

@@ -119,7 +119,7 @@

Venia Theme source

- Project source code for a conceptual and customizable PWA theme for Magento 2. + Project source code for a conceptual and customizable PWA storefront for Magento 2. It is built using the Peregrine component library and Buildpack tools.

diff --git a/packages/pwa-devdocs/src/pwa-buildpack/troubleshooting/index.md b/packages/pwa-devdocs/src/pwa-buildpack/troubleshooting/index.md index ab71f705eef..8c062dd2d6b 100644 --- a/packages/pwa-devdocs/src/pwa-buildpack/troubleshooting/index.md +++ b/packages/pwa-devdocs/src/pwa-buildpack/troubleshooting/index.md @@ -16,6 +16,8 @@ Paste the result console output into the issue. Thank you! ## Common issues +* [Validation errors when running developer mode](#validation-errors) +* [Venia queries to GraphQL produce validation errors](#graphql-validation-errors) * [Browser displays "Cannot proxy to " error and the console displays `ENOTFOUND`](#cannot-proxy) * [Webpack hangs for a long time before beginning compilation](#webpack-hangs) * [Browser cannot resolve the `.local.pwadev` site](#cannot-resolve-site) @@ -23,6 +25,22 @@ Paste the result console output into the issue. Thank you! ## Resolutions +**Validation errors when running developer mode**{:#validation-errors} + +Make sure you copied over the `example.env` file into a new `.env` file in the `packages/venia-concept` directory. +This file should specify variables for your local development environment. + +**Venia queries to GraphQL produce validation errors**{:#graphql-validation-errors} + +Venia and its GraphQL queries are out of sync with the schema of the connected Magentoi instance. +Make sure your Magento instance is up to date with the latest from Magento 2.3 development branch. + +To test whether your queries are up to date, run the following command in the project root: + +``` sh +npm run validate:venia:gql +``` + **Browser displays "Cannot proxy to " error and the console displays `ENOTFOUND`**{:#cannot-proxy} Make sure your Magento store loads in more than one browser. @@ -71,4 +89,4 @@ You can install higher versions of OpenSSL with [Homebrew] on OSX, [Chocolatey] [create an issue]: https://github.com/magento-research/pwa-buildpack/issues [Slack channel]: https://magentocommeng.slack.com/messages/C71HNKYS2/team/UAFV915FB/ [Homebrew]: https://brew.sh/ -[Chocolatey]: https://chocolatey.org/ \ No newline at end of file +[Chocolatey]: https://chocolatey.org/ diff --git a/packages/pwa-devdocs/src/venia-pwa-concept/setup/index.md b/packages/pwa-devdocs/src/venia-pwa-concept/setup/index.md index 579852046d6..ede4f01291b 100644 --- a/packages/pwa-devdocs/src/venia-pwa-concept/setup/index.md +++ b/packages/pwa-devdocs/src/venia-pwa-concept/setup/index.md @@ -1,11 +1,11 @@ --- -title: Venia theme setup +title: Venia storefront setup --- -Venia is a PWA theme that runs on top of an existing Magento 2 backend. -Follow the instructions on this page to setup and install the [Venia PWA concept theme][] in your Magento 2 instance. +Venia is a PWA storefront that runs on top of an existing Magento 2 backend. +Follow the instructions on this page to setup and install the [Venia PWA concept storefront][] in your Magento 2 instance. -At the end of this tutorial, you will have a working copy of the Venia theme installed and running on top of Magento. +At the end of this tutorial, you will have a working copy of the Venia storefront installed and running on top of Magento. Use this setup to explore or develop Magento PWA components and themes. If you experience problems with the project setup, see [Troubleshooting][] in the PWA Buildpack section. @@ -21,9 +21,64 @@ If you experience problems with the project setup, see [Troubleshooting][] in th * Magento 2 installed using [valet-plus][] * [Vagrant Box for Magento 2 developers][] +## Step 1. Install Venia sample data +The Venia storefront works best with the new Venia sample data modules installed. -## Step 1. Clone repository +{: .bs-callout .bs-callout-warning} +If you have the previous `magento2-sample-data` module installed, you need to [remove the sample data modules][] and re-install Magento with a clean database. + +In your Magento installation root directory, create a file called `deployVeniaSampleData.sh` with the following content: + +``` sh +#!/usr/bin/env bash +composer='/usr/bin/env composer' +composerParams='--no-interaction --ansi' +moduleVendor='magento' +moduleList=( + module-catalog-sample-data-venia + module-configurable-sample-data-venia + module-customer-sample-data-venia + module-sales-sample-data-venia + module-tax-sample-data-venia + sample-data-media-venia +) +githubBasUrl='git@github.com:PMET-public' + +add_composer_repository () { + name=$1 + type=$2 + url=$3 + echo "adding composer repository ${url}" + ${composer} config ${composerParams} repositories.${name} ${type} ${url} +} + +add_venia_sample_data_repository () { + name=$1 + add_composer_repository ${name} github "${githubBasUrl}/${name}.git" +} + +for moduleName in "${moduleList[@]}" +do + add_venia_sample_data_repository ${moduleName} +done + +${composer} require ${composerParams} $(printf "${moduleVendor}/%s:dev-master@dev " "${moduleList[@]}") +``` + +Execute this script to add the Venia sample data packages to the project: + +``` sh +bash deployVeniaSampleData.sh +``` + +Run the following command to install the Venia data from the modules: + +``` +bin/magento setup:upgrade +``` + +## Step 2. Clone the PWA Studio repository Clone the [PWA Studio] repository into your development environment. @@ -64,14 +119,6 @@ If you clone the PWA Studio project repo into the `magento2ce` directory of the ``` yml ce: "https://github.com/magento/magento2.git::2.3-develop" ``` - And if you want to pull the sample data (optional), update: - ``` yml - ce_sample_data: "git@github.com:magento/magento2-sample-data.git" - ``` - to - ``` yml - ce_sample_data: "https://github.com/magento/magento2-sample-data.git::2.3-develop" - ``` 4. In that same file, update the PHP version to 7.1 by updating the following line: ``` yml php_version: "7.0" @@ -90,7 +137,10 @@ If you clone the PWA Studio project repo into the `magento2ce` directory of the ``` -## Step 2. Install PWA Studio dependencies +## Step 3. Install PWA Studio dependencies + +{: .bs-callout .bs-callout-warning} +If you have an existing `node_modules` directory from a previous PWA Studio version installation, remove it to prevent installation errors. In the PWA Studio project's root directory, run the following command to install the project dependencies: @@ -98,87 +148,71 @@ In the PWA Studio project's root directory, run the following command to install npm install ``` -## Step 3. Link and install module +## Step 4. Set environment variables -Navigate to your Magento installation's `app/code/Magento` directory and create a `Pwa` symlink folder linking to the project's `module` directory. +Under the `packages/venia-concept` directory, copy `.env.dist` into a new `.env` file: -**Example command:** +**Example commands:** ``` sh -ln -s /Users/magedev/pwa-studio/packages/pwa-module Pwa +cd /Users/magedev/pwa-studio/packages/venia-concept ``` -Or from your Magento 2 root ``` sh -ln -s pwa-studio/packages/pwa-module app/code/Magento/Pwa +cp .env.dist .env ``` -### Enable and install - -Navigate to your Magento installation's root director and run the following command to enable the module: +In the `.env` file set the value of `MAGENTO_BACKEND_DOMAIN` to the URL of your Magento development store. -``` sh -bin/magento module:enable Magento_Pwa +**Example:** +``` text +MAGENTO_BACKEND_DOMAIN="https://magento.test/" ``` -Install the module using the following command: -``` sh -bin/magento setup:upgrade -``` +## Step 5. Start the server -## Step 4. Link theme directory +Use any of the following commands from the **project root directory** to start the server: -Navigate to your Magento installation's `app/design/frontend/Magento` directory and create a `venia` symlink folder linking to the project's `theme-frontend-venia` directory. +`npm run watch:venia` -**Example command:** -``` sh -ln -s /Users/magedev/pwa-studio/packages/venia-concept venia -``` +: Starts the Venia storefront development environment. -## Step 5. Activate the Venia theme +`npm run watch:all` -Browse to the Admin section of your Magento store and configure it to use the **Magento Venia** theme. -You can find this configuration using the **Configuration** link in the **Content** tab. +: Runs the full PWA Studio developer experience, which include Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds. -## Step 6. Set environment variables +`npm run build && npm run stage:venia` -Under the Venia project's `theme-frontend-venia` directory, copy `.env.dist` into a new `.env` file and update the variables with the URL to your Magento development store. +: Generates build artifacts and runs the staging environment, which uses more compressed assets and more closely reflects production. -**Example commands:** -``` sh -cd /Users/magedev/pwa-studio/packages/venia-concept -``` -``` sh -cp .env.dist .env -``` - -## Step 7. Start the development server +### Browsing to the application -Use the following command to start the development server: +After the development server is up and running, look for a similar line in the terminal output (the port may differ for your instance): ``` sh -npm start +PWADevServer ready at https://magento-venia.local.pwadev:8001 ``` -{: .bs-callout .bs-callout-info} -**Note:** -Some users have reported using `sudo npm start` to get around permissions. - -After the development server is up and running, look for a similar line in the terminal output (the port will differ for your instance): +OR ``` sh -Project is running at https://magento-venia.local.pwadev:8000/ +Launching staging server... + +https://magento-venia.local.pwadev:51828/ + +Staging server running at the address above. ``` -This is the new address for your PWA frontend. +This is the address for your PWA frontend. You can still use the old address to access the Admin section of Magento, but for PWA development on the frontend, use this new address. -Congratulations! You have set up your development environment for the Venia theme project. +Congratulations! You have set up your development environment for the Venia storefront project. -[Venia PWA concept theme]: https://github.com/magento-research/pwa-studio/tree/master/packages/venia-concept +[Venia PWA concept storefront]: https://github.com/magento-research/pwa-studio/tree/master/packages/venia-concept [Node Package Manager]: https://www.npmjs.com/ [NodeJS 8.x LTS]: https://nodejs.org/en/ [Vagrant Box for Magento 2 developers]: https://github.com/paliarush/magento2-vagrant-for-developers [Troubleshooting]: {{ site.baseurl }}{% link pwa-buildpack/troubleshooting/index.md %} [PWA Studio]: https://github.com/magento-research/pwa-studio [local development instance]: https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html -[valet-plus]: https://github.com/weprovide/valet-plus \ No newline at end of file +[valet-plus]: https://github.com/weprovide/valet-plus +[remove the sample data modules]: https://devdocs.magento.com/guides/v2.3/install-gde/install/cli/install-cli-sample-data-other.html#inst-sample-remove From a0f4a4b68c20ca670a54dc8338a2a82a1e57a1b1 Mon Sep 17 00:00:00 2001 From: Rowan Merewood Date: Mon, 8 Oct 2018 13:08:39 +0100 Subject: [PATCH 18/22] Explicitly run build on first install (#338) Fixed the buildpack error that turns up on first install. --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5f83fc8ab5d..5e7b0a780fe 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,10 @@ Follow these steps to install the dependencies for all the packages in the proje 4. Watch the bootstrapping take place. 5. Create a `packages/venia-concept/.env` file (or set environment variables manually) 6. Set the environment variable `MAGENTO_BACKEND_DOMAIN` to the URL of the backing Magento instance you are using -7. To run the Venia storefront development experience, run `npm run watch:venia` from package root. -8. To run the full PWA Studio developer experience, with Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds, run `npm run watch:all` from package root. -9. To run the staging environment, which uses more compressed assets and more closely reflects production, run `npm run stage:venia` from package root. (This requires that you first run `npm run build` to generate the artifacts being served.) +7. On your first install, run `npm run build` from package root. +8. To run the Venia storefront development experience, run `npm run watch:venia` from package root. +9. To run the full PWA Studio developer experience, with Venia hot-reloading and concurrent Buildpack/Peregrine rebuilds, run `npm run watch:all` from package root. +10. To run the staging environment, which uses more compressed assets and more closely reflects production, run `npm run stage:venia` from package root. (This requires that you first run `npm run build` to generate the artifacts being served.) ## Troubleshooting From 33f8d9c7a8a7c9705e3d2a51823e0e0e924b41b6 Mon Sep 17 00:00:00 2001 From: Javier Villanueva Date: Mon, 8 Oct 2018 13:19:58 +0100 Subject: [PATCH 19/22] Update test script filename (#334) --- packages/upward-spec/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/upward-spec/README.md b/packages/upward-spec/README.md index 5cb469d2050..3d1c006498f 100644 --- a/packages/upward-spec/README.md +++ b/packages/upward-spec/README.md @@ -75,7 +75,7 @@ This repository is a test suite for UPWARD compliance, testing several scenarios 2. Use `npx` to run `upward-spec` on your shell script ```sh - npx upward-spec ./test_my_upward.sh + npx upward-spec ./test_upward_server.sh ``` 3. The shell script will run for each test suite with the environment variable `UPWARD_YAML` set to the path of a fixture YAML file for configuring a server instance. The script should launch a server (on a local port or a remote port, but resolvable to the local system) and print its host to standard out, staying in the foreground. @@ -84,7 +84,7 @@ This repository is a test suite for UPWARD compliance, testing several scenarios 4. By default, the test runner will print human-readable results to stdout; the argument `--xunit` will make it print XUnit-compatible (and therefore JUnit-compatible) test result XML. The argument `--tap` will make it print [Test Anything Protocol](https://testanything.org/)-compatible text. Under the hood, this uses [tape](https://github.com/substack/tape) and it can be piped to [any number of open-source TAP reporters](https://github.com/sindresorhus/awesome-tap#javascript). -:information_source: _(The `npx` tool above is not required; it's a convenience script to avoid installing global NPM dependencies. You can also install `upward-spec` permanently using `npm install -g upward-spec`, and then simply invoke `upward-spec ./test_my_upward.sh` from that point forward.)_ +:information_source: _(The `npx` tool above is not required; it's a convenience script to avoid installing global NPM dependencies. You can also install `upward-spec` permanently using `npm install -g upward-spec`, and then simply invoke `upward-spec ./test_upward_server.sh` from that point forward.)_ ## Summary @@ -1116,7 +1116,7 @@ The YAML specificationsupports an [anchor and reference syntax][yaml anchors] wh [pwa def]: [js identifiers]: [npx]: -[spec-shell-script]: <./test_my_upward.sh> +[spec-shell-script]: <./test_upward_server.sh> [yaml anchors]: [pcre]: [graphql spec data property]: From 652b221f61cfbfde8876dd0ef9165cc0cde5dedd Mon Sep 17 00:00:00 2001 From: Pierre Martin Date: Mon, 8 Oct 2018 14:27:51 +0200 Subject: [PATCH 20/22] Add UPWARD packages to the Github issue template (#330) --- .github/ISSUE_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 24ffc33cc8a..b054d07117c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -7,6 +7,8 @@ [ ] `peregrine` [ ] `pwa-module` [ ] `pwa-devdocs` +[ ] `upward-js` +[ ] `upward-spec` ## This issue is a: From 9fcfceeec7496caac2a38579d8a81f3281d8b2f2 Mon Sep 17 00:00:00 2001 From: Bartek Igielski Date: Mon, 8 Oct 2018 14:31:36 +0200 Subject: [PATCH 21/22] Missing phase name in Venia Webpack config error message (#331) * Missing phase details in Venia webpack errors * Improved code formatting --- packages/venia-concept/webpack.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/venia-concept/webpack.config.js b/packages/venia-concept/webpack.config.js index c094748b134..e15b0d9477a 100644 --- a/packages/venia-concept/webpack.config.js +++ b/packages/venia-concept/webpack.config.js @@ -185,7 +185,9 @@ module.exports = async function(env) { }) ); } else { - throw Error(`Unsupported environment phase in webpack config: `); + throw Error( + `Unsupported environment phase in webpack config: ${phase}` + ); } return config; }; From a4c8c5a7327457e8f2c8f08b8e17399b4b8ee382 Mon Sep 17 00:00:00 2001 From: Pierre Martin Date: Mon, 8 Oct 2018 14:34:13 +0200 Subject: [PATCH 22/22] Fix package name in global install command (#328) --- packages/upward-js/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/upward-js/README.md b/packages/upward-js/README.md index a4cc3232bf0..16df0ffd4ec 100644 --- a/packages/upward-js/README.md +++ b/packages/upward-js/README.md @@ -14,7 +14,7 @@ You can use `upward-js` from the command line, through the server API, or throug #### Command Line -The `upward-js-server` command will become globally available if you install globally: `npm install -g upward-js`. +The `upward-js-server` command will become globally available if you install globally: `npm install -g @magento/upward-js`. The server takes no arguments; instead it is configured by environment variables. At minimum, the environment variable `UPWARD_JS_UPWARD_PATH` must be set to the path of your definition file, and `UPWARD_JS_BIND_LOCAL` must be set to 1.