diff --git a/package-lock.json b/package-lock.json index 49e7f4596d..94d6bea922 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,14 +13,14 @@ } }, "@babel/generator": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", - "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", "dev": true, "requires": { - "@babel/types": "^7.3.2", + "@babel/types": "^7.3.4", "jsesc": "^2.5.1", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "source-map": "^0.5.0", "trim-right": "^1.0.1" } @@ -66,9 +66,9 @@ } }, "@babel/parser": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", - "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", "dev": true }, "@babel/template": { @@ -83,20 +83,20 @@ } }, "@babel/traverse": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", - "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.2", + "@babel/generator": "^7.3.4", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.2.3", - "@babel/types": "^7.2.2", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.10" + "lodash": "^4.17.11" }, "dependencies": { "debug": { @@ -117,64 +117,64 @@ } }, "@babel/types": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", - "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" } }, "@lerna/add": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.11.0.tgz", - "integrity": "sha512-A2u889e+GeZzL28jCpcN53iHq2cPWVnuy5tv5nvG/MIg0PxoAQOUvphexKsIbqzVd9Damdmv5W0u9kS8y8TTow==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.13.1.tgz", + "integrity": "sha512-cXk42YbuhzEnADCK8Qte5laC9Qo03eJLVnr0qKY85jQUM/T4URe3IIUemqpg0CpVATrB+Vz+iNdeqw9ng1iALw==", "dev": true, "requires": { - "@lerna/bootstrap": "3.11.0", - "@lerna/command": "3.11.0", - "@lerna/filter-options": "3.11.0", - "@lerna/npm-conf": "3.7.0", - "@lerna/validation-error": "3.11.0", + "@lerna/bootstrap": "3.13.1", + "@lerna/command": "3.13.1", + "@lerna/filter-options": "3.13.0", + "@lerna/npm-conf": "3.13.0", + "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", "npm-package-arg": "^6.1.0", "p-map": "^1.2.0", - "pacote": "^9.4.1", + "pacote": "^9.5.0", "semver": "^5.5.0" } }, "@lerna/batch-packages": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.11.0.tgz", - "integrity": "sha512-ETO3prVqDZs/cpZo00ij61JEZ8/ADJx1OG/d/KtTdHlyRfQsb09Xzf0w+boimqa8fIqhpM3o5FV9GKd6GQ3iFQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.13.0.tgz", + "integrity": "sha512-TgLBTZ7ZlqilGnzJ3xh1KdAHcySfHytgNRTdG9YomfriTU6kVfp1HrXxKJYVGs7ClPUNt2CTFEOkw0tMBronjw==", "dev": true, "requires": { - "@lerna/package-graph": "3.11.0", - "@lerna/validation-error": "3.11.0", + "@lerna/package-graph": "3.13.0", + "@lerna/validation-error": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/bootstrap": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.11.0.tgz", - "integrity": "sha512-MqwviGJTy86joqSX2A3fmu2wXLBXc23tHJp5Xu4bVhynPegDnRrA3d9UI80UM3JcuYIQsxT4t2q2LNsZ4VdZKQ==", - "dev": true, - "requires": { - "@lerna/batch-packages": "3.11.0", - "@lerna/command": "3.11.0", - "@lerna/filter-options": "3.11.0", - "@lerna/has-npm-version": "3.10.0", - "@lerna/npm-install": "3.11.0", - "@lerna/package-graph": "3.11.0", - "@lerna/pulse-till-done": "3.11.0", - "@lerna/rimraf-dir": "3.11.0", - "@lerna/run-lifecycle": "3.11.0", - "@lerna/run-parallel-batches": "3.0.0", - "@lerna/symlink-binary": "3.11.0", - "@lerna/symlink-dependencies": "3.11.0", - "@lerna/validation-error": "3.11.0", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.13.1.tgz", + "integrity": "sha512-mKdi5Ds5f82PZwEFyB9/W60I3iELobi1i87sTeVrbJh/um7GvqpSPy7kG/JPxyOdMpB2njX6LiJgw+7b6BEPWw==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/filter-options": "3.13.0", + "@lerna/has-npm-version": "3.13.0", + "@lerna/npm-install": "3.13.0", + "@lerna/package-graph": "3.13.0", + "@lerna/pulse-till-done": "3.13.0", + "@lerna/rimraf-dir": "3.13.0", + "@lerna/run-lifecycle": "3.13.0", + "@lerna/run-parallel-batches": "3.13.0", + "@lerna/symlink-binary": "3.13.0", + "@lerna/symlink-dependencies": "3.13.0", + "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", "get-port": "^3.2.0", "multimatch": "^2.1.0", @@ -189,32 +189,32 @@ } }, "@lerna/changed": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.11.0.tgz", - "integrity": "sha512-owUwGqinBx4YWRelPlYyz+F7TqoyZcYCRPQZG+8F16Bivof5yj3bdnuzx0xzeOSW3WNOWANiaD4rWGdo3rmjeQ==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.13.1.tgz", + "integrity": "sha512-BRXitEJGOkoudbxEewW7WhjkLxFD+tTk4PrYpHLyCBk63pNTWtQLRE6dc1hqwh4emwyGncoyW6RgXfLgMZgryw==", "dev": true, "requires": { - "@lerna/collect-updates": "3.11.0", - "@lerna/command": "3.11.0", - "@lerna/listable": "3.11.0", - "@lerna/output": "3.11.0", - "@lerna/version": "3.11.0" + "@lerna/collect-updates": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/listable": "3.13.0", + "@lerna/output": "3.13.0", + "@lerna/version": "3.13.1" } }, "@lerna/check-working-tree": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.11.0.tgz", - "integrity": "sha512-uWKKmX4BKdK57MyX3rGNHNz4JmFP3tHnaIDDVeuSlgK5KwncPFyRXi3E9H0eiq6DUvDDLtztNOfWeGP2IY656Q==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.13.0.tgz", + "integrity": "sha512-dsdO15NXX5To+Q53SYeCrBEpiqv4m5VkaPZxbGQZNwoRen1MloXuqxSymJANQn+ZLEqarv5V56gydebeROPH5A==", "dev": true, "requires": { - "@lerna/describe-ref": "3.11.0", - "@lerna/validation-error": "3.11.0" + "@lerna/describe-ref": "3.13.0", + "@lerna/validation-error": "3.13.0" } }, "@lerna/child-process": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.3.0.tgz", - "integrity": "sha512-q2d/OPlNX/cBXB6Iz1932RFzOmOHq6ZzPjqebkINNaTojHWuuRpvJJY4Uz3NGpJ3kEtPDvBemkZqUBTSO5wb1g==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.13.0.tgz", + "integrity": "sha512-0iDS8y2jiEucD4fJHEzKoc8aQJgm7s+hG+0RmDNtfT0MM3n17pZnf5JOMtS1FJp+SEXOjMKQndyyaDIPFsnp6A==", "dev": true, "requires": { "chalk": "^2.3.1", @@ -223,57 +223,57 @@ } }, "@lerna/clean": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.11.0.tgz", - "integrity": "sha512-sHyMYv56MIVMH79+5vcxHVdgmd8BcsihI+RL2byW+PeoNlyDeGMjTRmnzLmbSD7dkinHGoa5cghlXy9GGIqpRw==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.13.1.tgz", + "integrity": "sha512-myGIaXv7RUO2qCFZXvx8SJeI+eN6y9SUD5zZ4/LvNogbOiEIlujC5lUAqK65rAHayQ9ltSa/yK6Xv510xhZXZQ==", "dev": true, "requires": { - "@lerna/command": "3.11.0", - "@lerna/filter-options": "3.11.0", - "@lerna/prompt": "3.11.0", - "@lerna/pulse-till-done": "3.11.0", - "@lerna/rimraf-dir": "3.11.0", + "@lerna/command": "3.13.1", + "@lerna/filter-options": "3.13.0", + "@lerna/prompt": "3.13.0", + "@lerna/pulse-till-done": "3.13.0", + "@lerna/rimraf-dir": "3.13.0", "p-map": "^1.2.0", "p-map-series": "^1.0.0", "p-waterfall": "^1.0.0" } }, "@lerna/cli": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.11.0.tgz", - "integrity": "sha512-dn2m2PgUxcb2NyTvwfYOFZf8yN5CMf1uKxht3ajQYdDjRgFi5pUQt/DmdguOZ3CMJkENa0i3yPOmrxGPXLD2aw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.13.0.tgz", + "integrity": "sha512-HgFGlyCZbYaYrjOr3w/EsY18PdvtsTmDfpUQe8HwDjXlPeCCUgliZjXLOVBxSjiOvPeOSwvopwIHKWQmYbwywg==", "dev": true, "requires": { - "@lerna/global-options": "3.10.6", + "@lerna/global-options": "3.13.0", "dedent": "^0.7.0", "npmlog": "^4.1.2", "yargs": "^12.0.1" } }, "@lerna/collect-updates": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.11.0.tgz", - "integrity": "sha512-O0Y18OC2P6j9/RFq+u5Kdq7YxsDd+up3ZRoW6+i0XHWktqxXA9P4JBQppkpYtJVK2yH8QyOzuVLQgtL0xtHdYA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.13.0.tgz", + "integrity": "sha512-uR3u6uTzrS1p46tHQ/mlHog/nRJGBqskTHYYJbgirujxm6FqNh7Do+I1Q/7zSee407G4lzsNxZdm8IL927HemQ==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/describe-ref": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/describe-ref": "3.13.0", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "slash": "^1.0.0" } }, "@lerna/command": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.11.0.tgz", - "integrity": "sha512-N+Z5kauVHSb2VhSIfQexG2VlCAAQ9xYKwVTxYh0JFOFUnZ/QPcoqx4VjynDXASFXXDgcXs4FLaGsJxq83Mf5Zg==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.13.1.tgz", + "integrity": "sha512-SYWezxX+iheWvzRoHCrbs8v5zHPaxAx3kWvZhqi70vuGsdOVAWmaG4IvHLn11ztS+Vpd5PM+ztBWSbnykpLFKQ==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/package-graph": "3.11.0", - "@lerna/project": "3.11.0", - "@lerna/validation-error": "3.11.0", - "@lerna/write-log-file": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/package-graph": "3.13.0", + "@lerna/project": "3.13.1", + "@lerna/validation-error": "3.13.0", + "@lerna/write-log-file": "3.13.0", "dedent": "^0.7.0", "execa": "^1.0.0", "is-ci": "^1.0.10", @@ -282,14 +282,14 @@ } }, "@lerna/conventional-commits": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.11.0.tgz", - "integrity": "sha512-ix1Ki5NiZdk2eMlCWNgLchWPKQTgkJdLeNjneep6OCF3ydSINizReGbFvCftRivun641cOHWswgWMsIxbqhMQw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.13.0.tgz", + "integrity": "sha512-BeAgcNXuocmLhPxnmKU2Vy8YkPd/Uo+vu2i/p3JGsUldzrPC8iF3IDxH7fuXpEFN2Nfogu7KHachd4tchtOppA==", "dev": true, "requires": { - "@lerna/validation-error": "3.11.0", - "conventional-changelog-angular": "^5.0.2", - "conventional-changelog-core": "^3.1.5", + "@lerna/validation-error": "3.13.0", + "conventional-changelog-angular": "^5.0.3", + "conventional-changelog-core": "^3.1.6", "conventional-recommended-bump": "^4.0.4", "fs-extra": "^7.0.0", "get-stream": "^4.0.0", @@ -308,15 +308,15 @@ } }, "@lerna/create": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.11.0.tgz", - "integrity": "sha512-1izS82QML+H/itwEu1GPrcoXyugFaP9z9r6KuIQRQq8RtmNCGEmK85aiOw6mukyRcRziq2akALgFDyrundznPQ==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.13.1.tgz", + "integrity": "sha512-pLENMXgTkQuvKxAopjKeoLOv9fVUCnpTUD7aLrY5d95/1xqSZlnsOcQfUYcpMf3GpOvHc8ILmI5OXkPqjAf54g==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/command": "3.11.0", - "@lerna/npm-conf": "3.7.0", - "@lerna/validation-error": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/npm-conf": "3.13.0", + "@lerna/validation-error": "3.13.0", "camelcase": "^5.0.0", "dedent": "^0.7.0", "fs-extra": "^7.0.0", @@ -324,7 +324,7 @@ "init-package-json": "^1.10.3", "npm-package-arg": "^6.1.0", "p-reduce": "^1.0.0", - "pacote": "^9.4.1", + "pacote": "^9.5.0", "pify": "^3.0.0", "semver": "^5.5.0", "slash": "^1.0.0", @@ -334,9 +334,9 @@ }, "dependencies": { "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", "dev": true }, "pify": { @@ -348,9 +348,9 @@ } }, "@lerna/create-symlink": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-3.11.0.tgz", - "integrity": "sha512-UDR32uos8FIEc1keMKxXj5goZAHpCbpUd4u/btHXymUL9WqIym3cgz2iMr3ZNdZtjdMyUoHup5Dp0zjSgKCaEA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-3.13.0.tgz", + "integrity": "sha512-PTvg3jAAJSAtLFoZDsuTMv1wTOC3XYIdtg54k7uxIHsP8Ztpt+vlilY/Cni0THAqEMHvfiToel76Xdta4TU21Q==", "dev": true, "requires": { "cmd-shim": "^2.0.2", @@ -359,76 +359,76 @@ } }, "@lerna/describe-ref": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.11.0.tgz", - "integrity": "sha512-lX/NVMqeODg4q/igN06L/KjtVUpW1oawh6IgOINy2oqm4RUR+1yDpsdVu3JyZZ4nHB572mJfbW56dl8qoxEVvQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.13.0.tgz", + "integrity": "sha512-UJefF5mLxLae9I2Sbz5RLYGbqbikRuMqdgTam0MS5OhXnyuuKYBUpwBshCURNb1dPBXTQhSwc7+oUhORx8ojCg==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", + "@lerna/child-process": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/diff": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.11.0.tgz", - "integrity": "sha512-r3WASQix31ApA0tlkZejXhS8Z3SEg6Jw9YnKDt9V6wLjEUXGLauUDMrgx1YWu3cs9KB8/hqheRyRI7XAXGJS1w==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.13.1.tgz", + "integrity": "sha512-cKqmpONO57mdvxtp8e+l5+tjtmF04+7E+O0QEcLcNUAjC6UR2OSM77nwRCXDukou/1h72JtWs0jjcdYLwAmApg==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/command": "3.11.0", - "@lerna/validation-error": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/validation-error": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/exec": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.11.0.tgz", - "integrity": "sha512-oIkI+Hj74kpsnHhw0qJj12H4XMPSlDbBsshLWY+f3BiwKhn6wkXoQZ1FC8/OVNHM67GtSRv4bkcOaM4ucHm9Hw==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.13.1.tgz", + "integrity": "sha512-I34wEP9lrAqqM7tTXLDxv/6454WFzrnXDWpNDbiKQiZs6SIrOOjmm6I4FiQsx+rU3o9d+HkC6tcUJRN5mlJUgA==", "dev": true, "requires": { - "@lerna/batch-packages": "3.11.0", - "@lerna/child-process": "3.3.0", - "@lerna/command": "3.11.0", - "@lerna/filter-options": "3.11.0", - "@lerna/run-parallel-batches": "3.0.0", - "@lerna/validation-error": "3.11.0" + "@lerna/batch-packages": "3.13.0", + "@lerna/child-process": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/filter-options": "3.13.0", + "@lerna/run-parallel-batches": "3.13.0", + "@lerna/validation-error": "3.13.0" } }, "@lerna/filter-options": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.11.0.tgz", - "integrity": "sha512-z0krgC/YBqz7i6MGHBsPLvsQ++XEpPdGnIkSpcN0Cjp5J67K9vb5gJ2hWp1c1bitNh3xiwZ69voGqN+DYk1mUg==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.13.0.tgz", + "integrity": "sha512-SRp7DCo9zrf+7NkQxZMkeyO1GRN6GICoB9UcBAbXhLbWisT37Cx5/6+jh49gYB63d/0/WYHSEPMlheUrpv1Srw==", "dev": true, "requires": { - "@lerna/collect-updates": "3.11.0", - "@lerna/filter-packages": "3.11.0", + "@lerna/collect-updates": "3.13.0", + "@lerna/filter-packages": "3.13.0", "dedent": "^0.7.0" } }, "@lerna/filter-packages": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.11.0.tgz", - "integrity": "sha512-bnukkW1M0uMKWqM/m/IHou2PKRyk4fDAksAj3diHc1UVQkH2j8hXOfLl9+CgHA/cnTrf6/LARg8hKujqduqHyA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.13.0.tgz", + "integrity": "sha512-RWiZWyGy3Mp7GRVBn//CacSnE3Kw82PxE4+H6bQ3pDUw/9atXn7NRX+gkBVQIYeKamh7HyumJtyOKq3Pp9BADQ==", "dev": true, "requires": { - "@lerna/validation-error": "3.11.0", + "@lerna/validation-error": "3.13.0", "multimatch": "^2.1.0", "npmlog": "^4.1.2" } }, "@lerna/get-npm-exec-opts": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.11.0.tgz", - "integrity": "sha512-EDxsbuq2AbB3LWwH/4SOcn4gWOnoIYrSHfITWo7xz/SbEKeHtiva99l424ZRWUJqLPGIpQiMTlmOET2ZEI8WZg==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.13.0.tgz", + "integrity": "sha512-Y0xWL0rg3boVyJk6An/vurKzubyJKtrxYv2sj4bB8Mc5zZ3tqtv0ccbOkmkXKqbzvNNF7VeUt1OJ3DRgtC/QZw==", "dev": true, "requires": { "npmlog": "^4.1.2" } }, "@lerna/get-packed": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-3.7.0.tgz", - "integrity": "sha512-yuFtjsUZIHjeIvIYQ/QuytC+FQcHwo3peB+yGBST2uWCLUCR5rx6knoQcPzbxdFDCuUb5IFccFGd3B1fHFg3RQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-3.13.0.tgz", + "integrity": "sha512-EgSim24sjIjqQDC57bgXD9l22/HCS93uQBbGpkzEOzxAVzEgpZVm7Fm1t8BVlRcT2P2zwGnRadIvxTbpQuDPTg==", "dev": true, "requires": { "fs-extra": "^7.0.0", @@ -454,103 +454,103 @@ } }, "@lerna/github-client": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.11.0.tgz", - "integrity": "sha512-yPMBhzShuth3uJo0kKu84RvgjSZgOYNT8fKfhZmzTeVGuPbYBKlK+UQ6jjpb6E9WW2BVdiUCrFhqIsbK5Lqe7A==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.13.1.tgz", + "integrity": "sha512-iPLUp8FFoAKGURksYEYZzfuo9TRA+NepVlseRXFaWlmy36dCQN20AciINpoXiXGoHcEUHXUKHQvY3ARFdMlf3w==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@octokit/plugin-enterprise-rest": "^2.1.0", - "@octokit/rest": "^16.15.0", + "@lerna/child-process": "3.13.0", + "@octokit/plugin-enterprise-rest": "^2.1.1", + "@octokit/rest": "^16.16.0", "git-url-parse": "^11.1.2", "npmlog": "^4.1.2" } }, "@lerna/global-options": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.10.6.tgz", - "integrity": "sha512-k5Xkq1M/uREFC2R9uwN5gcvIgjj4iOXo0YyeEXCMWBiW3j2GL9xN4d1MmAIcrYlAzVYh6kLlWaFWl/rNIneHIw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.13.0.tgz", + "integrity": "sha512-SlZvh1gVRRzYLVluz9fryY1nJpZ0FHDGB66U9tFfvnnxmueckRQxLopn3tXj3NU1kc3QANT2I5BsQkOqZ4TEFQ==", "dev": true }, "@lerna/has-npm-version": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.10.0.tgz", - "integrity": "sha512-N4RRYxGeivuaKgPDzrhkQOQs1Sg4tOnxnEe3akfqu1wDA4Ng5V6Y2uW3DbkAjFL3aNJhWF5Vbf7sBsGtfgDQ8w==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.13.0.tgz", + "integrity": "sha512-Oqu7DGLnrMENPm+bPFGOHnqxK8lCnuYr6bk3g/CoNn8/U0qgFvHcq6Iv8/Z04TsvleX+3/RgauSD2kMfRmbypg==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", + "@lerna/child-process": "3.13.0", "semver": "^5.5.0" } }, "@lerna/import": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.11.0.tgz", - "integrity": "sha512-WgF0We+4k/MrC1vetT8pt3/SSJPMvXhyPYmL2W9rcvch3zV0IgLyso4tEs8gNbwZorDVEG1KcM+x8TG4v1nV5Q==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.13.1.tgz", + "integrity": "sha512-A1Vk1siYx1XkRl6w+zkaA0iptV5TIynVlHPR9S7NY0XAfhykjztYVvwtxarlh6+VcNrO9We6if0+FXCrfDEoIg==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/command": "3.11.0", - "@lerna/prompt": "3.11.0", - "@lerna/pulse-till-done": "3.11.0", - "@lerna/validation-error": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/prompt": "3.13.0", + "@lerna/pulse-till-done": "3.13.0", + "@lerna/validation-error": "3.13.0", "dedent": "^0.7.0", "fs-extra": "^7.0.0", "p-map-series": "^1.0.0" } }, "@lerna/init": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.11.0.tgz", - "integrity": "sha512-JZC5jpCVJgK34grye52kGWjrYCyh4LB8c0WBLaS8MOUt6rxTtPqubwvCDKPOF2H0Se6awsgEfX4wWNuqiQVpRQ==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.13.1.tgz", + "integrity": "sha512-M59WACqim8WkH5FQEGOCEZ89NDxCKBfFTx4ZD5ig3LkGyJ8RdcJq5KEfpW/aESuRE9JrZLzVr0IjKbZSxzwEMA==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/command": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/command": "3.13.1", "fs-extra": "^7.0.0", "p-map": "^1.2.0", "write-json-file": "^2.3.0" } }, "@lerna/link": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.11.0.tgz", - "integrity": "sha512-QN+kxRWb6P9jrKpE2t6K9sGnFpqy1KOEjf68NpGhmp+J9Yt6Kvz9kG43CWoqg4Zyqqgqgn3NVV2Z7zSDNhdH0g==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.13.1.tgz", + "integrity": "sha512-N3h3Fj1dcea+1RaAoAdy4g2m3fvU7m89HoUn5X/Zcw5n2kPoK8kTO+NfhNAatfRV8VtMXst8vbNrWQQtfm0FFw==", "dev": true, "requires": { - "@lerna/command": "3.11.0", - "@lerna/package-graph": "3.11.0", - "@lerna/symlink-dependencies": "3.11.0", + "@lerna/command": "3.13.1", + "@lerna/package-graph": "3.13.0", + "@lerna/symlink-dependencies": "3.13.0", "p-map": "^1.2.0", "slash": "^1.0.0" } }, "@lerna/list": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.11.0.tgz", - "integrity": "sha512-hBAwZzEzF1LQOOB2/5vQkal/nSriuJbLY39BitIGkUxifsmu7JK0k3LYrwe1sxXv5SMf2HDaTLr+Z23mUslhaQ==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.13.1.tgz", + "integrity": "sha512-635iRbdgd9gNvYLLIbYdQCQLr+HioM5FGJLFS0g3DPGygr6iDR8KS47hzCRGH91LU9NcM1mD1RoT/AChF+QbiA==", "dev": true, "requires": { - "@lerna/command": "3.11.0", - "@lerna/filter-options": "3.11.0", - "@lerna/listable": "3.11.0", - "@lerna/output": "3.11.0" + "@lerna/command": "3.13.1", + "@lerna/filter-options": "3.13.0", + "@lerna/listable": "3.13.0", + "@lerna/output": "3.13.0" } }, "@lerna/listable": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.11.0.tgz", - "integrity": "sha512-nCrtGSS3YiAlh5dU5mmTAU9aLRlmIUn2FnahqsksN2uQ5O4o+614tneDuO298/eWLZo00eGw69EFngaQEl8quw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.13.0.tgz", + "integrity": "sha512-liYJ/WBUYP4N4MnSVZuLUgfa/jy3BZ02/1Om7xUY09xGVSuNVNEeB8uZUMSC+nHqFHIsMPZ8QK9HnmZb1E/eTA==", "dev": true, "requires": { - "@lerna/batch-packages": "3.11.0", + "@lerna/batch-packages": "3.13.0", "chalk": "^2.3.1", "columnify": "^1.5.4" } }, "@lerna/log-packed": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-3.11.0.tgz", - "integrity": "sha512-TH//81TzSTMuNzJIQE7zqu+ymI5rH25jdEdmbYEWmaJ+T42GMQXKxP8cj2m+fWRaDML8ta0uzBOm5PKHdgoFYQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-3.13.0.tgz", + "integrity": "sha512-Rmjrcz+6aM6AEcEVWmurbo8+AnHOvYtDpoeMMJh9IZ9SmZr2ClXzmD7wSvjTQc8BwOaiWjjC/ukcT0UYA2m7wg==", "dev": true, "requires": { "byte-size": "^4.0.3", @@ -560,9 +560,9 @@ } }, "@lerna/npm-conf": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.7.0.tgz", - "integrity": "sha512-+WSMDfPKcKzMfqq283ydz9RRpOU6p9wfx0wy4hVSUY/6YUpsyuk8SShjcRtY8zTM5AOrxvFBuuV90H4YpZ5+Ng==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.13.0.tgz", + "integrity": "sha512-Jg2kANsGnhg+fbPEzE0X9nX5oviEAvWj0nYyOkcE+cgWuT7W0zpnPXC4hA4C5IPQGhwhhh0IxhWNNHtjTuw53g==", "dev": true, "requires": { "config-chain": "^1.1.11", @@ -578,9 +578,9 @@ } }, "@lerna/npm-dist-tag": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.11.0.tgz", - "integrity": "sha512-WqZcyDb+wiqAKRFcYEK6R8AQfspyro85zGGHyjYw6ZPNgJX3qhwtQ+MidDmOesi2p5/0GfeVSWega+W7fPzVpg==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.13.0.tgz", + "integrity": "sha512-mcuhw34JhSRFrbPn0vedbvgBTvveG52bR2lVE3M3tfE8gmR/cKS/EJFO4AUhfRKGCTFn9rjaSEzlFGYV87pemQ==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -590,13 +590,13 @@ } }, "@lerna/npm-install": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.11.0.tgz", - "integrity": "sha512-iNKEgFvFHMmBqn9AnFye2rv7CdUBlYciwWSTNtpfVqtOnoL/lg+4A774oL4PDoxTCGmougztyxMkqLVSBYXTpw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.13.0.tgz", + "integrity": "sha512-qNyfts//isYQxore6fsPorNYJmPVKZ6tOThSH97tP0aV91zGMtrYRqlAoUnDwDdAjHPYEM16hNujg2wRmsqqIw==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/get-npm-exec-opts": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/get-npm-exec-opts": "3.13.0", "fs-extra": "^7.0.0", "npm-package-arg": "^6.1.0", "npmlog": "^4.1.2", @@ -605,12 +605,12 @@ } }, "@lerna/npm-publish": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.11.0.tgz", - "integrity": "sha512-wgbb55gUXRlP8uTe60oW6c06ZhquaJu9xbi2vWNpb5Fmjh/KbZ2iNm9Kj2ciZlvb8D+k4Oc3qV7slBGxyMm8wg==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.13.0.tgz", + "integrity": "sha512-y4WO0XTaf9gNRkI7as6P2ItVDOxmYHwYto357fjybcnfXgMqEA94c3GJ++jU41j0A9vnmYC6/XxpTd9sVmH9tA==", "dev": true, "requires": { - "@lerna/run-lifecycle": "3.11.0", + "@lerna/run-lifecycle": "3.13.0", "figgy-pudding": "^3.5.1", "fs-extra": "^7.0.0", "libnpmpublish": "^1.1.1", @@ -628,36 +628,36 @@ } }, "@lerna/npm-run-script": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.11.0.tgz", - "integrity": "sha512-cLnTMrRQlK/N5bCr6joOFMBfRyW2EbMdk3imtjHk0LwZxsvQx3naAPUB/2RgNfC8fGf/yHF/0bmBrpb5sa2IlA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.13.0.tgz", + "integrity": "sha512-hiL3/VeVp+NFatBjkGN8mUdX24EfZx9rQlSie0CMgtjc7iZrtd0jCguLomSCRHYjJuvqgbp+LLYo7nHVykfkaQ==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", - "@lerna/get-npm-exec-opts": "3.11.0", + "@lerna/child-process": "3.13.0", + "@lerna/get-npm-exec-opts": "3.13.0", "npmlog": "^4.1.2" } }, "@lerna/output": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/output/-/output-3.11.0.tgz", - "integrity": "sha512-xHYGcEaZZ4cR0Jw368QgUgFvV27a6ZO5360BMNGNsjCjuY0aOPQC5+lBhgfydJtJteKjDna853PSjBK3uMhEjw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/output/-/output-3.13.0.tgz", + "integrity": "sha512-7ZnQ9nvUDu/WD+bNsypmPG5MwZBwu86iRoiW6C1WBuXXDxM5cnIAC1m2WxHeFnjyMrYlRXM9PzOQ9VDD+C15Rg==", "dev": true, "requires": { "npmlog": "^4.1.2" } }, "@lerna/pack-directory": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.11.0.tgz", - "integrity": "sha512-bgA3TxZx5AyZeqUadSPspktdecW7nIpg/ODq0o0gKFr7j+DC9Fqu8vQa2xmFSKsXDtOYkCV0jox6Ox9XSFSM3A==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.13.1.tgz", + "integrity": "sha512-kXnyqrkQbCIZOf1054N88+8h0ItC7tUN5v9ca/aWpx298gsURpxUx/1TIKqijL5TOnHMyIkj0YJmnH/PyBVLKA==", "dev": true, "requires": { - "@lerna/get-packed": "3.7.0", - "@lerna/package": "3.11.0", - "@lerna/run-lifecycle": "3.11.0", + "@lerna/get-packed": "3.13.0", + "@lerna/package": "3.13.0", + "@lerna/run-lifecycle": "3.13.0", "figgy-pudding": "^3.5.1", - "npm-packlist": "^1.1.12", + "npm-packlist": "^1.4.1", "npmlog": "^4.1.2", "tar": "^4.4.8", "temp-write": "^3.4.0" @@ -681,9 +681,9 @@ } }, "@lerna/package": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/package/-/package-3.11.0.tgz", - "integrity": "sha512-hMzBhFEubhg+Tis5C8skwIfgOk+GTl0qudvzfPU9gQqLV8u4/Hs6mka6N0rKgbUb4VFVc5MJVe1eZ6Rv+kJAWw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/package/-/package-3.13.0.tgz", + "integrity": "sha512-kSKO0RJQy093BufCQnkhf1jB4kZnBvL7kK5Ewolhk5gwejN+Jofjd8DGRVUDUJfQ0CkW1o6GbUeZvs8w8VIZDg==", "dev": true, "requires": { "load-json-file": "^4.0.0", @@ -728,25 +728,25 @@ } }, "@lerna/package-graph": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.11.0.tgz", - "integrity": "sha512-ICYiOZvCfcmeH1qfzOkFYh0t0QA56OddQfI3ydxCiWi5G+UupJXnCIWSTh3edTAtw/kyxhCOWny/PJsG4CQfjA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.13.0.tgz", + "integrity": "sha512-3mRF1zuqFE1HEFmMMAIggXy+f+9cvHhW/jzaPEVyrPNLKsyfJQtpTNzeI04nfRvbAh+Gd2aNksvaW/w3xGJnnw==", "dev": true, "requires": { - "@lerna/validation-error": "3.11.0", + "@lerna/validation-error": "3.13.0", "npm-package-arg": "^6.1.0", "semver": "^5.5.0" } }, "@lerna/project": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.11.0.tgz", - "integrity": "sha512-j3DGds+q/q2YNpoBImaEsMpkWgu5gP0IGKz1o1Ju39NZKrTPza+ARIzEByL4Jqu87tcoOj7RbZzhhrBP8JBbTg==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.13.1.tgz", + "integrity": "sha512-/GoCrpsCCTyb9sizk1+pMBrIYchtb+F1uCOn3cjn9yenyG/MfYEnlfrbV5k/UDud0Ei75YBLbmwCbigHkAKazQ==", "dev": true, "requires": { - "@lerna/package": "3.11.0", - "@lerna/validation-error": "3.11.0", - "cosmiconfig": "^5.0.2", + "@lerna/package": "3.13.0", + "@lerna/validation-error": "3.13.0", + "cosmiconfig": "^5.1.0", "dedent": "^0.7.0", "dot-prop": "^4.2.0", "glob-parent": "^3.1.0", @@ -795,9 +795,9 @@ } }, "@lerna/prompt": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-3.11.0.tgz", - "integrity": "sha512-SB/wvyDPQASze9txd+8/t24p6GiJuhhL30zxuRwvVwER5lIJR7kaXy1KhQ7kUAKPlNTVfCBm3GXReIMl4jhGhw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-3.13.0.tgz", + "integrity": "sha512-P+lWSFokdyvYpkwC3it9cE0IF2U5yy2mOUbGvvE4iDb9K7TyXGE+7lwtx2thtPvBAfIb7O13POMkv7df03HJeA==", "dev": true, "requires": { "inquirer": "^6.2.0", @@ -805,29 +805,29 @@ } }, "@lerna/publish": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.11.0.tgz", - "integrity": "sha512-8vdb5YOnPphIig4FCXwuLAdptFNfMcCj/TMCwtsFDQqNbeCbVABkptqjfmldVmGfcxwbkqHLH7cbazVSIGPonA==", - "dev": true, - "requires": { - "@lerna/batch-packages": "3.11.0", - "@lerna/check-working-tree": "3.11.0", - "@lerna/child-process": "3.3.0", - "@lerna/collect-updates": "3.11.0", - "@lerna/command": "3.11.0", - "@lerna/describe-ref": "3.11.0", - "@lerna/log-packed": "3.11.0", - "@lerna/npm-conf": "3.7.0", - "@lerna/npm-dist-tag": "3.11.0", - "@lerna/npm-publish": "3.11.0", - "@lerna/output": "3.11.0", - "@lerna/pack-directory": "3.11.0", - "@lerna/prompt": "3.11.0", - "@lerna/pulse-till-done": "3.11.0", - "@lerna/run-lifecycle": "3.11.0", - "@lerna/run-parallel-batches": "3.0.0", - "@lerna/validation-error": "3.11.0", - "@lerna/version": "3.11.0", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.13.1.tgz", + "integrity": "sha512-KhCJ9UDx76HWCF03i5TD7z5lX+2yklHh5SyO8eDaLptgdLDQ0Z78lfGj3JhewHU2l46FztmqxL/ss0IkWHDL+g==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.13.0", + "@lerna/check-working-tree": "3.13.0", + "@lerna/child-process": "3.13.0", + "@lerna/collect-updates": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/describe-ref": "3.13.0", + "@lerna/log-packed": "3.13.0", + "@lerna/npm-conf": "3.13.0", + "@lerna/npm-dist-tag": "3.13.0", + "@lerna/npm-publish": "3.13.0", + "@lerna/output": "3.13.0", + "@lerna/pack-directory": "3.13.1", + "@lerna/prompt": "3.13.0", + "@lerna/pulse-till-done": "3.13.0", + "@lerna/run-lifecycle": "3.13.0", + "@lerna/run-parallel-batches": "3.13.0", + "@lerna/validation-error": "3.13.0", + "@lerna/version": "3.13.1", "figgy-pudding": "^3.5.1", "fs-extra": "^7.0.0", "libnpmaccess": "^3.0.1", @@ -838,23 +838,23 @@ "p-map": "^1.2.0", "p-pipe": "^1.2.0", "p-reduce": "^1.0.0", - "pacote": "^9.4.1", + "pacote": "^9.5.0", "semver": "^5.5.0" } }, "@lerna/pulse-till-done": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-3.11.0.tgz", - "integrity": "sha512-nMwBa6S4+VI/ketN92oj1xr8y74Fz4ul2R5jdbrRqLLEU/IMBWIqn6NRM2P+OQBoLpPZ2MdWENLJVFNN8X1Q+A==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-3.13.0.tgz", + "integrity": "sha512-1SOHpy7ZNTPulzIbargrgaJX387csN7cF1cLOGZiJQA6VqnS5eWs2CIrG8i8wmaUavj2QlQ5oEbRMVVXSsGrzA==", "dev": true, "requires": { "npmlog": "^4.1.2" } }, "@lerna/resolve-symlink": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-3.11.0.tgz", - "integrity": "sha512-lDer8zPXS36iL4vJdZwOk6AnuUjDXswoTWdYkl+HdAKXp7cBlS+VeGmcFIJS4R3mSSZE20h1oEDuH8h8GGORIQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-3.13.0.tgz", + "integrity": "sha512-Lc0USSFxwDxUs5JvIisS8JegjA6SHSAWJCMvi2osZx6wVRkEDlWG2B1JAfXUzCMNfHoZX0/XX9iYZ+4JIpjAtg==", "dev": true, "requires": { "fs-extra": "^7.0.0", @@ -863,12 +863,12 @@ } }, "@lerna/rimraf-dir": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.11.0.tgz", - "integrity": "sha512-roy4lKel7BMNLfFvyzK0HI251mgI9EwbpOccR2Waz0V22d0gaqLKzfVrzovat9dVHXrKNxAhJ5iKkKeT93IunQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.13.0.tgz", + "integrity": "sha512-kte+pMemulre8cmPqljxIYjCmdLByz8DgHBHXB49kz2EiPf8JJ+hJFt0PzEubEyJZ2YE2EVAx5Tv5+NfGNUQyQ==", "dev": true, "requires": { - "@lerna/child-process": "3.3.0", + "@lerna/child-process": "3.13.0", "npmlog": "^4.1.2", "path-exists": "^3.0.0", "rimraf": "^2.6.2" @@ -883,38 +883,38 @@ } }, "@lerna/run": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.11.0.tgz", - "integrity": "sha512-8c2yzbKJFzgO6VTOftWmB0fOLTL7G1GFAG5UTVDSk95Z2Gnjof3I/Xkvtbzq8L+DIOLpr+Tpj3fRBjZd8rONlA==", - "dev": true, - "requires": { - "@lerna/batch-packages": "3.11.0", - "@lerna/command": "3.11.0", - "@lerna/filter-options": "3.11.0", - "@lerna/npm-run-script": "3.11.0", - "@lerna/output": "3.11.0", - "@lerna/run-parallel-batches": "3.0.0", - "@lerna/timer": "3.5.0", - "@lerna/validation-error": "3.11.0", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.13.1.tgz", + "integrity": "sha512-nv1oj7bsqppWm1M4ifN+/IIbVu9F4RixrbQD2okqDGYne4RQPAXyb5cEZuAzY/wyGTWWiVaZ1zpj5ogPWvH0bw==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/filter-options": "3.13.0", + "@lerna/npm-run-script": "3.13.0", + "@lerna/output": "3.13.0", + "@lerna/run-parallel-batches": "3.13.0", + "@lerna/timer": "3.13.0", + "@lerna/validation-error": "3.13.0", "p-map": "^1.2.0" } }, "@lerna/run-lifecycle": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.11.0.tgz", - "integrity": "sha512-3xeeVz9s3Dh2ljKqJI/Fl+gkZD9Y8JblAN62f4WNM76d/zFlgpCXDs62OpxNjEuXujA7YFix0sJ+oPKMm8mDrw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.13.0.tgz", + "integrity": "sha512-oyiaL1biZdjpmjh6X/5C4w07wNFyiwXSSHH5GQB4Ay4BPwgq9oNhCcxRoi0UVZlZ1YwzSW8sTwLgj8emkIo3Yg==", "dev": true, "requires": { - "@lerna/npm-conf": "3.7.0", + "@lerna/npm-conf": "3.13.0", "figgy-pudding": "^3.5.1", "npm-lifecycle": "^2.1.0", "npmlog": "^4.1.2" } }, "@lerna/run-parallel-batches": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@lerna/run-parallel-batches/-/run-parallel-batches-3.0.0.tgz", - "integrity": "sha512-Mj1ravlXF7AkkewKd9YFq9BtVrsStNrvVLedD/b2wIVbNqcxp8lS68vehXVOzoL/VWNEDotvqCQtyDBilCodGw==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/run-parallel-batches/-/run-parallel-batches-3.13.0.tgz", + "integrity": "sha512-bICFBR+cYVF1FFW+Tlm0EhWDioTUTM6dOiVziDEGE1UZha1dFkMYqzqdSf4bQzfLS31UW/KBd/2z8jy2OIjEjg==", "dev": true, "requires": { "p-map": "^1.2.0", @@ -922,26 +922,26 @@ } }, "@lerna/symlink-binary": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.11.0.tgz", - "integrity": "sha512-5sOED+1O8jI+ckDS6DRUKtAtbKo7lbxFIJs6sWWEu5qKzM5e21O6E2wTWimJkad8nJ1SJAuyc8DC8M8ki4kT4w==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.13.0.tgz", + "integrity": "sha512-obc4Y6jxywkdaCe+DB0uTxYqP0IQ8mFWvN+k/YMbwH4G2h7M7lCBWgPy8e7xw/50+1II9tT2sxgx+jMus1sTJg==", "dev": true, "requires": { - "@lerna/create-symlink": "3.11.0", - "@lerna/package": "3.11.0", + "@lerna/create-symlink": "3.13.0", + "@lerna/package": "3.13.0", "fs-extra": "^7.0.0", "p-map": "^1.2.0" } }, "@lerna/symlink-dependencies": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.11.0.tgz", - "integrity": "sha512-XKNX8oOgcOmiKHUn7qT5GvvmKP3w5otZPOjRixUDUILWTc3P8nO5I1VNILNF6IE5ajNw6yiXOWikSxc6KuFqBQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.13.0.tgz", + "integrity": "sha512-7CyN5WYEPkbPLbqHBIQg/YiimBzb5cIGQB0E9IkLs3+racq2vmUNQZn38LOaazQacAA83seB+zWSxlI6H+eXSg==", "dev": true, "requires": { - "@lerna/create-symlink": "3.11.0", - "@lerna/resolve-symlink": "3.11.0", - "@lerna/symlink-binary": "3.11.0", + "@lerna/create-symlink": "3.13.0", + "@lerna/resolve-symlink": "3.13.0", + "@lerna/symlink-binary": "3.13.0", "fs-extra": "^7.0.0", "p-finally": "^1.0.0", "p-map": "^1.2.0", @@ -949,37 +949,37 @@ } }, "@lerna/timer": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-3.5.0.tgz", - "integrity": "sha512-TAb99hqQN6E3JBGtG9iyZNPq1/DbmqgBOeNrKtdJsGvIeX/NGLgUDWMrj2h04V4O+jpBFmSf6HIld6triKmxCA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-3.13.0.tgz", + "integrity": "sha512-RHWrDl8U4XNPqY5MQHkToWS9jHPnkLZEt5VD+uunCKTfzlxGnRCr3/zVr8VGy/uENMYpVP3wJa4RKGY6M0vkRw==", "dev": true }, "@lerna/validation-error": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-3.11.0.tgz", - "integrity": "sha512-/mS4o6QYm4OXUqfPJnW1mKudGhvhLe9uiQ9eK2cgSxkCAVq9G2Sl/KVohpnqAgeRI3nXordGxHS745CdAhg7pA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-3.13.0.tgz", + "integrity": "sha512-SiJP75nwB8GhgwLKQfdkSnDufAaCbkZWJqEDlKOUPUvVOplRGnfL+BPQZH5nvq2BYSRXsksXWZ4UHVnQZI/HYA==", "dev": true, "requires": { "npmlog": "^4.1.2" } }, "@lerna/version": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.11.0.tgz", - "integrity": "sha512-J6Ffq1qU7hYwgmn7vM1QlhkBUH1wakG5wiHWv6Pk4XpCCA+PoHKTjCbpovmFIIYOI19QGYpdZV9C8dST/0aPiA==", - "dev": true, - "requires": { - "@lerna/batch-packages": "3.11.0", - "@lerna/check-working-tree": "3.11.0", - "@lerna/child-process": "3.3.0", - "@lerna/collect-updates": "3.11.0", - "@lerna/command": "3.11.0", - "@lerna/conventional-commits": "3.11.0", - "@lerna/github-client": "3.11.0", - "@lerna/output": "3.11.0", - "@lerna/prompt": "3.11.0", - "@lerna/run-lifecycle": "3.11.0", - "@lerna/validation-error": "3.11.0", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.13.1.tgz", + "integrity": "sha512-WpfKc5jZBBOJ6bFS4atPJEbHSiywQ/Gcd+vrwaEGyQHWHQZnPTvhqLuq3q9fIb9sbuhH5pSY6eehhuBrKqTnjg==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.13.0", + "@lerna/check-working-tree": "3.13.0", + "@lerna/child-process": "3.13.0", + "@lerna/collect-updates": "3.13.0", + "@lerna/command": "3.13.1", + "@lerna/conventional-commits": "3.13.0", + "@lerna/github-client": "3.13.1", + "@lerna/output": "3.13.0", + "@lerna/prompt": "3.13.0", + "@lerna/run-lifecycle": "3.13.0", + "@lerna/validation-error": "3.13.0", "chalk": "^2.3.1", "dedent": "^0.7.0", "minimatch": "^3.0.4", @@ -994,9 +994,9 @@ } }, "@lerna/write-log-file": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-3.11.0.tgz", - "integrity": "sha512-skpTDMDOkQAN4lCeAoI6/rPhbNE431eD0i6Ts3kExUOrYTr0m5CIwVtMZ31Flpky0Jfh4ET6rOl5SDNMLbf4VA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-3.13.0.tgz", + "integrity": "sha512-RibeMnDPvlL8bFYW5C8cs4mbI3AHfQef73tnJCQ/SgrXZHehmHnsyWUiE7qDQCAo+B1RfTapvSyFF69iPj326A==", "dev": true, "requires": { "npmlog": "^4.1.2", @@ -1020,43 +1020,45 @@ "dev": true }, "@octokit/endpoint": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-3.1.2.tgz", - "integrity": "sha512-iRx4kDYybAv9tOrHDBE6HwlgiFi8qmbZl8SHliZWtxbUFuXLZXh2yv8DxGIK9wzD9J0wLDMZneO8vNYJNUSJ9Q==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-3.1.3.tgz", + "integrity": "sha512-vAWzeoj9Lzpl3V3YkWKhGzmDUoMfKpyxJhpq74/ohMvmLXDoEuAGnApy/7TRi3OmnjyX2Lr+e9UGGAD0919ohA==", "dev": true, "requires": { - "deepmerge": "3.1.0", + "deepmerge": "3.2.0", "is-plain-object": "^2.0.4", "universal-user-agent": "^2.0.1", "url-template": "^2.0.8" } }, "@octokit/plugin-enterprise-rest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.1.1.tgz", - "integrity": "sha512-DJNXHH0LptKCLpJ8y3vCA/O+s+3/sDU4JNN2V0M04tsMN0hVGLPzoGgejPJgaxGP8Il5aw+jA5Nl5mTfdt9NrQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.2.0.tgz", + "integrity": "sha512-/uXIvjK5bxmMKI1MDZXxVSiheiyvqv7GCWjoN1s43jF3MMrfqnErOwbZkreeL0CgO1R2lNW6dESDV5NbRiWEQA==", "dev": true }, "@octokit/request": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-2.3.0.tgz", - "integrity": "sha512-5YRqYNZOAaL7+nt7w3Scp6Sz4P2g7wKFP9npx1xdExMomk8/M/ICXVLYVam2wzxeY0cIc6wcKpjC5KI4jiNbGw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-2.4.1.tgz", + "integrity": "sha512-nN8W24ZXEpJQJoVgMsGZeK9FOzxkc39Xn9ykseUpPpPMNEDFSvqfkCeqqKrjUiXRm72ubGLWG1SOz0aJPcgGww==", "dev": true, "requires": { "@octokit/endpoint": "^3.1.1", + "deprecation": "^1.0.1", "is-plain-object": "^2.0.4", "node-fetch": "^2.3.0", + "once": "^1.4.0", "universal-user-agent": "^2.0.1" } }, "@octokit/rest": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.15.0.tgz", - "integrity": "sha512-Un+e7rgh38RtPOTe453pT/KPM/p2KZICimBmuZCd2wEo8PacDa4h6RqTPZs+f2DPazTTqdM7QU4LKlUjgiBwWw==", + "version": "16.17.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.17.0.tgz", + "integrity": "sha512-1RB7e4ptR/M+1Ik3Qn84pbppbSadBaCtpgFqgqsXn6s4ZVE6hqW9SOm6UW5yd3KT7ObVfdYUkhMlgR937oKyDw==", "dev": true, "requires": { - "@octokit/request": "2.3.0", - "before-after-hook": "^1.2.0", + "@octokit/request": "2.4.1", + "before-after-hook": "^1.4.0", "btoa-lite": "^1.0.0", "lodash.get": "^4.4.2", "lodash.set": "^4.3.2", @@ -1083,9 +1085,9 @@ "dev": true }, "acorn": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", - "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true }, "acorn-jsx": { @@ -1113,9 +1115,9 @@ } }, "ajv": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", - "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1441,9 +1443,9 @@ } }, "before-after-hook": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.3.2.tgz", - "integrity": "sha512-zyPgY5dgbf99c0uGUjhY4w+mxqEGxPKg9RQDl34VvrVh2bM31lFN+mwR1ZHepq/KA3VCPk1gwJZL6IIJqjLy2w==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", + "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==", "dev": true }, "block-stream": { @@ -1907,9 +1909,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.2.tgz", - "integrity": "sha512-yx7m7lVrXmt4nKWQgWZqxSALEiAKZhOAcbxdUaU9575mB0CzXVbgrgpfSnSP7OqWDUTYGD0YVJ0MSRdyOPgAwA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz", + "integrity": "sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -1925,12 +1927,12 @@ } }, "conventional-changelog-core": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.1.5.tgz", - "integrity": "sha512-iwqAotS4zk0wA4S84YY1JCUG7X3LxaRjJxuUo6GI4dZuIy243j5nOg/Ora35ExT4DOiw5dQbMMQvw2SUjh6moQ==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.1.6.tgz", + "integrity": "sha512-5teTAZOtJ4HLR6384h50nPAaKdDr+IaU0rnD2Gg2C3MS7hKsEPH8pZxrDNqam9eOSPQg9tET6uZY79zzgSz+ig==", "dev": true, "requires": { - "conventional-changelog-writer": "^4.0.2", + "conventional-changelog-writer": "^4.0.3", "conventional-commits-parser": "^3.0.1", "dateformat": "^3.0.0", "get-pkg-repo": "^1.0.0", @@ -2039,15 +2041,15 @@ "dev": true }, "conventional-changelog-writer": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.2.tgz", - "integrity": "sha512-d8/FQY/fix2xXEBUhOo8u3DCbyEw3UOQgYHxLsPDw+wHUDma/GQGAGsGtoH876WyNs32fViHmTOUrgRKVLvBug==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.3.tgz", + "integrity": "sha512-bIlpSiQtQZ1+nDVHEEh798Erj2jhN/wEjyw9sfxY9es6h7pREE5BNJjfv0hXGH/FTrAsEpHUq4xzK99eePpwuA==", "dev": true, "requires": { "compare-func": "^1.3.1", "conventional-commits-filter": "^2.0.1", "dateformat": "^3.0.0", - "handlebars": "^4.0.2", + "handlebars": "^4.1.0", "json-stringify-safe": "^5.0.1", "lodash": "^4.2.1", "meow": "^4.0.0", @@ -2565,14 +2567,15 @@ "dev": true }, "cosmiconfig": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.7.tgz", - "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.1.0.tgz", + "integrity": "sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q==", "dev": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", "js-yaml": "^3.9.0", + "lodash.get": "^4.4.2", "parse-json": "^4.0.0" }, "dependencies": { @@ -2583,9 +2586,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -2716,9 +2719,9 @@ "dev": true }, "deepmerge": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.1.0.tgz", - "integrity": "sha512-/TnecbwXEdycfbsM2++O3eGiatEFHjjNciHEwJclM+T5Kd94qD1AP+2elP/Mq0L5b9VZJao5znR01Mz6eX8Seg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.2.0.tgz", + "integrity": "sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow==", "dev": true }, "defaults": { @@ -2814,6 +2817,12 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, + "deprecation": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-1.0.1.tgz", + "integrity": "sha512-ccVHpE72+tcIKaGMql33x5MAjKQIZrk+3x2GbJ7TeraUCZWHoT+KSZpoC+JQFsUBlSTXUrBaGiF0j6zVTepPLg==", + "dev": true + }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -2968,9 +2977,9 @@ } }, "es6-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", "dev": true }, "es6-promisify": { @@ -3120,9 +3129,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3348,9 +3357,9 @@ "dev": true }, "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.2.tgz", + "integrity": "sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4390,9 +4399,9 @@ } }, "globals": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", - "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", "dev": true }, "globby": { @@ -4578,12 +4587,12 @@ }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "^4.17.11" } }, "source-map": { @@ -4679,9 +4688,9 @@ } }, "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "requires": { "parse-passwd": "^1.0.0" @@ -4955,18 +4964,18 @@ } }, "strip-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", - "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.1.0.tgz", + "integrity": "sha512-TjxrkPONqO2Z8QDCpeE2j6n0M6EwxzyDgzEeGp+FbdvaJAt//ClYi6W5my+3ROlC/hZX2KACUwDfK49Ka5eDvg==", "dev": true, "requires": { - "ansi-regex": "^4.0.0" + "ansi-regex": "^4.1.0" }, "dependencies": { "ansi-regex": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", - "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true } } @@ -5430,26 +5439,26 @@ } }, "lerna": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.11.0.tgz", - "integrity": "sha512-87gFkJ/E/XtWvKrnBnixfPkroAZls7Vzfhdt42gPJYaBdXBqeJWQskGB10mr80GZTm8RmMPrC8M+t7XL1g/YQA==", - "dev": true, - "requires": { - "@lerna/add": "3.11.0", - "@lerna/bootstrap": "3.11.0", - "@lerna/changed": "3.11.0", - "@lerna/clean": "3.11.0", - "@lerna/cli": "3.11.0", - "@lerna/create": "3.11.0", - "@lerna/diff": "3.11.0", - "@lerna/exec": "3.11.0", - "@lerna/import": "3.11.0", - "@lerna/init": "3.11.0", - "@lerna/link": "3.11.0", - "@lerna/list": "3.11.0", - "@lerna/publish": "3.11.0", - "@lerna/run": "3.11.0", - "@lerna/version": "3.11.0", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.13.1.tgz", + "integrity": "sha512-7kSz8LLozVsoUNTJzJzy+b8TnV9YdviR2Ee2PwGZSlVw3T1Rn7kOAPZjEi+3IWnOPC96zMPHVmjCmzQ4uubalw==", + "dev": true, + "requires": { + "@lerna/add": "3.13.1", + "@lerna/bootstrap": "3.13.1", + "@lerna/changed": "3.13.1", + "@lerna/clean": "3.13.1", + "@lerna/cli": "3.13.0", + "@lerna/create": "3.13.1", + "@lerna/diff": "3.13.1", + "@lerna/exec": "3.13.1", + "@lerna/import": "3.13.1", + "@lerna/init": "3.13.1", + "@lerna/link": "3.13.1", + "@lerna/list": "3.13.1", + "@lerna/publish": "3.13.1", + "@lerna/run": "3.13.1", + "@lerna/version": "3.13.1", "import-local": "^1.0.0", "npmlog": "^4.1.2" } @@ -5631,6 +5640,15 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -5806,18 +5824,18 @@ } }, "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", "dev": true }, "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", "dev": true, "requires": { - "mime-db": "~1.37.0" + "mime-db": "~1.38.0" } }, "mimic-fn": { @@ -6108,9 +6126,9 @@ } }, "npm-packlist": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.3.0.tgz", - "integrity": "sha512-qPBc6CnxEzpOcc4bjoIBJbYdy0D/LFFPUdxvfwor4/w3vxeE0h6TiOVurCEPpQ6trjN77u/ShyfeJGsbAfB3dA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -6188,9 +6206,9 @@ "dev": true }, "nyc": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", - "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", + "integrity": "sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w==", "dev": true, "requires": { "archy": "^1.0.0", @@ -6203,10 +6221,10 @@ "glob": "^7.1.3", "istanbul-lib-coverage": "^2.0.3", "istanbul-lib-hook": "^2.0.3", - "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-instrument": "^3.1.0", "istanbul-lib-report": "^2.0.4", "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.0", + "istanbul-reports": "^2.1.1", "make-dir": "^1.3.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", @@ -6243,11 +6261,11 @@ "dev": true }, "async": { - "version": "2.6.1", + "version": "2.6.2", "bundled": true, "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "^4.17.11" } }, "balanced-match": { @@ -6264,11 +6282,6 @@ "concat-map": "0.0.1" } }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, "caching-transform": { "version": "3.0.1", "bundled": true, @@ -6467,7 +6480,7 @@ "dev": true }, "handlebars": { - "version": "4.0.12", + "version": "4.1.0", "bundled": true, "dev": true, "requires": { @@ -6531,14 +6544,6 @@ "bundled": true, "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "bundled": true, @@ -6607,11 +6612,11 @@ } }, "istanbul-reports": { - "version": "2.1.0", + "version": "2.1.1", "bundled": true, "dev": true, "requires": { - "handlebars": "^4.0.11" + "handlebars": "^4.1.0" } }, "json-parse-better-errors": { @@ -6683,13 +6688,13 @@ } }, "mem": { - "version": "4.0.0", + "version": "4.1.0", "bundled": true, "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" + "p-is-promise": "^2.0.0" } }, "merge-source-map": { @@ -6751,12 +6756,12 @@ "dev": true }, "normalize-package-data": { - "version": "2.4.0", + "version": "2.5.0", "bundled": true, "dev": true, "requires": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } @@ -6817,7 +6822,7 @@ "dev": true }, "p-is-promise": { - "version": "1.1.0", + "version": "2.0.0", "bundled": true, "dev": true }, @@ -6877,6 +6882,11 @@ "bundled": true, "dev": true }, + "path-parse": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, "path-type": { "version": "3.0.0", "bundled": true, @@ -6949,6 +6959,14 @@ "bundled": true, "dev": true }, + "resolve": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "resolve-from": { "version": "4.0.0", "bundled": true, @@ -7265,9 +7283,9 @@ } }, "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", "dev": true }, "object-visit": { @@ -7496,9 +7514,9 @@ } }, "pacote": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.1.tgz", - "integrity": "sha512-YKSRsQqmeHxgra0KCdWA2FtVxDPUlBiCdmew+mSe44pzlx5t1ViRMWiQg18T+DREA+vSqYfKzynaToFR4hcKHw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.0.tgz", + "integrity": "sha512-aUplXozRbzhaJO48FaaeClmN+2Mwt741MC6M3bevIGZwdCaP7frXzbUOfOWa91FPHoLITzG0hYaKY363lxO3bg==", "dev": true, "requires": { "bluebird": "^3.5.3", @@ -7866,11 +7884,12 @@ } }, "prop-types": { - "version": "15.7.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.0.tgz", - "integrity": "sha512-rlfizAIb1WrkMkbFm3uk7cZGqeVPOhHHMj3gy9FUHE+Ha5lKvbIzj9ygvLdG8Cv2CQEhQnP5djXS7pbmTOpBqw==", + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "dev": true, "requires": { + "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.8.1" } @@ -7966,9 +7985,9 @@ "dev": true }, "react-is": { - "version": "16.8.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.1.tgz", - "integrity": "sha512-ioMCzVDWvCvKD8eeT+iukyWrBGrA3DiFYkXfBsVYIRdaREZuBjENG+KjrikavCLasozqRWTwFUagU/O4vPpRMA==", + "version": "16.8.4", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", + "integrity": "sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==", "dev": true }, "read": { @@ -8019,9 +8038,9 @@ } }, "read-package-tree": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.2.1.tgz", - "integrity": "sha512-2CNoRoh95LxY47LvqrehIAfUVda2JbuFE/HaGYs42bNrGG+ojbw1h3zOcPcQ+1GQ3+rkzNndZn85u1XyZ3UsIA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.2.2.tgz", + "integrity": "sha512-rW3XWUUkhdKmN2JKB4FL563YAgtINifso5KShykufR03nJ5loGFlkUMe1g/yxmqX073SoYYTsgXu7XdDinKZuA==", "dev": true, "requires": { "debuglog": "^1.0.1", @@ -8633,9 +8652,9 @@ } }, "socks": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.3.tgz", - "integrity": "sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz", + "integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==", "dev": true, "requires": { "ip": "^1.1.5", @@ -8643,13 +8662,13 @@ } }, "socks-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", + "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", "dev": true, "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" + "agent-base": "~4.2.1", + "socks": "~2.3.2" } }, "sort-keys": { @@ -9643,9 +9662,9 @@ } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -9704,9 +9723,9 @@ }, "dependencies": { "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", "dev": true } } diff --git a/package.json b/package.json index 388a942324..31c1decda0 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "install": "lerna bootstrap", "publish": "lerna publish", "lint": "semistandard \"packages/**/lib/**/*.js\" \"packages/**/test/**/*.js\" --fix", - "test": "npm run lint && nyc lerna run test --ignore @feathersjs/authentication-client", + "test": "npm run lint && nyc lerna run test", "test:client": "grunt" }, "semistandard": { diff --git a/packages/authentication-client/lib/core.js b/packages/authentication-client/lib/core.js new file mode 100644 index 0000000000..6e367efb25 --- /dev/null +++ b/packages/authentication-client/lib/core.js @@ -0,0 +1,127 @@ +const { NotAuthenticated } = require('@feathersjs/errors'); + +exports.Storage = class Storage { + constructor () { + this.store = {}; + } + + getItem (key) { + return this.store[key]; + } + + setItem (key, value) { + return (this.store[key] = value); + } + + removeItem (key) { + delete this.store[key]; + return this; + } +}; + +exports.AuthenticationClient = class AuthenticationClient { + constructor (app, options) { + const socket = app.io || app.primus; + + this.app = app; + this.app.set('storage', this.app.get('storage') || options.storage); + this.options = options; + this.authenticated = false; + + if (socket) { + this.handleSocket(socket); + } + } + + get service () { + return this.app.service(this.options.path); + } + + get storage () { + return this.app.get('storage'); + } + + handleSocket (socket) { + // Connection events happen on every reconnect + const connected = this.app.io ? 'connect' : 'open'; + + socket.on(connected, () => { + // Only reconnect when `reAuthenticate()` or `authenticate()` + // has been called explicitly first + if (this.authenticated) { + // Force reauthentication with the server + this.reauthenticate(true); + } + }); + } + + setJwt (accessToken) { + return Promise.resolve(this.storage.setItem(this.options.storageKey, accessToken)); + } + + getJwt () { + return Promise.resolve(this.storage.getItem(this.options.storageKey)); + } + + removeJwt () { + return Promise.resolve(this.storage.removeItem(this.options.storageKey)); + } + + reset () { + // Reset the internal authentication state + // but not the accessToken from storage + const authResult = this.app.get('authentication'); + + this.app.set('authentication', null); + this.authenticated = false; + + return authResult; + } + + reauthenticate (force = false) { + // Either returns the authentication state or + // tries to re-authenticate with the stored JWT and strategy + const authPromise = this.app.get('authentication'); + + if (!authPromise || force === true) { + return this.getJwt().then(accessToken => { + if (!accessToken) { + throw new NotAuthenticated('No accessToken found in storage'); + } + + return this.authenticate({ + strategy: this.options.jwtStrategy, + accessToken + }); + }); + } + + return authPromise; + } + + authenticate (authentication) { + if (!authentication) { + return this.reauthenticate(); + } + + const promise = this.service.create(authentication) + .then(authResult => { + const { accessToken } = authResult; + + this.authenticated = true; + + return this.setJwt(accessToken).then(() => authResult); + }); + + this.app.set('authentication', promise); + + return promise; + } + + logout () { + return this.app.get('authentication') + .then(() => this.service.remove(null)) + .then(() => this.removeJwt()) + .then(() => this.reset()); + } +}; diff --git a/packages/authentication-client/lib/hooks/authentication.js b/packages/authentication-client/lib/hooks/authentication.js new file mode 100644 index 0000000000..acd3a8f718 --- /dev/null +++ b/packages/authentication-client/lib/hooks/authentication.js @@ -0,0 +1,19 @@ +const { stripSlashes } = require('@feathersjs/commons'); + +module.exports = () => { + return context => { + const { app, params, path, method, app: { authentication } } = context; + + if (stripSlashes(authentication.options.path) === path && method === 'create') { + return context; + } + + return Promise.resolve(app.get('authentication')).then(authResult => { + if (authResult) { + context.params = Object.assign({}, authResult, params); + } + + return context; + }); + }; +}; diff --git a/packages/authentication-client/lib/hooks/index.js b/packages/authentication-client/lib/hooks/index.js index 85f579c07d..1155be5bd1 100644 --- a/packages/authentication-client/lib/hooks/index.js +++ b/packages/authentication-client/lib/hooks/index.js @@ -1,11 +1,5 @@ +const authentication = require('./authentication'); const populateHeader = require('./populate-header'); -const populateAccessToken = require('./populate-access-token'); -const populateEntity = require('./populate-entity'); -let hooks = { - populateHeader, - populateAccessToken, - populateEntity -}; - -module.exports = hooks; +exports.authentication = authentication; +exports.populateHeader = populateHeader; diff --git a/packages/authentication-client/lib/hooks/populate-access-token.js b/packages/authentication-client/lib/hooks/populate-access-token.js deleted file mode 100644 index c7c4516ce1..0000000000 --- a/packages/authentication-client/lib/hooks/populate-access-token.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = function populateAccessToken () { - return function (hook) { - const app = hook.app; - - if (hook.type !== 'before') { - return Promise.reject(new Error(`The 'populateAccessToken' hook should only be used as a 'before' hook.`)); - } - - Object.assign(hook.params, { accessToken: app.get('accessToken') }); - - return Promise.resolve(hook); - }; -}; diff --git a/packages/authentication-client/lib/hooks/populate-entity.js b/packages/authentication-client/lib/hooks/populate-entity.js deleted file mode 100644 index 81c33592d2..0000000000 --- a/packages/authentication-client/lib/hooks/populate-entity.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = function populateEntity (options = {}) { - if (!options.service) { - throw new Error(`You need to pass 'options.service' to the populateEntity() hook.`); - } - - if (!options.field) { - throw new Error(`You need to pass 'options.field' to the populateEntity() hook.`); - } - - if (!options.entity) { - throw new Error(`You need to pass 'options.entity' to the populateEntity() hook.`); - } - - return function (hook) { - const app = hook.app; - - if (hook.type !== 'after') { - return Promise.reject(new Error(`The 'populateEntity' hook should only be used as an 'after' hook.`)); - } - - return app.passport - .verifyJWT(hook.result.accessToken) - .then(payload => { - const id = payload[options.field]; - - if (!id) { - return Promise.reject(new Error(`Access token payload is missing the '${options.field}' field.`)); - } - - return app.service(options.service).get(id); - }) - .then(entity => { - hook.result[options.entity] = entity; - app.set(options.entity, entity); - - return Promise.resolve(hook); - }); - }; -}; diff --git a/packages/authentication-client/lib/hooks/populate-header.js b/packages/authentication-client/lib/hooks/populate-header.js index 2681318f7e..ca6f304df2 100644 --- a/packages/authentication-client/lib/hooks/populate-header.js +++ b/packages/authentication-client/lib/hooks/populate-header.js @@ -1,19 +1,18 @@ -module.exports = function populateHeader (options = {}) { - if (!options.header) { - throw new Error(`You need to pass 'options.header' to the populateHeader() hook.`); - } +module.exports = () => { + return context => { + const { app, params: { accessToken } } = context; + const authentication = app.authentication; - return function (hook) { - if (hook.type !== 'before') { - return Promise.reject(new Error(`The 'populateHeader' hook should only be used as a 'before' hook.`)); - } + // Set REST header if necessary + if (app.rest && accessToken) { + const { scheme, header } = authentication.options; + const authHeader = `${scheme} ${accessToken}`; - if (hook.params.accessToken) { - hook.params.headers = Object.assign({}, { - [options.header]: options.prefix ? `${options.prefix} ${hook.params.accessToken}` : hook.params.accessToken - }, hook.params.headers); + context.params.headers = Object.assign({}, { + [header]: authHeader + }, context.params.headers); } - return Promise.resolve(hook); + return context; }; }; diff --git a/packages/authentication-client/lib/index.js b/packages/authentication-client/lib/index.js index c051de11ba..7467c69d53 100644 --- a/packages/authentication-client/lib/index.js +++ b/packages/authentication-client/lib/index.js @@ -1,52 +1,37 @@ -const hooks = require('./hooks/index'); -const Passport = require('./passport'); - +const { AuthenticationClient, Storage } = require('./core'); +const hooks = require('./hooks'); const defaults = { header: 'Authorization', - cookie: 'feathers-jwt', + scheme: 'Bearer', storageKey: 'feathers-jwt', jwtStrategy: 'jwt', path: '/authentication', - entity: 'user', - service: 'users', - timeout: 5000 + Authentication: AuthenticationClient }; -function init (config = {}) { - const options = Object.assign({}, defaults, config); - - return function () { - const app = this; - - app.passport = new Passport(app, options); - app.authenticate = app.passport.authenticate.bind(app.passport); - app.logout = app.passport.logout.bind(app.passport); - - // Set up hook that adds token and user to params so that - // it they can be accessed by client side hooks and services - app.mixins.push(function (service) { - // if (typeof service.hooks !== 'function') { - if (app.version < '3.0.0') { - throw new Error(`This version of @feathersjs/authentication-client only works with @feathersjs/feathers v3.0.0 or later.`); - } - - service.hooks({ - before: hooks.populateAccessToken(options) - }); +module.exports = _options => { + const options = Object.assign({}, { + storage: new Storage() + }, defaults, _options); + const { Authentication } = options; + + return app => { + const authentication = new Authentication(app, options); + + app.authentication = authentication; + app.authenticate = authentication.authenticate.bind(authentication); + app.reauthenticate = authentication.reauthenticate.bind(authentication); + app.logout = authentication.logout.bind(authentication); + + app.hooks({ + before: [ + hooks.authentication(), + hooks.populateHeader() + ] }); - - // Set up hook that adds authorization header for REST provider - if (app.rest) { - app.mixins.push(function (service) { - service.hooks({ - before: hooks.populateHeader(options) - }); - }); - } }; -} - -module.exports = init; +}; -module.exports.default = init; -module.exports.defaults = defaults; +Object.assign(module.exports, { + AuthenticationClient, Storage, hooks, defaults +}); diff --git a/packages/authentication-client/lib/passport.js b/packages/authentication-client/lib/passport.js deleted file mode 100644 index b6d39c0b58..0000000000 --- a/packages/authentication-client/lib/passport.js +++ /dev/null @@ -1,301 +0,0 @@ -const errors = require('@feathersjs/errors'); -const decode = require('jwt-decode'); -const Debug = require('debug'); - -const { - Storage, - payloadIsValid, - getCookie, - clearCookie -} = require('./utils'); - -const debug = Debug('@feathersjs/authentication-client'); - -module.exports = class Passport { - constructor (app, options) { - if (app.passport) { - throw new Error('You have already registered authentication on this client app instance. You only need to do it once.'); - } - - Object.assign(this, { - options, - app, - payloadIsValid, - getCookie, - clearCookie, - storage: app.get('storage') || this.getStorage(options.storage) - }); - - this.setJWT = this.setJWT.bind(this); - - app.set('storage', this.storage); - this.getJWT().then(this.setJWT); - - this.setupSocketListeners(); - } - - setupSocketListeners () { - const app = this.app; - const socket = app.io || app.primus; - const emit = app.io ? 'emit' : 'send'; - const reconnected = app.io ? 'reconnect' : 'reconnected'; - - if (!socket) { - return; - } - - socket.on(reconnected, () => { - debug('Socket reconnected'); - - // If socket was already authenticated then re-authenticate - // it with the server automatically. - if (socket.authenticated) { - const data = { - strategy: this.options.jwtStrategy, - accessToken: app.get('accessToken') - }; - this.authenticateSocket(data, socket, emit) - .then(this.setJWT) - .catch(error => { - debug('Error re-authenticating after socket reconnect', error); - socket.authenticated = false; - app.emit('reauthentication-error', error); - }); - } - }); - - const socketUpgradeHandler = () => { - socket.io.engine.on('upgrade', () => { - debug('Socket upgrading'); - - // If socket was already authenticated then re-authenticate - // it with the server automatically. - if (socket.authenticated) { - const data = { - strategy: this.options.jwtStrategy, - accessToken: app.get('accessToken') - }; - - this.authenticateSocket(data, socket, emit) - .then(this.setJWT) - .catch(error => { - debug('Error re-authenticating after socket upgrade', error); - socket.authenticated = false; - app.emit('reauthentication-error', error); - }); - } - }); - }; - - if (socket.io && socket.io.engine) { - socketUpgradeHandler(); - } else { - socket.on('connect', socketUpgradeHandler); - } - } - - connected () { - const app = this.app; - - if (app.rest) { - return Promise.resolve(); - } - - const socket = app.io || app.primus; - - if (!socket) { - return Promise.reject(new Error(`It looks like your client connection has not been configured.`)); - } - - if ((app.io && socket.connected) || (app.primus && socket.readyState === 3)) { - debug('Socket already connected'); - return Promise.resolve(socket); - } - - return new Promise((resolve, reject) => { - const connected = app.primus ? 'open' : 'connect'; - const disconnect = app.io ? 'disconnect' : 'end'; - const timeout = setTimeout(() => { - debug('Socket connection timed out'); - reject(new Error('Socket connection timed out')); - }, this.options.timeout); - - debug('Waiting for socket connection'); - - const handleDisconnect = () => { - debug('Socket disconnected before it could connect'); - socket.authenticated = false; - }; - - // If disconnect happens before `connect` the promise will be rejected. - socket.once(disconnect, handleDisconnect); - socket.once(connected, () => { - debug('Socket connected'); - debug(`Removing ${disconnect} listener`); - socket.removeListener(disconnect, handleDisconnect); - clearTimeout(timeout); - resolve(socket); - }); - }); - } - - authenticate (credentials = {}) { - const app = this.app; - let getCredentials = Promise.resolve(credentials); - - // If no strategy was given let's try to authenticate with a stored JWT - if (!credentials.strategy) { - if (credentials.accessToken) { - credentials.strategy = this.options.jwtStrategy; - } else { - getCredentials = this.getJWT().then(accessToken => { - if (!accessToken) { - return Promise.reject(new errors.NotAuthenticated(`Could not find stored JWT and no authentication strategy was given`)); - } - return { strategy: this.options.jwtStrategy, accessToken }; - }); - } - } - - return getCredentials.then(credentials => { - return this.connected(app).then(socket => { - if (app.rest) { - return app.service(this.options.path).create(credentials).then(this.setJWT); - } - - const emit = app.io ? 'emit' : 'send'; - return this.authenticateSocket(credentials, socket, emit).then(this.setJWT); - }); - }).then(payload => { - app.emit('authenticated', payload); - return payload; - }); - } - - // Returns a promise that authenticates a socket - authenticateSocket (credentials, socket, emit) { - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - debug('authenticateSocket timed out'); - reject(new Error('Authentication timed out')); - }, this.options.timeout); - - debug('Attempting to authenticate socket'); - socket[emit]('authenticate', credentials, (error, data) => { - if (error) { - return reject(error); - } - - clearTimeout(timeout); - socket.authenticated = true; - debug('Socket authenticated!'); - - resolve(data); - }); - }); - } - - logoutSocket (socket, emit) { - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - debug('logoutSocket timed out'); - reject(new Error('Logout timed out')); - }, this.options.timeout); - - socket[emit]('logout', error => { - clearTimeout(timeout); - socket.authenticated = false; - - if (error) { - return reject(error); - } - - resolve(); - }); - }); - } - - logout () { - const app = this.app; - - app.set('accessToken', null); - this.clearCookie(this.options.cookie); - - // remove the accessToken from localStorage - return Promise.resolve(app.get('storage').removeItem(this.options.storageKey)).then(() => { - // If using sockets de-authenticate the socket - if (app.io || app.primus) { - const method = app.io ? 'emit' : 'send'; - const socket = app.io ? app.io : app.primus; - - return this.logoutSocket(socket, method); - } - }).then(result => { - app.emit('logout', result); - - return result; - }); - } - - setJWT (data) { - const accessToken = (data && data.accessToken) ? data.accessToken : data; - - if (accessToken) { - this.app.set('accessToken', accessToken); - this.app.get('storage').setItem(this.options.storageKey, accessToken); - } - - return Promise.resolve(data); - } - - getJWT () { - const app = this.app; - return new Promise((resolve, reject) => { - const accessToken = app.get('accessToken'); - - if (accessToken) { - return resolve(accessToken); - } - - return Promise.resolve(this.storage.getItem(this.options.storageKey)) - .then(jwt => { - let token = jwt || this.getCookie(this.options.cookie); - - if (token && token !== 'null' && !this.payloadIsValid(decode(token))) { - token = undefined; - } - - return resolve(token); - }) - .catch(reject); - }); - } - - // Pass a jwt token, get back a payload if it's valid. - verifyJWT (token) { - if (typeof token !== 'string') { - return Promise.reject(new Error('Token provided to verifyJWT is missing or not a string')); - } - - try { - let payload = decode(token); - - if (this.payloadIsValid(payload)) { - return Promise.resolve(payload); - } - - return Promise.reject(new Error('Invalid token: expired')); - } catch (error) { - return Promise.reject(new Error('Cannot decode malformed token.')); - } - } - - // Returns a storage implementation - getStorage (storage) { - if (storage) { - return storage; - } - - return new Storage(); - } -}; diff --git a/packages/authentication-client/lib/utils.js b/packages/authentication-client/lib/utils.js deleted file mode 100644 index b5159f8e42..0000000000 --- a/packages/authentication-client/lib/utils.js +++ /dev/null @@ -1,43 +0,0 @@ -exports.Storage = class Storage { - constructor () { - this.store = {}; - } - - getItem (key) { - return this.store[key]; - } - - setItem (key, value) { - return (this.store[key] = value); - } - - removeItem (key) { - delete this.store[key]; - return this; - } -}; - -exports.payloadIsValid = function payloadIsValid (payload) { - return payload && (!payload.exp || payload.exp * 1000 > new Date().getTime()); -}; - -exports.getCookie = function getCookie (name) { - if (typeof document !== 'undefined') { - const value = `; ${document.cookie}`; - const parts = value.split(`; ${name}=`); - - if (parts.length === 2) { - return parts.pop().split(';').shift(); - } - } - - return null; -}; - -exports.clearCookie = function clearCookie (name) { - if (typeof document !== 'undefined') { - document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;`; - } - - return null; -}; diff --git a/packages/authentication-client/package.json b/packages/authentication-client/package.json index a4d022b6af..31b9379b4f 100644 --- a/packages/authentication-client/package.json +++ b/packages/authentication-client/package.json @@ -26,7 +26,7 @@ "node": ">= 6" }, "scripts": { - "test": "mocha --opts ../../mocha.opts" + "test": "../../node_modules/.bin/nyc mocha --opts ../../mocha.opts" }, "directories": { "lib": "lib" @@ -36,12 +36,10 @@ }, "dependencies": { "@feathersjs/errors": "^3.3.6", - "debug": "^4.1.1", - "jwt-decode": "^2.2.0" + "debug": "^4.1.1" }, "devDependencies": { "@feathersjs/authentication": "^2.1.16", - "@feathersjs/authentication-jwt": "^2.0.10", "@feathersjs/authentication-local": "^1.2.9", "@feathersjs/express": "^1.3.1", "@feathersjs/feathers": "^3.3.1", @@ -50,15 +48,10 @@ "@feathersjs/rest-client": "^1.4.7", "@feathersjs/socketio": "^3.2.9", "@feathersjs/socketio-client": "^1.2.1", - "body-parser": "^1.18.3", - "chai": "^4.2.0", - "feathers-memory": "^3.0.2", - "localstorage-memory": "^1.0.3", + "axios": "^0.18.0", "mocha": "^5.2.0", "primus": "^7.3.2", "primus-emitter": "^3.1.1", - "socket.io-client": "^2.2.0", - "superagent": "^4.1.0", - "ws": "^6.1.3" + "socket.io-client": "^2.2.0" } } diff --git a/packages/authentication-client/test/fixtures/server.js b/packages/authentication-client/test/fixtures/server.js deleted file mode 100644 index 9fe28a6992..0000000000 --- a/packages/authentication-client/test/fixtures/server.js +++ /dev/null @@ -1,64 +0,0 @@ -const path = require('path'); -const feathers = require('@feathersjs/feathers'); -const express = require('@feathersjs/express'); -const rest = require('@feathersjs/express/rest'); -const socketio = require('@feathersjs/socketio'); -const primus = require('@feathersjs/primus'); -const memory = require('feathers-memory'); -const bodyParser = require('body-parser'); -const errorHandler = require('@feathersjs/errors/handler'); -const local = require('@feathersjs/authentication-local'); -const jwt = require('@feathersjs/authentication-jwt'); -const auth = require('@feathersjs/authentication'); - -const User = { - email: 'admin@feathersjs.com', - password: 'admin', - permissions: ['*'] -}; - -module.exports = function (settings, socketProvider) { - const app = express(feathers()); - - app.configure(rest()) - .configure(socketProvider === 'socketio' ? socketio() : primus({ - transformer: 'websockets' - })) - .use(bodyParser.json()) - .use(bodyParser.urlencoded({ extended: true })) - .configure(auth(settings)) - .configure(local()) - .configure(jwt()) - .use('/users', memory()) - .use('/', express.static(path.resolve(__dirname, '/public'))) - .use(errorHandler()); - - app.service('authentication').hooks({ - before: { - create: [ - auth.hooks.authenticate(['jwt', 'local']) - ], - remove: [ - auth.hooks.authenticate('jwt') - ] - } - }); - - // Add a hook to the user service that automatically replaces - // the password with a hash of the password before saving it. - app.service('users').hooks({ - before: { - find: [ - auth.hooks.authenticate('jwt') - ], - create: [ - local.hooks.hashPassword({ passwordField: 'password' }) - ] - } - }); - - // Create a user that we can use to log in - app.service('users').create(User).catch(console.error); - - return app; -}; diff --git a/packages/authentication-client/test/hooks/index.test.js b/packages/authentication-client/test/hooks/index.test.js deleted file mode 100644 index f5f799a52d..0000000000 --- a/packages/authentication-client/test/hooks/index.test.js +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable no-unused-expressions */ -const { expect } = require('chai'); - -const hooks = require('../../lib/hooks'); - -describe('hooks', () => { - it('is CommonJS compatible', () => { - expect(typeof require('../../lib/hooks')).to.equal('object'); - }); - - it('is ES6 compatible', () => { - expect(typeof hooks).to.equal('object'); - }); - - it('exposes populateEntity hook', () => { - expect(typeof hooks.populateEntity).to.equal('function'); - }); - - it('exposes populateHeader hook', () => { - expect(typeof hooks.populateHeader).to.equal('function'); - }); - - it('exposes populateAccessToken hook', () => { - expect(typeof hooks.populateAccessToken).to.equal('function'); - }); -}); diff --git a/packages/authentication-client/test/hooks/populate-access-token.test.js b/packages/authentication-client/test/hooks/populate-access-token.test.js deleted file mode 100644 index 85b4cc1c7f..0000000000 --- a/packages/authentication-client/test/hooks/populate-access-token.test.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable no-unused-expressions */ -const { expect } = require('chai'); -const { populateAccessToken } = require('../../lib/hooks'); - -describe('hooks:populateAccessToken', () => { - let hook; - - beforeEach(() => { - hook = { - type: 'before', - params: {}, - app: { - get: () => 'my token' - } - }; - }); - - describe('when not called as a before hook', () => { - it('returns an error', () => { - hook.type = 'after'; - - return populateAccessToken()(hook).catch(error => { - expect(error).to.not.equal(undefined); - }); - }); - }); - - it('adds the accessToken to hook.params', () => { - return populateAccessToken()(hook).then(hook => { - expect(hook.params.accessToken).to.equal('my token'); - }); - }); -}); diff --git a/packages/authentication-client/test/hooks/populate-entity.test.js b/packages/authentication-client/test/hooks/populate-entity.test.js deleted file mode 100644 index cb42517ed9..0000000000 --- a/packages/authentication-client/test/hooks/populate-entity.test.js +++ /dev/null @@ -1,84 +0,0 @@ -/* eslint-disable no-unused-expressions */ -const { expect } = require('chai'); -const { populateEntity } = require('../../lib/hooks'); - -const user = { id: '1', name: 'Bob' }; - -describe('hooks:populateEntity', () => { - let hook; - let options; - - beforeEach(() => { - hook = { - type: 'after', - params: { - accessToken: 'my token', - headers: {} - }, - result: {}, - app: { - passport: { - verifyJWT: () => Promise.resolve({ userId: '1' }) - }, - set: () => {}, - service: () => { - return { - get: () => Promise.resolve(user) - }; - } - } - }; - - options = { - service: 'users', - field: 'userId', - entity: 'user' - }; - }); - - describe('when options.service is missing', () => { - it('throws an error', () => { - delete options.service; - - expect(() => { - populateEntity(options); - }).to.throw; - }); - }); - - describe('when options.field is missing', () => { - it('throws an error', () => { - delete options.field; - - expect(() => { - populateEntity(options); - }).to.throw; - }); - }); - - describe('when options.entity is missing', () => { - it('throws an error', () => { - delete options.entity; - - expect(() => { - populateEntity(options); - }).to.throw; - }); - }); - - describe('when not called as an after hook', () => { - it('returns an error', () => { - hook.type = 'before'; - - return populateEntity(options)(hook).catch(error => { - expect(error).to.not.equal(undefined); - }); - }); - }); - - it('populates an entity by token payload id', () => { - return populateEntity(options)(hook).then(hook => { - expect(hook.result.user).to.deep.equal(user); - }); - }); -}); diff --git a/packages/authentication-client/test/hooks/populate-header.test.js b/packages/authentication-client/test/hooks/populate-header.test.js deleted file mode 100644 index 7e0cfd4bc5..0000000000 --- a/packages/authentication-client/test/hooks/populate-header.test.js +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable no-unused-expressions */ -const { expect } = require('chai'); -const { populateHeader } = require('../../lib/hooks'); - -describe('hooks:populateHeader', () => { - let hook; - let options; - - beforeEach(() => { - options = { header: 'Authorization' }; - hook = { - type: 'before', - params: { - accessToken: 'my token', - headers: {} - } - }; - }); - - describe('when options.header is missing', () => { - it('throws an error', () => { - delete options.header; - - expect(() => { - populateHeader(options); - }).to.throw; - }); - }); - - describe('when not called as a before hook', () => { - it('returns an error', () => { - hook.type = 'after'; - - return populateHeader(options)(hook).catch(error => { - expect(error).to.not.equal(undefined); - }); - }); - }); - - describe('when accessToken is missing', () => { - it('does nothing', () => { - delete hook.params.accessToken; - return populateHeader(options)(hook).then(newHook => { - expect(newHook).to.deep.equal(hook); - }); - }); - }); - - describe('when accessToken is present', () => { - it('adds the accessToken to authorization header', () => { - return populateHeader(options)(hook).then(hook => { - expect(hook.params.headers.Authorization).to.equal('my token'); - }); - }); - - it('retains existing headers', () => { - hook.params.headers = { - authorization: 'existing', - custom: 'custom' - }; - - return populateHeader(options)(hook).then(hook => { - expect(hook.params.headers.authorization).to.equal('existing'); - expect(hook.params.headers.custom).to.equal('custom'); - }); - }); - - it('supports a custom token header', () => { - options.header = 'custom'; - return populateHeader(options)(hook).then(hook => { - expect(hook.params.headers.custom).to.equal('my token'); - }); - }); - }); -}); diff --git a/packages/authentication-client/test/index.test.js b/packages/authentication-client/test/index.test.js index ad67154677..0f12eb28c5 100644 --- a/packages/authentication-client/test/index.test.js +++ b/packages/authentication-client/test/index.test.js @@ -1,54 +1,130 @@ -/* eslint-disable no-unused-expressions */ -const { expect } = require('chai'); - +const assert = require('assert'); const feathers = require('@feathersjs/feathers'); -const auth = require('../lib/index'); -describe('Feathers Authentication Client', () => { - let client; +const client = require('../lib'); + +describe('@feathersjs/authentication-client', () => { + const accessToken = 'testing'; + const user = { + name: 'Test User' + }; + let app; beforeEach(() => { - client = feathers() - .configure(auth()); + app = feathers(); + + app.configure(client()); + app.use('/authentication', { + create (data) { + return Promise.resolve({ + accessToken, + data, + user + }); + }, + + remove (id) { + return Promise.resolve({ id }); + } + }); + app.use('dummy', { + find (params) { + return Promise.resolve(params); + } + }); }); - it('throws an error if registered twice', () => { - expect(() => { - client.configure(auth()); - }).to.throw(Error); + it('initializes', () => { + assert.ok(app.authentication instanceof client.AuthenticationClient); + assert.strictEqual(app.get('storage'), app.authentication.storage); + assert.strictEqual(typeof app.authenticate, 'function'); + assert.strictEqual(typeof app.logout, 'function'); }); - it('exports default', () => { - expect(auth.default).to.equal(auth); + it('setJwt, getJwt, removeJwt', () => { + const auth = app.authentication; + const token = 'hi'; + + return auth.setJwt(token) + .then(() => auth.getJwt()) + .then(res => assert.strictEqual(res, token)) + .then(() => auth.removeJwt()) + .then(() => auth.getJwt()) + .then(res => assert.strictEqual(res, undefined)); }); - describe('default options', () => { - it('sets the authorization header', () => { - expect(client.passport.options.header).to.equal('Authorization'); - }); + it('authenticate and authentication hook', () => { + const data = { + strategy: 'testing' + }; - it('sets the cookie name', () => { - expect(client.passport.options.cookie).to.equal('feathers-jwt'); - }); + return app.authenticate(data).then(result => { + assert.deepStrictEqual(result, { + accessToken, + data, + user + }); - it('sets the name used for localstorage', () => { - expect(client.passport.options.storageKey).to.equal('feathers-jwt'); - }); + return app.authentication.getJwt(); + }).then(at => { + assert.strictEqual(at, accessToken, 'Set accessToken in storage'); - it('sets the jwtStrategy', () => { - expect(client.passport.options.jwtStrategy).to.equal('jwt'); - }); + return Promise.resolve(app.get('storage').getItem('feathers-jwt')); + }).then(at => { + assert.strictEqual(at, accessToken, 'Set accessToken in storage'); - it('sets the auth service path', () => { - expect(client.passport.options.path).to.equal('/authentication'); + return app.service('dummy').find(); + }).then(result => { + assert.deepStrictEqual(result.accessToken, accessToken); + assert.deepStrictEqual(result.user, user); }); + }); - it('sets the entity', () => { - expect(client.passport.options.entity).to.equal('user'); + describe('reauthenticate', () => { + it('fails when no token in storage', () => { + return app.authentication.reauthenticate().then(() => { + assert.fail('Should never get here'); + }).catch(error => { + assert.strictEqual(error.message, 'No accessToken found in storage'); + }); }); - it('sets the entity service', () => { - expect(client.passport.options.service).to.equal('users'); + it('reauthenticates when token is in storage', () => { + const data = { + strategy: 'testing' + }; + + app.authenticate(data).then(result => { + assert.deepStrictEqual(result, { + accessToken, + data, + user + }); + + return result; + }).then(() => app.authentication.reauthenticate()) + .then(() => + app.authentication.reset() + ).then(() => { + return Promise.resolve(app.get('storage').getItem('feathers-jwt')); + }).then(at => { + assert.strictEqual(at, accessToken, 'Set accessToken in storage'); + + return app.authentication.reauthenticate(); + }).then(at => { + assert.deepStrictEqual(at, { + accessToken, + data: { strategy: 'jwt', accessToken: 'testing' }, + user + }); + + return app.logout(); + }).then(() => { + return Promise.resolve(app.get('storage').getItem('feathers-jwt')); + }).then(at => { + assert.ok(!at); + assert.ok(!app.get('authentication')); + }); }); }); }); diff --git a/packages/authentication-client/test/integration/commons.js b/packages/authentication-client/test/integration/commons.js new file mode 100644 index 0000000000..1f7aae1da0 --- /dev/null +++ b/packages/authentication-client/test/integration/commons.js @@ -0,0 +1,103 @@ +const assert = require('assert'); + +module.exports = (getApp, getClient, { + provider, email, password, restartServer +}) => { + describe('common tests', () => { + let client, user; + + before(() => getApp().service('users').create({ + email, password + }).then(result => { + user = result; + })); + + beforeEach(() => { + client = getClient(); + }); + + it('authenticates with local strategy', () => { + return client.authenticate({ + strategy: 'local', + email, + password + }).then(result => { + assert.ok(result.accessToken); + assert.strictEqual(result.authentication.strategy, 'local'); + assert.strictEqual(result.user.email, email); + }); + }); + + it('authentication with wrong credentials fails', () => { + return client.authenticate({ + strategy: 'local', + email, + password: 'blabla' + }) + .then(() => assert.fail('Should never get here')) + .catch(error => { + assert.strictEqual(error.name, 'NotAuthenticated'); + assert.strictEqual(error.message, 'Invalid login'); + }); + }); + + it('errors when not authenticated', () => { + return client.service('dummy').find() + .then(() => assert.fail('Should never get here')) + .catch(error => { + assert.strictEqual(error.name, 'NotAuthenticated'); + assert.strictEqual(error.code, 401); + assert.strictEqual(error.message, 'Not authenticated'); + }); + }); + + it('authenticates and allows access', () => { + return client.authenticate({ + strategy: 'local', + email, + password + }).then(() => + client.service('dummy').find() + ).then(result => { + assert.strictEqual(result.provider, provider); + assert.ok(result.authentication); + assert.ok(result.authentication.payload); + assert.strictEqual(result.user.email, user.email); + assert.strictEqual(result.user.id, user.id); + }); + }); + + it('re-authenticates', () => { + return client.authenticate({ + strategy: 'local', + email, + password + }) + .then(() => client.authentication.reset()) + .then(() => client.authenticate()) + .then(() => client.service('dummy').find()) + .then(result => { + assert.strictEqual(result.provider, provider); + assert.ok(result.authentication); + assert.ok(result.authentication.payload); + assert.strictEqual(result.user.email, user.email); + assert.strictEqual(result.user.id, user.id); + }); + }); + + it('after logout does not allow subsequent access', () => { + return client.authenticate({ + strategy: 'local', + email, + password + }).then(() => client.logout()) + .then(() => client.service('dummy').find()) + .then(() => assert.fail('Should never get here')) + .catch(error => { + assert.strictEqual(error.name, 'NotAuthenticated'); + assert.strictEqual(error.code, 401); + assert.strictEqual(error.message, 'Not authenticated'); + }); + }); + }); +}; diff --git a/packages/authentication-client/test/integration/express.test.js b/packages/authentication-client/test/integration/express.test.js new file mode 100644 index 0000000000..51288ddb76 --- /dev/null +++ b/packages/authentication-client/test/integration/express.test.js @@ -0,0 +1,35 @@ +const axios = require('axios'); +const feathers = require('@feathersjs/feathers'); +const express = require('@feathersjs/express'); +const rest = require('@feathersjs/rest-client'); + +const authClient = require('../../lib'); +const getApp = require('./fixture'); +const commonTests = require('./commons'); + +describe('@feathersjs/authentication-client Express integration', () => { + let app, server; + + before(() => { + const restApp = express(feathers()) + .use(express.json()) + .configure(express.rest()) + .use(express.parseAuthentication('jwt')); + app = getApp(restApp); + app.use(express.errorHandler()); + + server = app.listen(9776); + }); + + after(done => server.close(() => done())); + + commonTests(() => app, () => { + return feathers() + .configure(rest('http://localhost:9776').axios(axios)) + .configure(authClient()); + }, { + email: 'expressauth@feathersjs.com', + password: 'secret', + provider: 'rest' + }); +}); diff --git a/packages/authentication-client/test/integration/fixture.js b/packages/authentication-client/test/integration/fixture.js new file mode 100644 index 0000000000..ea307f037b --- /dev/null +++ b/packages/authentication-client/test/integration/fixture.js @@ -0,0 +1,28 @@ +const { authenticate } = require('@feathersjs/authentication'); +const getApp = require('@feathersjs/authentication-local/test/fixture'); + +module.exports = _app => { + const app = getApp(_app); + + app.use('/dummy', { + find (params) { + return Promise.resolve(params); + } + }); + + app.service('dummy').hooks({ + before: authenticate('jwt') + }); + + app.service('users').hooks({ + before (context) { + if (context.id !== undefined && context.id !== null) { + context.id = parseInt(context.id); + } + + return context; + } + }); + + return app; +}; diff --git a/packages/authentication-client/test/integration/primus.test.js b/packages/authentication-client/test/integration/primus.test.js index 3f6c3db4d0..94a625bf13 100644 --- a/packages/authentication-client/test/integration/primus.test.js +++ b/packages/authentication-client/test/integration/primus.test.js @@ -1,13 +1,12 @@ -/* eslint-disable no-unused-expressions */ const feathers = require('@feathersjs/feathers'); -const primus = require('@feathersjs/primus-client'); -const localstorage = require('localstorage-memory'); const Primus = require('primus'); const Emitter = require('primus-emitter'); -const { expect } = require('chai'); +const primusClient = require('@feathersjs/primus-client'); +const primus = require('@feathersjs/primus'); -const authentication = require('../../lib/index'); -const createApplication = require('../fixtures/server'); +const authClient = require('../../lib'); +const getApp = require('./fixture'); +const commonTests = require('./commons'); const port = 8998; const baseURL = `http://localhost:${port}`; @@ -18,200 +17,26 @@ const Socket = Primus.createSocket({ } }); -const app = createApplication({ secret: 'supersecret' }, 'primus'); -let options; +describe('@feathersjs/authentication-client Primus integration', () => { + let app, server; -describe('Primus client authentication', function () { - this.timeout(20000); - let socket; - let server; - let client; + before(() => { + app = getApp(feathers().configure(primus({ + transformer: 'websockets' + }))); - before(done => { server = app.listen(port); - server.once('listening', () => { - socket = new Socket(baseURL); - client = feathers() - .configure(primus(socket, { timeout: 1000 })) - .configure(authentication()); - - done(); - }); - }); - - beforeEach(() => { - options = { - strategy: 'local', - email: 'admin@feathersjs.com', - password: 'admin' - }; - }); - - after(done => { - socket.socket.close(); - server.close(done); - }); - - it('can use client.passport.getJWT() to get the accessToken', () => { - return client.authenticate(options).then(response => { - client.passport.getJWT().then(accessToken => { - expect(accessToken).to.equal(response.accessToken); - }); - }); - }); - - it('can decode an accessToken with client.passport.verifyToken()', () => { - return client.authenticate(options).then(response => { - return client.passport.verifyJWT(response.accessToken).then(payload => { - expect(payload.userId).to.equal(0); - expect(payload.iss).to.equal('feathers'); - expect(payload.sub).to.equal('anonymous'); - }); - }); - }); - - it('local username password authentication', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - expect(client.get('accessToken')).to.deep.equal(response.accessToken); - }); - }); - - it('supports socket timeouts', () => { - return client.passport.connected().then(() => { - client.passport.options.timeout = 0; - - return client.authenticate(options).catch(error => { - client.passport.options.timeout = 5000; - expect(error.message).to.equal('Authentication timed out'); - }); - }); - }); - - it('`authenticated` event', done => { - client.once('authenticated', response => { - try { - expect(response.accessToken).to.not.equal(undefined); - expect(client.get('accessToken')).to.deep.equal(response.accessToken); - done(); - } catch (e) { - done(e); - } - }); - - client.authenticate(options); }); - it('local username password authentication and access to protected service', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.service('users').get(0).then(user => { - expect(user.id).to.equal(0); - }); - }); - }); - - it('local authentication with wrong credentials fails', () => { - options.password = 'this is wrong'; - return client.authenticate(options).catch(error => { - expect(error.name).to.equal('NotAuthenticated'); - expect(error.code).to.equal(401); - }); - }); - - it('authentication with no options and no stored accessToken fails', () => { - return client.authenticate().catch(error => { - expect(error.message).to.equal('Could not find stored JWT and no authentication type was given'); - expect(error.code).to.equal(401); - }); - }); - - it('uses localStorage compatible stores', () => { - const oldStorage = client.get('storage'); - client.set('storage', localstorage); - - return client.authenticate(options).then(response => { - expect(response.accessToken).to.equal(localstorage.getItem('feathers-jwt')); - client.set('storage', oldStorage); - }); - }); - - it('accessToken is stored and re-authentication with stored accessToken works', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - - return client.authenticate().then(response => { - expect(client.get('accessToken')).to.equal(response.accessToken); - }); - }); - }); - - it('.logout works, does not grant access to protected service and accessToken is removed from localstorage', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.logout(); - }) - .then(() => { - expect(client.get('accessToken')).to.equal(null); - return Promise.resolve(client.get('storage').getItem('feathers-jwt')); - }) - .then(accessToken => { - expect(accessToken).to.equal(undefined); - - return client.service('users').get(0).catch(error => { - expect(error.code).to.equal(401); - }); - }); - }); - - it('`logout` event', done => { - client.once('logout', () => done()); - - client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.logout(); - }); - }); - - it('authenticates automatically after reconnection', done => { - client.authenticate(options).then(response => { - app.primus.end({ reconnect: true }); - server.close(() => { - setTimeout(() => { - const newApp = createApplication({ secret: 'supersecret' }, 'primus'); - - server = newApp.listen(port); - server.once('listening', () => { - newApp.primus.on('connection', s => { - s.once('authenticate', data => { - expect(data.accessToken).to.equal(response.accessToken); - done(); - }); - }); - }); - }, 1000); - }); - }); - }); - - it.skip('authenticates automatically after upgrade', done => { - // TODO (EK): This is working but I have no idea how to manually - // trigger socket upgrade events. - app.primus.on('connection', serverSocket => { - serverSocket.on('upgrade', () => { - console.log('upgraded'); - - serverSocket.on('authenticate', data => { - expect(data.accessToken).to.be.ok; - done(); - }); - }); - }); + after(() => server.close()); - client.authenticate(options).then(response => { - setTimeout(() => { - app.primus.send('upgrade'); - }, 500); - }); + commonTests(() => app, () => { + return feathers() + .configure(primusClient(new Socket(baseURL), { timeout: 1000 })) + .configure(authClient()); + }, { + email: 'primusauth@feathersjs.com', + password: 'secrets', + provider: 'primus' }); }); diff --git a/packages/authentication-client/test/integration/rest.test.js b/packages/authentication-client/test/integration/rest.test.js deleted file mode 100644 index 4bf5367c12..0000000000 --- a/packages/authentication-client/test/integration/rest.test.js +++ /dev/null @@ -1,153 +0,0 @@ -const feathers = require('@feathersjs/feathers'); -const rest = require('@feathersjs/rest-client'); -const localstorage = require('localstorage-memory'); -const superagent = require('superagent'); -const { expect } = require('chai'); - -const authentication = require('../../lib/index'); -const createApplication = require('../fixtures/server'); - -const port = 8998; -const baseURL = `http://localhost:${port}`; - -const app = createApplication({ secret: 'supersecret' }); -let options; - -describe('REST client authentication', () => { - let server; - let client; - - before(done => { - server = app.listen(port); - server.once('listening', () => { - client = feathers() - .configure(rest(baseURL).superagent(superagent)) - .configure(authentication()); - - done(); - }); - }); - - beforeEach(() => { - options = { - strategy: 'local', - email: 'admin@feathersjs.com', - password: 'admin' - }; - }); - - after(done => { - server.close(); - done(); - }); - - it('can use client.passport.getJWT() to get the accessToken', () => { - return client.authenticate(options).then(response => { - client.passport.getJWT().then(accessToken => { - expect(accessToken).to.equal(response.accessToken); - }); - }); - }); - - it('can decode a accessToken with client.passport.verifyToken()', () => { - return client.authenticate(options).then(response => { - return client.passport.verifyJWT(response.accessToken).then(payload => { - expect(payload.userId).to.equal(0); - expect(payload.iss).to.equal('feathers'); - expect(payload.sub).to.equal('anonymous'); - }); - }); - }); - - it('local username password authentication', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - expect(client.get('accessToken')).to.deep.equal(response.accessToken); - }); - }); - - it('`authenticated` event', done => { - client.once('authenticated', response => { - try { - expect(response.accessToken).to.not.equal(undefined); - expect(client.get('accessToken')).to.deep.equal(response.accessToken); - done(); - } catch (e) { - done(e); - } - }); - - client.authenticate(options); - }); - - it('local username password authentication and access to protected service', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.service('users').get(0).then(user => { - expect(user.id).to.equal(0); - }); - }); - }); - - it('local authentication with wrong credentials fails', () => { - options.password = 'this is wrong'; - return client.authenticate(options).catch(error => { - expect(error.name).to.equal('NotAuthenticated'); - expect(error.code).to.equal(401); - }); - }); - - it('authentication with no options and no stored accessToken fails', () => { - return client.authenticate().catch(error => { - expect(error.message).to.equal('Could not find stored JWT and no authentication type was given'); - expect(error.code).to.equal(401); - }); - }); - - it('uses localStorage compatible stores', () => { - const oldStorage = client.get('storage'); - client.set('storage', localstorage); - - return client.authenticate(options).then(response => { - expect(response.accessToken).to.equal(localstorage.getItem('feathers-jwt')); - client.set('storage', oldStorage); - }); - }); - - it('accessToken is stored and re-authentication with stored accessToken works', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - - return client.authenticate().then(response => { - expect(client.get('accessToken')).to.equal(response.accessToken); - }); - }); - }); - - it('.logout works, does not grant access to protected service and accessToken is removed from localstorage', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.logout(); - }) - .then(() => { - expect(client.get('accessToken')).to.equal(null); - return Promise.resolve(client.get('storage').getItem('feathers-jwt')); - }) - .then(accessToken => { - expect(accessToken).to.equal(undefined); - - return client.service('users').get(0).catch(error => { - expect(error.code).to.equal(401); - }); - }); - }); - - it('`logout` event', done => { - client.once('logout', () => done()); - - client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.logout(); - }); - }); -}); diff --git a/packages/authentication-client/test/integration/socketio.test.js b/packages/authentication-client/test/integration/socketio.test.js index d210c403a5..4a93a40982 100644 --- a/packages/authentication-client/test/integration/socketio.test.js +++ b/packages/authentication-client/test/integration/socketio.test.js @@ -1,210 +1,30 @@ -/* eslint-disable no-unused-expressions */ -const feathers = require('@feathersjs/feathers'); -const socketio = require('@feathersjs/socketio-client'); -const localstorage = require('localstorage-memory'); const io = require('socket.io-client'); -const { expect } = require('chai'); - -const authentication = require('../../lib/index'); -const createApplication = require('../fixtures/server'); - -const port = 8998; -const baseURL = `http://localhost:${port}`; - -const app = createApplication({ secret: 'supersecret' }, 'socketio'); -let options; - -describe('Socket.io client authentication', function () { - this.timeout(20000); - let socket; - let server; - let client; - - before(done => { - server = app.listen(port); - server.once('listening', () => { - socket = io(baseURL); - client = feathers() - .configure(socketio(socket)) - .configure(authentication()); - - done(); - }); - }); - - beforeEach(() => { - options = { - strategy: 'local', - email: 'admin@feathersjs.com', - password: 'admin' - }; - }); - - after(done => { - socket.close(); - server.close(done); - }); - - it('can use client.passport.getJWT() to get the accessToken', () => { - return client.authenticate(options).then(response => { - client.passport.getJWT().then(accessToken => { - expect(accessToken).to.equal(response.accessToken); - }); - }); - }); - - it('can decode an accessToken with client.passport.verifyToken()', () => { - return client.authenticate(options).then(response => { - return client.passport.verifyJWT(response.accessToken).then(payload => { - expect(payload.userId).to.equal(0); - expect(payload.iss).to.equal('feathers'); - expect(payload.sub).to.equal('anonymous'); - }); - }); - }); - - it('local username password authentication', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - expect(client.get('accessToken')).to.deep.equal(response.accessToken); - }); - }); - - it('supports socket timeouts', () => { - return client.passport.connected().then(() => { - client.passport.options.timeout = 0; - - return client.authenticate(options).catch(error => { - client.passport.options.timeout = 5000; - expect(error.message).to.equal('Authentication timed out'); - }); - }); - }); - - it('`authenticated` event', done => { - client.once('authenticated', response => { - try { - expect(response.accessToken).to.not.equal(undefined); - expect(client.get('accessToken')).to.deep.equal(response.accessToken); - done(); - } catch (e) { - done(e); - } - }); - - client.authenticate(options); - }); - - it('local username password authentication and access to protected service', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.service('users').get(0).then(user => { - expect(user.id).to.equal(0); - }); - }); - }); - - it('local authentication with wrong credentials fails', () => { - options.password = 'this is wrong'; - return client.authenticate(options).catch(error => { - expect(error.name).to.equal('NotAuthenticated'); - expect(error.code).to.equal(401); - }); - }); - - it('authentication with no options and no stored accessToken fails', () => { - return client.authenticate().catch(error => { - expect(error.message).to.equal('Could not find stored JWT and no authentication type was given'); - expect(error.code).to.equal(401); - }); - }); - - it('uses localStorage compatible stores', () => { - const oldStorage = client.get('storage'); - client.set('storage', localstorage); - - return client.authenticate(options).then(response => { - expect(response.accessToken).to.equal(localstorage.getItem('feathers-jwt')); - client.set('storage', oldStorage); - }); - }); - - it('accessToken is stored and re-authentication with stored accessToken works', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - - return client.authenticate().then(response => { - expect(client.get('accessToken')).to.equal(response.accessToken); - }); - }); - }); - - it('.logout works, does not grant access to protected service and accessToken is removed from localstorage', () => { - return client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.logout(); - }) - .then(() => { - expect(client.get('accessToken')).to.equal(null); - return Promise.resolve(client.get('storage').getItem('feathers-jwt')); - }) - .then(accessToken => { - expect(accessToken).to.equal(undefined); +const feathers = require('@feathersjs/feathers'); +const socketio = require('@feathersjs/socketio'); +const socketioClient = require('@feathersjs/socketio-client'); - return client.service('users').get(0).catch(error => { - expect(error.code).to.equal(401); - }); - }); - }); +const authClient = require('../../lib'); +const getApp = require('./fixture'); +const commonTests = require('./commons'); - it('`logout` event', done => { - client.once('logout', () => done()); +describe('@feathersjs/authentication-client Socket.io integration', () => { + let app; - client.authenticate(options).then(response => { - expect(response.accessToken).to.not.equal(undefined); - return client.logout(); - }); - }); + before(() => { + app = getApp(feathers().configure(socketio())); - it('authenticates automatically after reconnection', done => { - client.authenticate(options).then(response => { - app.io.close(); - server.close(() => { - setTimeout(() => { - const newApp = createApplication({ secret: 'supersecret' }, 'socketio'); - server = newApp.listen(port); - - server.once('listening', () => { - newApp.io.on('connect', s => { - s.once('authenticate', data => { - expect(data.accessToken).to.equal(response.accessToken); - done(); - }); - }); - }); - }, 1000); - }); - }); + app.listen(9777); }); - it.skip('authenticates automatically after upgrade', done => { - // TODO (EK): This is working but I have no idea how to manually - // trigger socket upgrade events. - app.io.on('connect', serverSocket => { - serverSocket.on('upgrade', () => { - console.log('upgraded'); - - serverSocket.on('authenticate', data => { - expect(data.accessToken).to.be.ok; - done(); - }); - }); - }); + after(done => app.io.close(() => done())); - client.authenticate(options).then(response => { - setTimeout(() => { - app.io.engine.emit('upgrade'); - }, 500); - }); + commonTests(() => app, () => { + return feathers() + .configure(socketioClient(io('http://localhost:9777'))) + .configure(authClient()); + }, { + email: 'socketioauth@feathersjs.com', + password: 'secretive', + provider: 'socketio' }); }); diff --git a/packages/authentication-client/test/passport.test.js b/packages/authentication-client/test/passport.test.js deleted file mode 100644 index 45d71d3056..0000000000 --- a/packages/authentication-client/test/passport.test.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable no-unused-expressions */ -const { expect } = require('chai'); - -const feathers = require('@feathersjs/feathers'); -const Passport = require('../lib/passport'); -const auth = require('../lib'); - -const validToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiZXhwIjozNDc2MzkyNDgwLCJpYXQiOjE0NzYzOTI0ODAsImlzcyI6ImZlYXRoZXJzIn0.0V6NKoNszBPeIA72xWs2FDW6aPxOnHzEmskulq20uyo'; -const expiredToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJleHAiOjE0NzYzOTI0ODAsImlhdCI6MTQ3NjM5MjQ4MCwiaXNzIjoiZmVhdGhlcnMifQ.6rzpXFqWSmNEotnWo8f-SQ2Ey4rbar3f0pQKNTHdq9A'; - -describe('Passport', () => { - let passport; - let app; - let options; - - before(() => { - options = Object.assign({}, auth.defaults); - app = feathers(); - passport = new Passport(app, options); - }); - - describe.skip('getJWT', () => { - it(`get unexpired token from storage`, () => { - let storage = { - getItem () { - return Promise.resolve(validToken); - } - }; - passport.getJWT('feathers-jwt', 'feathers-jwt', storage).then(jwt => { - expect(jwt).to.equal(validToken); - }); - }); - - it(`expired jwt returns undefined`, () => { - let storage = { - getItem () { - return Promise.resolve(expiredToken); - } - }; - passport.getJWT('feathers-jwt', 'feathers-jwt', storage).then(jwt => { - expect(jwt).to.equal(undefined); - }); - }); - }); - - describe('verifyJWT', () => { - it('returns an error when token is missing', () => { - return passport.verifyJWT().catch(error => { - expect(error instanceof Error).to.equal(true); - }); - }); - - it('returns an error token is not a string', () => { - return passport.verifyJWT(true).catch(error => { - expect(error instanceof Error).to.equal(true); - }); - }); - - it('decodes a token string properly', () => { - return passport.verifyJWT(validToken).then(payload => { - expect(payload).to.deep.equal({ - id: 1, - exp: 3476392480, - iat: 1476392480, - iss: 'feathers' - }); - }); - }); - - it('gracefully handles an invalid token', () => { - let token = `lily`; - return passport.verifyJWT(token).catch(error => { - expect(error instanceof Error).to.equal(true); - }); - }); - - it('returns an error with an expired token', () => { - return passport.verifyJWT(expiredToken).catch(error => { - expect(error instanceof Error).to.equal(true); - }); - }); - }); -}); diff --git a/packages/express/lib/authentication.js b/packages/express/lib/authentication.js index 01775382cf..651d1bd5ec 100644 --- a/packages/express/lib/authentication.js +++ b/packages/express/lib/authentication.js @@ -45,7 +45,7 @@ exports.authenticate = (...strategies) => { if (!Array.isArray(settings.strategies) || settings.strategies.length === 0) { throw new Error(`'authenticate' middleware requires at least one strategy name`); } - + return function (req, res, next) { const { app, authentication } = req; const service = getService(settings, app); diff --git a/packages/express/test/authentication.test.js b/packages/express/test/authentication.test.js index 94a8bcb1a8..f19925c776 100644 --- a/packages/express/test/authentication.test.js +++ b/packages/express/test/authentication.test.js @@ -71,7 +71,7 @@ describe('@feathersjs/express/authentication', () => { try { expressify.authenticate(); assert.fail('Should never get here'); - } catch(error) { + } catch (error) { assert.strictEqual(error.message, `'authenticate' middleware requires at least one strategy name` ); @@ -87,7 +87,7 @@ describe('@feathersjs/express/authentication', () => { assert.strictEqual(authResult.user.email, email); assert.strictEqual(authResult.user.password, undefined); }); - + it('local authentication with wrong password fails', () => { return axios.post('/authentication', { strategy: 'local', @@ -101,56 +101,56 @@ describe('@feathersjs/express/authentication', () => { assert.strictEqual(data.message, 'Invalid login'); }); }); - + it('authenticating with JWT works but returns same accessToken', () => { const { accessToken } = authResult; - + return axios.post('/authentication', { strategy: 'jwt', accessToken }).then(res => { const { data } = res; - + assert.strictEqual(data.accessToken, accessToken); assert.strictEqual(data.authentication.strategy, 'jwt'); assert.strictEqual(data.authentication.payload.sub, user.id.toString()); assert.strictEqual(data.user.email, email); }); }); - + it('can make a protected request with Authorization header', () => { const { accessToken } = authResult; - + return axios.get('/dummy/dave', { headers: { Authorization: accessToken } }).then(res => { const { data, data: { params } } = res; - + assert.strictEqual(data.id, 'dave'); assert.deepStrictEqual(params.user, user); assert.strictEqual(params.authentication.accessToken, accessToken); }); }); - + it('can make a protected request with Authorization header and bearer scheme', () => { const { accessToken } = authResult; - + return axios.get('/dummy/dave', { headers: { Authorization: ` Bearer: ${accessToken}` } }).then(res => { const { data, data: { params } } = res; - + assert.strictEqual(data.id, 'dave'); assert.deepStrictEqual(params.user, user); assert.strictEqual(params.authentication.accessToken, accessToken); }); }); }); - + describe('authenticate middleware', () => { it('protected endpoint fails when JWT is not present', () => { return axios.get('/protected').then(() => {