From c7771fe41ba4984c65f050486ccc7676ed0b6dc0 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 12 Nov 2018 09:02:23 -0800 Subject: [PATCH 01/62] npm init --- package.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..4d77cc5 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "@snowjs/cli", + "version": "0.0.0", + "description": "Self-hosted now deployments", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/snowjs/cli.git" + }, + "author": "Peter Mikitsh ", + "license": "MIT", + "bugs": { + "url": "https://github.com/snowjs/cli/issues" + }, + "homepage": "https://github.com/snowjs/cli#readme" +} From a9ab8f4288d903cc860ec005f3da26456bc0e1da Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 12 Nov 2018 11:24:39 -0800 Subject: [PATCH 02/62] 'secrets', 'ls' subcommands --- .gitignore | 1 + .npmrc | 2 + package.json | 21 +- src/index.js | 45 + yarn.lock | 2848 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 2915 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 .npmrc create mode 100755 src/index.js create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..32ef673 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +registry=https://registry.npmjs.org/ +save-exact=true diff --git a/package.json b/package.json index 4d77cc5..38d8d1b 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,17 @@ "name": "@snowjs/cli", "version": "0.0.0", "description": "Self-hosted now deployments", - "main": "index.js", + "main": "src/index.js", + "engines": { + "node": ">=8.0.0" + }, "scripts": { + "lint": "xo", "test": "echo \"Error: no test specified\" && exit 1" }, + "bin": { + "snow": "src/index.js" + }, "repository": { "type": "git", "url": "git+https://github.com/snowjs/cli.git" @@ -15,5 +22,15 @@ "bugs": { "url": "https://github.com/snowjs/cli/issues" }, - "homepage": "https://github.com/snowjs/cli#readme" + "homepage": "https://github.com/snowjs/cli#readme", + "dependencies": { + "chalk": "2.4.1", + "mri": "1.1.1" + }, + "devDependencies": { + "xo": "0.23.0" + }, + "xo": { + "space": true + } } diff --git a/src/index.js b/src/index.js new file mode 100755 index 0000000..699a501 --- /dev/null +++ b/src/index.js @@ -0,0 +1,45 @@ +#!/usr/bin/env node + +const childProcess = require('child_process'); +const util = require('util'); +const chalk = require('chalk'); +const mri = require('mri'); + +const exec = util.promisify(childProcess.exec); + +async function run(str) { + try { + const {stdout} = await exec(str); + console.log(stdout); + } catch (error) { + console.log(chalk.red(error.stderr)); + } +} + +function isRemove(str) { + return str === 'rm' || str === 'remove'; +} + +async function main() { + const {_} = mri(process.argv.slice(2)); + const [subcommand, ...rest] = _; + + if (subcommand === 'ls') { + const [deployment] = rest; + await run(`kubectl get deployments ${deployment}`); + } + if (subcommand === 'secrets') { + const [action, key, value] = rest; + if (action === 'ls') { + await run('kubectl get secrets'); + } + if (action === 'add') { + await run(`kubectl create secret generic ${key} --from-literal=${key}=${value}`); + } + if (isRemove(action)) { + await run(`kubectl delete secret ${key}`); + } + } +} + +main(); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..8dac550 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2848 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +acorn-jsx@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz#958584ddb60990c02c97c1bd9d521fce433bb101" + integrity sha512-XkB50fn0MURDyww9+UYL3c1yLbOBz0ZFvrdYlGB8l+Ije1oSC75qAqrzSPjYQbdnQUzhlUGNKuesryAv0gxZOg== + +acorn@^6.0.2: + version "6.0.4" + resolved "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" + integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== + +ajv@^6.5.3: + version "6.5.5" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" + integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + integrity sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs= + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +buf-compare@^1.0.0: + version "1.0.1" + resolved "http://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + integrity sha1-/vKNqLgROgoNtEMLC2Rntpcws0o= + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^4.0.0, camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: + version "2.4.1" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" + integrity sha1-jffHquUf02h06PjQW5GAvBGj/tc= + dependencies: + escape-string-regexp "^1.0.5" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-assert@^0.2.0: + version "0.2.1" + resolved "http://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" + integrity sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8= + dependencies: + buf-compare "^1.0.0" + is-error "^2.2.0" + +core-js@^2.0.0: + version "2.5.7" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1: + version "4.1.0" + resolved "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + dependencies: + ms "^2.1.1" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deep-strict-equal@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz#4a078147a8ab57f6a0d4f5547243cd22f44eb4e4" + integrity sha1-SgeBR6irV/ag1PVUckPNIvROtOQ= + dependencies: + core-assert "^0.2.0" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +enhance-visitors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz#aa945d05da465672a1ebd38fee2ed3da8518e95a" + integrity sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo= + dependencies: + lodash "^4.13.1" + +env-editor@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/env-editor/-/env-editor-0.3.1.tgz#30d0540c2101414f258a94d4c0a524c06c13e3c6" + integrity sha1-MNBUDCEBQU8lipTUwKUkwGwT48Y= + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-ast-utils@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz#3d58ba557801cfb1c941d68131ee9f8c34bd1586" + integrity sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA== + dependencies: + lodash.get "^4.4.2" + lodash.zip "^4.2.0" + +eslint-config-prettier@^3.0.1: + version "3.3.0" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz#41afc8d3b852e757f06274ed6c44ca16f939a57d" + integrity sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA== + dependencies: + get-stdin "^6.0.0" + +eslint-config-xo@^0.25.0: + version "0.25.0" + resolved "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.25.0.tgz#8e8bbdee06e3d75b47aeba03fb28d4a43cc8092f" + integrity sha512-bViV+I3smPWzzhI15U9PIk5CTt1Ym/GqdtRMIK/LePqp0yKLgw+WC51bBZEPgrKcib79uwwOLVPrv+nzoJJj+g== + +eslint-formatter-pretty@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-1.3.0.tgz#985d9e41c1f8475f4a090c5dbd2dfcf2821d607e" + integrity sha512-5DY64Y1rYCm7cfFDHEGUn54bvCnK+wSUVF07N8oXeqUJFSd+gnYOTXbzelQ1HurESluY6gnEQPmXOIkB4Wa+gA== + dependencies: + ansi-escapes "^2.0.0" + chalk "^2.1.0" + log-symbols "^2.0.0" + plur "^2.1.2" + string-width "^2.0.0" + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-ava@^5.1.0: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-5.1.1.tgz#709a03f6c56f9f316d83ebc739952cc28cea979a" + integrity sha512-3N7geVdXTabpngQOl+ih1ejMbFOXCUYROnTIP66KAQoMcEAkPSXYc/Jwo/qC4zpRR7PXMuf5afMzTEBpyZmWzQ== + dependencies: + arrify "^1.0.1" + deep-strict-equal "^0.2.0" + enhance-visitors "^1.0.0" + esm "^3.0.82" + espree "^4.0.0" + espurify "^1.8.1" + import-modules "^1.1.0" + is-plain-object "^2.0.4" + multimatch "^2.1.0" + pkg-up "^2.0.0" + +eslint-plugin-es@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.3.2.tgz#6d2e94ed40db3b3d92a0eb55c7c06e3a7adbb3db" + integrity sha512-xrdbConViY20DhGrt9FwjhDo4fr/9Yus2pYf0xJsdJaCcUzMq7+pAoNH7kSXF6V08bRHMpgDWclYbcr/Sn3hNg== + dependencies: + eslint-utils "^1.3.0" + regexpp "^2.0.1" + +eslint-plugin-import@^2.14.0: + version "2.14.0" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" + integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== + dependencies: + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" + +eslint-plugin-no-use-extend-native@^0.3.12: + version "0.3.12" + resolved "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.3.12.tgz#3ad9a00c2df23b5d7f7f6be91550985a4ab701ea" + integrity sha1-OtmgDC3yO11/f2vpFVCYWkq3Aeo= + dependencies: + is-get-set-prop "^1.0.0" + is-js-type "^2.0.0" + is-obj-prop "^1.0.0" + is-proto-prop "^1.0.0" + +eslint-plugin-node@^7.0.0: + version "7.0.1" + resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz#a6e054e50199b2edd85518b89b4e7b323c9f36db" + integrity sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw== + dependencies: + eslint-plugin-es "^1.3.1" + eslint-utils "^1.3.1" + ignore "^4.0.2" + minimatch "^3.0.4" + resolve "^1.8.1" + semver "^5.5.0" + +eslint-plugin-prettier@^2.6.0: + version "2.7.0" + resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" + integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== + dependencies: + fast-diff "^1.1.1" + jest-docblock "^21.0.0" + +eslint-plugin-promise@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" + integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== + +eslint-plugin-unicorn@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-6.0.1.tgz#4a97f0bc9449e20b82848dad12094ee2ba72347e" + integrity sha512-hjy9LhTdtL7pz8WTrzS0CGXRkWK3VAPLDjihofj8JC+uxQLfXm0WwZPPPB7xKmcjRyoH+jruPHOCrHNEINpG/Q== + dependencies: + clean-regexp "^1.0.0" + eslint-ast-utils "^1.0.0" + import-modules "^1.1.0" + lodash.camelcase "^4.1.1" + lodash.kebabcase "^4.0.1" + lodash.snakecase "^4.0.1" + lodash.upperfirst "^4.2.0" + safe-regex "^1.1.0" + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.0, eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^5.5.0: + version "5.9.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" + integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.5.3" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^2.1.0" + eslint-scope "^4.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + imurmurhash "^0.1.4" + inquirer "^6.1.0" + is-resolvable "^1.1.0" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.5" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^2.0.1" + require-uncached "^1.0.3" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.0.2" + text-table "^0.2.0" + +esm@^3.0.82: + version "3.0.84" + resolved "https://registry.npmjs.org/esm/-/esm-3.0.84.tgz#bb108989f4673b32d4f62406869c28eed3815a63" + integrity sha512-SzSGoZc17S7P+12R9cg21Bdb7eybX25RnIeRZ80xZs+VZ3kdQKzqTp2k4hZJjR7p9l0186TTXSgrxzlMDBktlw== + +espree@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" + integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== + dependencies: + acorn "^6.0.2" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +espurify@^1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz#5746c6c1ab42d302de10bd1d5bf7f0e8c0515056" + integrity sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg== + dependencies: + core-js "^2.0.0" + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.9.0: + version "0.9.0" + resolved "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + integrity sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA== + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +external-editor@^3.0.0: + version "3.0.3" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-diff@^1.1.1: + version "1.2.0" + resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^2.0.2: + version "2.2.4" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" + integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.3.2" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.2.tgz#7f852d70be573dac874a4c4129d340a34fba7e65" + integrity sha512-KByBY8c98sLUAGpnmjEdWTrtrLZRtZdwds+kAL/ciFXTCb7AZgqKsAnVnYFQj1hxepwO8JKN/8AsRWwLq+RK0A== + dependencies: + circular-json "^0.3.1" + del "^3.0.0" + graceful-fs "^4.1.2" + write "^0.2.1" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-set-props@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz#998475c178445686d0b32246da5df8dbcfbe8ea3" + integrity sha1-mYR1wXhEVobQsyJG2l3428++jqM= + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@^3.0.0: + version "3.0.0" + resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: + version "7.1.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +globals@^11.7.0: + version "11.9.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" + integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^8.0.0: + version "8.0.1" + resolved "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2: + version "4.1.15" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" + integrity sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac= + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.2, ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-modules@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" + integrity sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^6.1.0: + version "6.2.0" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" + integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +irregular-plurals@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" + integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-error@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" + integrity sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw= + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-get-set-prop@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz#2731877e4d78a6a69edcce6bb9d68b0779e76312" + integrity sha1-JzGHfk14pqae3M5rudaLB3nnYxI= + dependencies: + get-set-props "^0.1.0" + lowercase-keys "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-js-type@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz#73617006d659b4eb4729bba747d28782df0f7e22" + integrity sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI= + dependencies: + js-types "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-obj-prop@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz#b34de79c450b8d7c73ab2cdf67dc875adb85f80e" + integrity sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4= + dependencies: + lowercase-keys "^1.0.0" + obj-props "^1.0.0" + +is-obj@^1.0.0: + version "1.0.1" + resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-proto-prop@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.1.tgz#c8a0455c28fe38c8843d0c22af6f95f01ed4abc4" + integrity sha512-dkmgrJB7nfJhH1ySK1/Qn9xLPMv3ZNlPSAPoyUseD6DQzBF6YmbgQnoyy9OM8derNUlDVJlUGdCEhYbcCPfN5A== + dependencies: + lowercase-keys "^1.0.0" + proto-props "^1.1.0" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@1.0.0, isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +jest-docblock@^21.0.0: + version "21.2.0" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" + integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-types@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz#d242e6494ed572ad3c92809fc8bed7f7687cbf03" + integrity sha1-0kLmSU7Vcq08koCfyL7X92h8vwM= + +js-yaml@^3.12.0: + version "3.12.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +line-column-path@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/line-column-path/-/line-column-path-1.0.0.tgz#383b83fca8488faa7a59940ebf28b82058c16c55" + integrity sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU= + +load-json-file@^2.0.0: + version "2.0.0" + resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.camelcase@^4.1.1: + version "4.3.0" + resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.kebabcase@^4.0.1: + version "4.1.1" + resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.mergewith@^4.6.1: + version "4.6.1" + resolved "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== + +lodash.snakecase@^4.0.1: + version "4.1.1" + resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= + +lodash.upperfirst@^4.2.0: + version "4.3.1" + resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" + integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= + +lodash.zip@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" + integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= + +lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: + version "4.17.11" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log-symbols@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^4.0.1: + version "4.1.3" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +meow@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + yargs-parser "^10.0.0" + +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1: + version "0.5.1" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mri@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1" + integrity sha1-haom09ru7t+A3FmEr5XMXKXK2fE= + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.4.0" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +obj-props@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz#626313faa442befd4a44e9a02c3cb6bde937b511" + integrity sha1-YmMT+qRCvv1KROmgLDy2vek3tRE= + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +open-editor@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/open-editor/-/open-editor-1.2.0.tgz#75ca23f0b74d4b3f55ee0b8a4e0f5c2325eb775f" + integrity sha1-dcoj8LdNSz9V7guKTg9cIyXrd18= + dependencies: + env-editor "^0.3.1" + line-column-path "^1.0.0" + opn "^5.0.0" + +opn@^5.0.0: + version "5.4.0" + resolved "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" + integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.5: + version "1.0.6" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pify@^2.0.0: + version "2.3.0" + resolved "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-conf@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" + integrity sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg= + dependencies: + find-up "^2.0.0" + load-json-file "^4.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +plur@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= + dependencies: + irregular-plurals "^1.0.0" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prettier@^1.12.1: + version "1.15.2" + resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" + integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== + +progress@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" + integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== + +proto-props@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/proto-props/-/proto-props-1.1.0.tgz#e2606581dd24aa22398aeeeb628fc08e2ec89c91" + integrity sha512-A377CdhQBRjYVsSWrm2jo0KJa+N/IBew6lGLm0pdzZjtVqlUT23wEqg7q1/bk5gBEgVoBBbaErZY+UUNrcKOug== + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +rc@^1.0.1, rc@^1.1.6: + version "1.2.8" + resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +registry-auth-token@^3.0.1: + version "3.3.2" + resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-uncached@^1.0.3: + version "1.0.3" + resolved "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== + dependencies: + path-parse "^1.0.5" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.2.8: + version "2.6.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +rxjs@^6.1.0: + version "6.3.3" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.5.0, semver@^5.5.1: + version "5.6.0" + resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +spdx-correct@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" + integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +table@^5.0.2: + version "5.1.0" + resolved "https://registry.npmjs.org/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" + integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg== + dependencies: + ajv "^6.5.3" + lodash "^4.17.10" + slice-ansi "1.0.0" + string-width "^2.1.1" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +the-argv@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz#0084705005730dd84db755253c931ae398db9522" + integrity sha1-AIRwUAVzDdhNt1UlPJMa45jblSI= + +through@^2.3.6: + version "2.3.8" + resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-json-file@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xo-init@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/xo-init/-/xo-init-0.7.0.tgz#634b4789e366b4f87f747ef0cee1a99ce273aa15" + integrity sha512-mrrCKMu52vz0u2tiOl8DoG709pBtnSp58bb4/j58a4jeXjrb1gV7dxfOBjOlXitYtfW2QnlxxxfAojoFcpynDg== + dependencies: + arrify "^1.0.0" + execa "^0.9.0" + has-yarn "^1.0.0" + minimist "^1.1.3" + path-exists "^3.0.0" + read-pkg-up "^3.0.0" + the-argv "^1.0.0" + write-pkg "^3.1.0" + +xo@0.23.0: + version "0.23.0" + resolved "https://registry.npmjs.org/xo/-/xo-0.23.0.tgz#dbc709b0e5e38060a497a39d147a173ddd36d355" + integrity sha512-jyNZrGULm1oPgL0AMWWFWr3Q2cLsULrIkBsogIGWEUw/wGu47N3XGNmUwB4AvJcMhveNK2gqndY3+z8m0CJFEA== + dependencies: + arrify "^1.0.1" + debug "^3.1.0" + eslint "^5.5.0" + eslint-config-prettier "^3.0.1" + eslint-config-xo "^0.25.0" + eslint-formatter-pretty "^1.3.0" + eslint-plugin-ava "^5.1.0" + eslint-plugin-import "^2.14.0" + eslint-plugin-no-use-extend-native "^0.3.12" + eslint-plugin-node "^7.0.0" + eslint-plugin-prettier "^2.6.0" + eslint-plugin-promise "^4.0.0" + eslint-plugin-unicorn "^6.0.1" + get-stdin "^6.0.0" + globby "^8.0.0" + has-flag "^3.0.0" + lodash.isequal "^4.5.0" + lodash.mergewith "^4.6.1" + meow "^5.0.0" + multimatch "^2.1.0" + open-editor "^1.2.0" + path-exists "^3.0.0" + pkg-conf "^2.1.0" + prettier "^1.12.1" + resolve-cwd "^2.0.0" + resolve-from "^4.0.0" + semver "^5.5.0" + slash "^2.0.0" + update-notifier "^2.3.0" + xo-init "^0.7.0" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" From 9e7b46f05d4da86eb230ff1c14cc5b37c30db325 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 12 Nov 2018 11:30:06 -0800 Subject: [PATCH 03/62] Update README --- README.md | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index a694eee..f66bf73 100644 --- a/README.md +++ b/README.md @@ -18,21 +18,18 @@ snow Without arguments, deploys just like `now`. -| Support | Command | Description | -|---------|------------------------|-------------------| -| :x: | \ | Deploy | -| :x: | `alias` | Alias deployment | -| :x: | `deploy` | Deploy | -| :x: | `domains` | List domains | -| :x: | `domains add [domain]` | Add domain | -| :x: | `domains rm [domain]` | Remove domain | -| :x: | `login` | Login | -| :x: | `logout` | Logout | -| :x: | `ls` | List deployments | -| :x: | `rm [name]` | Remove deployment | -### Flags - -| Support | Command | Flag | Description | -|---------|---------|-------------------|----------------------| -| :x: | \ | `--token [token]` | Authentication token | -| :x: | `login` | `--host [host]` | Snow server hostname | \ No newline at end of file +| Support | Command | Description | +|--------------------|-----------------------------|-------------------| +| :x: | \ | Create deployment | +| :x: | `alias` | Alias deployment | +| :x: | `deploy` | Deploy | +| :x: | `domains` | List domains | +| :x: | `domains add [domain]` | Add domain | +| :x: | `domains rm [domain]` | Remove domain | +| :x: | `login` | Login | +| :x: | `logout` | Logout | +| :white_check_mark: | `ls` | List deployments | +| :x: | `rm [name]` | Remove deployment | +| :white_check_mark: | `secrets ls` | List secrets | +| :white_check_mark: | `secrets add [key] [value]` | Create secret | +| :white_check_mark: | `secrets rm [key]` | Remove secret | \ No newline at end of file From 02d99e1020303cec0edd4be4e5fb3aa7b476ce94 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 12 Nov 2018 17:53:36 -0800 Subject: [PATCH 04/62] remove deployment --- README.md | 6 ++---- src/index.js | 10 +++++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f66bf73..4f57bec 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,12 @@ Enjoy effortless deployments with a clone of [now](https://github.com/zeit/now-c ``` curl -sSL https://get.snowjs.app/ | sh -npm i -g snow-cli +npm i -g @snowjs/cli snow ``` ### Supported commands -Without arguments, deploys just like `now`. - | Support | Command | Description | |--------------------|-----------------------------|-------------------| | :x: | \ | Create deployment | @@ -29,7 +27,7 @@ Without arguments, deploys just like `now`. | :x: | `login` | Login | | :x: | `logout` | Logout | | :white_check_mark: | `ls` | List deployments | -| :x: | `rm [name]` | Remove deployment | +| :white_check_mark: | `rm [name]` | Remove deployment | | :white_check_mark: | `secrets ls` | List secrets | | :white_check_mark: | `secrets add [key] [value]` | Create secret | | :white_check_mark: | `secrets rm [key]` | Remove secret | \ No newline at end of file diff --git a/src/index.js b/src/index.js index 699a501..9f73e10 100755 --- a/src/index.js +++ b/src/index.js @@ -22,13 +22,17 @@ function isRemove(str) { async function main() { const {_} = mri(process.argv.slice(2)); - const [subcommand, ...rest] = _; + const [command, ...rest] = _; - if (subcommand === 'ls') { + if (command === 'ls') { const [deployment] = rest; await run(`kubectl get deployments ${deployment}`); } - if (subcommand === 'secrets') { + if (isRemove(command)) { + const [deployment] = rest; + await run(`kubectl delete deploy ${deployment}`); + } + if (command === 'secrets') { const [action, key, value] = rest; if (action === 'ls') { await run('kubectl get secrets'); From 1600ddae42da5cab52ce4f7cad1130f421982e10 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 12 Nov 2018 18:40:10 -0800 Subject: [PATCH 05/62] deploy command (wip) --- src/index.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/index.js b/src/index.js index 9f73e10..e65a24a 100755 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,15 @@ #!/usr/bin/env node const childProcess = require('child_process'); +const fs = require('fs'); +const path = require('path'); const util = require('util'); const chalk = require('chalk'); const mri = require('mri'); const exec = util.promisify(childProcess.exec); +const stat = util.promisify(fs.stat); +const readFile = util.promisify(fs.readFile); async function run(str) { try { @@ -24,6 +28,64 @@ async function main() { const {_} = mri(process.argv.slice(2)); const [command, ...rest] = _; + if (_.length === 0 || command === 'deploy') { + // First: Verify we have a Dockerfile. + const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); + try { + await stat(dockerFilePath); + } catch (error) { + const msg = `Error finding Dockerfile.\n${error.message}`; + console.log(chalk.red(msg)); + return; + } + + // Second: Verify we have a now.json file. + const nowFilePath = path.resolve(process.cwd(), 'now.json'); + let nowConfig; + try { + const nowFile = await readFile(nowFilePath); + nowConfig = JSON.parse(nowFile.toString()); + } catch (error) { + console.log(chalk.red(`Error reading now.json.\n${error.message}`)); + return; + } + + // Third: Build and tag the image. + const {name} = nowConfig; + if (!name) { + console.log(chalk.red('Specify a "name" in now.json')); + return; + } + const imageName = `${name}:latest`; + try { + await exec(`docker build -t ${imageName} -f ./Dockerfile .`); + console.log(`Docker image built => ${imageName}`); + } catch (error) { + console.log(`Could not build image from Dockerfile.\n${error.message}`); + } + + // Fourth: Start a local Docker registry, if necessary. + let registryRunning = true; + try { + const {stdout} = await exec('docker ps --format "{{.Names}}" -f "name=registry"'); + if (!stdout) { + registryRunning = false; + } + } catch (error) { + console.log(`Could not determine if registry started.\n${error.message}`); + return; + } + if (!registryRunning) { + try { + await exec('docker run -d -p 5000:5000 --restart=always --name registry registry:2'); + } catch (error) { + console.log(`Could not start local Docker registry.\n${error.message}`); + return; + } + } + + // Fifth: Push image to local registry. + } if (command === 'ls') { const [deployment] = rest; await run(`kubectl get deployments ${deployment}`); From 4d445ef08fe00078f68ce1e2ab8a4bf68a045397 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Wed, 19 Dec 2018 06:59:14 -0800 Subject: [PATCH 06/62] split cli cmds into separate files; add 'install' cmd --- README.md | 44 ++++++++++++++++-- package.json | 3 ++ src/create.js | 74 ++++++++++++++++++++++++++++++ src/deploy.js | 68 +++++++++++++++++++++++++++ src/index.js | 121 ++++++++++++------------------------------------- src/install.js | 53 ++++++++++++++++++++++ src/ls.js | 6 +++ src/remove.js | 6 +++ src/secrets.js | 14 ++++++ src/utils.js | 76 +++++++++++++++++++++++++++++++ 10 files changed, 371 insertions(+), 94 deletions(-) create mode 100644 src/create.js create mode 100644 src/deploy.js create mode 100644 src/install.js create mode 100644 src/ls.js create mode 100644 src/remove.js create mode 100644 src/secrets.js create mode 100644 src/utils.js diff --git a/README.md b/README.md index 4f57bec..e460321 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,26 @@ > :snowflake: **S**elf-hosted **now** deployments -Enjoy effortless deployments with a clone of [now](https://github.com/zeit/now-cli) on your own hardware. +Enjoy effortless deployments with a clone of [now][now] on a cloud of your choosing. + +### This is Magic 🔮 + +No, it isn't. This CLI abstracts away the complexities of using [Kubernetes][kubernetes] to replicate the functionality provided by `now`. ### Getting started ``` -curl -sSL https://get.snowjs.app/ | sh npm i -g @snowjs/cli + +# Install CLI tools +snow install + +# Create your kubernetes cluster (GCP) +snow create + +# Create a DNS 'A' record (e.g., myapp.com A 1.2.3.4) + +# Deploy your app snow ``` @@ -30,4 +43,29 @@ snow | :white_check_mark: | `rm [name]` | Remove deployment | | :white_check_mark: | `secrets ls` | List secrets | | :white_check_mark: | `secrets add [key] [value]` | Create secret | -| :white_check_mark: | `secrets rm [key]` | Remove secret | \ No newline at end of file +| :white_check_mark: | `secrets rm [key]` | Remove secret | + +### Tell me more + +Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. When you create your cluster via `snow`, we install [tiller][helm], which is used to install [traefik] as an [ingress object][ingress], which (1) automanages the SSL certificate lifecycle and (2) maps aliases to deployments. SSL terminiation occurs prior to requests reaching deployments. + +When you create a deployment, your project must have `Dockerfile` and `now.json` files. An image is created from the Dockerfile, pushed to a Docker registry, and deployed to Kubernetes. Aliases from `now.json` will point to the deployment. If necessary, new SSL certificates will be created. + +For your domain name to be resolvable by Kubernetes, you must create a DNS `A` record, which points to the IP Address of your [traefik] ingress. + +The following CLI tools (installable via `snow install`) are necessary to orchestrate the entire end-to-end process, from Kubernetes cluster creation to managing your deployments: + +- `virtualbox` (for creating docker images) +- `docker` (for running local registry) +- `helm` (for installing [tiller][helm] and [traefik] on your cluster) +- `kubectl` (for managing deployments, secrets) +- one of [`minikube`, `gcloud`] + +[now]: https://github.com/zeit/now-cli +[ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ +[kubernetes]: https://kubernetes.io/ +[helm]: https://docs.helm.sh/ +[docker]: https://www.docker.com/ +[letsencrypt]: https://letsencrypt.org/ +[minikube]: https://kubernetes.io/docs/setup/minikube/ +[traefik]: https://traefik.io/ \ No newline at end of file diff --git a/package.json b/package.json index 38d8d1b..8f42c9c 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,9 @@ "xo": "0.23.0" }, "xo": { + "rules": { + "no-await-in-loop": 0 + }, "space": true } } diff --git a/src/create.js b/src/create.js new file mode 100644 index 0000000..9ff1b8c --- /dev/null +++ b/src/create.js @@ -0,0 +1,74 @@ +const path = require('path'); +const chalk = require('chalk'); +const {exec, pickOne, run} = require('./utils'); + +module.exports = async function () { + const cloudProviders = ['minikube', 'gcp']; + const question = 'Which cloud provider are you hosting with (minikube,gcp)'; + const provider = await pickOne(question, cloudProviders); + switch (provider) { + case 'minikube': { + const msgs = [ + 'Note: Minikube is for development purposes only.', + 'Starting Minikube. This may take a minute.' + ]; + const msg = chalk.bold.white(msgs.join('\n')); + console.log(msg); + await run('minikube start'); + await run('minikube addons enable ingress'); + await run('helm init --wait'); + + // Install traefik and kaniko + await run('helm install stable/traefik --name traefik --namespace kube-system --set serviceType=NodePort,dashboard.enabled=true,dashboard.domain=traefik-ui.minikube'); + // Put an example deployment on the server + // await run('kubectl run whoami --image=emilevauge/whoami --port=80 --replicas=5 --expose'); + // await run('kubectl apply -f whoami-ingress.yml'); + // await run(`kubectl apply -f ${path.resolve(__dirname, '../config/kaniko.yaml')}`); + break; + } + case 'gcp': { + // Check if we need to authenticate. + try { + const {stdout} = await exec('gcloud auth list'); + const isAuthenticated = stdout.indexOf('*') > -1; + if (!isAuthenticated) { + await run('gcloud auth login'); + } + } catch (error) { + await run('gcloud auth login'); + } + + const {stdout} = await exec('gcloud config get-value project'); + const projectId = stdout.trim(); + await run('gcloud services enable container.googleapis.com'); + const createClusterCmd = ` + gcloud beta container \ + clusters create "snow-cluster" \ + --zone "us-west1-b" \ + --no-enable-basic-auth \ + --cluster-version "1.10.9-gke.5" \ + --image-type "COS" \ + --machine-type "f1-micro" \ + --disk-type "pd-standard" \ + --disk-size "10" \ + --default-max-pods-per-node "110" \ + --num-nodes "3" \ + --enable-cloud-logging \ + --enable-cloud-monitoring \ + --enable-ip-alias \ + --network "projects/${projectId}/global/networks/default" \ + --subnetwork "projects/${projectId}/regions/us-west1/subnetworks/default" \ + --default-max-pods-per-node "110" \ + --addons HorizontalPodAutoscaling,HttpLoadBalancing \ + --enable-autoupgrade \ + --enable-autorepair \ + --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/trace.append" \ + `; + await run(createClusterCmd); + break; + } + default: { + console.log(chalk.bold.red('No valid cloud provider selected.')); + } + } +}; diff --git a/src/deploy.js b/src/deploy.js new file mode 100644 index 0000000..f461ba9 --- /dev/null +++ b/src/deploy.js @@ -0,0 +1,68 @@ + +const path = require('path'); +const chalk = require('chalk'); +const {exec, readFile, stat} = require('./utils'); + +module.exports = async function () { + // First: Verify we have a Dockerfile. + const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); + try { + await stat(dockerFilePath); + } catch (error) { + const msg = `Error finding Dockerfile.\n${error.message}`; + console.log(chalk.red(msg)); + return; + } + + // Second: Verify we have a now.json file. + const nowFilePath = path.resolve(process.cwd(), 'now.json'); + let nowConfig; + try { + const nowFile = await readFile(nowFilePath); + nowConfig = JSON.parse(nowFile.toString()); + } catch (error) { + console.log(chalk.red(`Error reading now.json.\n${error.message}`)); + return; + } + + // Third: Build and tag the image. + const {name} = nowConfig; + if (!name) { + console.log(chalk.red('Specify a "name" in now.json')); + return; + } + const imageName = `${name}:latest`; + try { + await exec(`docker build -t ${imageName} -f ./Dockerfile .`); + console.log(`Docker image built => ${imageName}`); + } catch (error) { + console.log(`Could not build image from Dockerfile.\n${error.message}`); + } + + // Fourth: Start a local Docker registry, if necessary. + let registryRunning = true; + try { + const {stdout} = await exec('docker ps --format "{{.Names}}" -f "name=registry"'); + if (!stdout) { + registryRunning = false; + } + } catch (error) { + console.log(`Could not determine if registry started.\n${error.message}`); + return; + } + if (!registryRunning) { + try { + await exec('docker run -d -p 5000:5000 --restart=always --name registry registry:2'); + } catch (error) { + console.log(`Could not start local Docker registry.\n${error.message}`); + } + } + + // Fifth: Push image to local registry. + + // Sixth: Create or update a deployment. + + // Seventh: Create or update a service. + + // Eight: Create or update the ingress resource. +}; diff --git a/src/index.js b/src/index.js index e65a24a..854f58a 100755 --- a/src/index.js +++ b/src/index.js @@ -1,109 +1,48 @@ #!/usr/bin/env node -const childProcess = require('child_process'); -const fs = require('fs'); -const path = require('path'); -const util = require('util'); const chalk = require('chalk'); const mri = require('mri'); - -const exec = util.promisify(childProcess.exec); -const stat = util.promisify(fs.stat); -const readFile = util.promisify(fs.readFile); - -async function run(str) { - try { - const {stdout} = await exec(str); - console.log(stdout); - } catch (error) { - console.log(chalk.red(error.stderr)); - } -} - -function isRemove(str) { - return str === 'rm' || str === 'remove'; -} +const create = require('./create'); +const deploy = require('./deploy'); +const install = require('./install'); +const ls = require('./ls'); +const remove = require('./remove'); +const secrets = require('./secrets'); +const {isRemove} = require('./utils'); async function main() { const {_} = mri(process.argv.slice(2)); const [command, ...rest] = _; - if (_.length === 0 || command === 'deploy') { - // First: Verify we have a Dockerfile. - const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); - try { - await stat(dockerFilePath); - } catch (error) { - const msg = `Error finding Dockerfile.\n${error.message}`; - console.log(chalk.red(msg)); - return; + switch (command) { + case 'create': { + await create(rest); + break; } - - // Second: Verify we have a now.json file. - const nowFilePath = path.resolve(process.cwd(), 'now.json'); - let nowConfig; - try { - const nowFile = await readFile(nowFilePath); - nowConfig = JSON.parse(nowFile.toString()); - } catch (error) { - console.log(chalk.red(`Error reading now.json.\n${error.message}`)); - return; + case undefined: + case 'deploy': { + await deploy(rest); + break; } - - // Third: Build and tag the image. - const {name} = nowConfig; - if (!name) { - console.log(chalk.red('Specify a "name" in now.json')); - return; + case 'install': { + await install(rest); + break; } - const imageName = `${name}:latest`; - try { - await exec(`docker build -t ${imageName} -f ./Dockerfile .`); - console.log(`Docker image built => ${imageName}`); - } catch (error) { - console.log(`Could not build image from Dockerfile.\n${error.message}`); + case 'ls': { + await ls(rest); + break; } - - // Fourth: Start a local Docker registry, if necessary. - let registryRunning = true; - try { - const {stdout} = await exec('docker ps --format "{{.Names}}" -f "name=registry"'); - if (!stdout) { - registryRunning = false; - } - } catch (error) { - console.log(`Could not determine if registry started.\n${error.message}`); - return; - } - if (!registryRunning) { - try { - await exec('docker run -d -p 5000:5000 --restart=always --name registry registry:2'); - } catch (error) { - console.log(`Could not start local Docker registry.\n${error.message}`); - return; - } - } - - // Fifth: Push image to local registry. - } - if (command === 'ls') { - const [deployment] = rest; - await run(`kubectl get deployments ${deployment}`); - } - if (isRemove(command)) { - const [deployment] = rest; - await run(`kubectl delete deploy ${deployment}`); - } - if (command === 'secrets') { - const [action, key, value] = rest; - if (action === 'ls') { - await run('kubectl get secrets'); + case isRemove(command): { + await remove(rest); + break; } - if (action === 'add') { - await run(`kubectl create secret generic ${key} --from-literal=${key}=${value}`); + case 'secrets': { + await secrets(rest); + break; } - if (isRemove(action)) { - await run(`kubectl delete secret ${key}`); + default: { + const errMsg = `Error: Invalid command: snow ${command} ${rest.join(' ')}`; + console.log(chalk.bold.red(errMsg)); } } } diff --git a/src/install.js b/src/install.js new file mode 100644 index 0000000..332669b --- /dev/null +++ b/src/install.js @@ -0,0 +1,53 @@ +const {confirm, exec, run} = require('./utils'); + +module.exports = async function () { + const dependencies = [{ + label: 'Virtualbox', + detectCmd: 'which virtualbox', + installCmd: 'brew cask install virtualbox' + }, { + label: 'Docker', + detectCmd: 'which docker', + installCmd: 'brew cask install docker' + }, { + label: 'Kubernetes', + detectCmd: 'which kubectl', + installCmd: 'brew install kubernetes-cli' + }, { + label: 'Helm', + detectCmd: 'which helm', + installCmd: 'brew install kubernetes-helm' + }, { + label: 'Minikube', + detectCmd: 'which minikube', + installCmd: 'brew cask install minikube' + }, { + label: 'Google Cloud SDK (gcloud)', + detectCmd: 'which gcloud', + installCmd: 'brew cask install google-cloud-sdk' + }, { + label: 'Google Cloud SDK (gcloud) Beta Commands', + detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', + installCmd: 'gcloud components install beta --quiet', + detectAdvanced: output => { + return output.indexOf('Not Installed | gcloud Beta Commands') > -1; + } + }]; + + async function tryInstall(label, installCmd) { + if (await confirm(`Install ${label}`)) { + await run(installCmd); + } + } + + for (const {label, detectCmd, detectAdvanced, installCmd} of dependencies) { + try { + const {stdout} = await exec(detectCmd); + if (detectAdvanced && detectAdvanced(stdout)) { + tryInstall(label, installCmd); + } + } catch (error) { + tryInstall(label, installCmd); + } + } +}; diff --git a/src/ls.js b/src/ls.js new file mode 100644 index 0000000..8806050 --- /dev/null +++ b/src/ls.js @@ -0,0 +1,6 @@ +const {run} = require('./utils'); + +module.exports = async function (args) { + const [deployment] = args; + await run(`kubectl get deployments ${deployment}`); +}; diff --git a/src/remove.js b/src/remove.js new file mode 100644 index 0000000..5ed07cb --- /dev/null +++ b/src/remove.js @@ -0,0 +1,6 @@ +const {run} = require('./utils'); + +module.exports = async function (args) { + const [deployment] = args; + await run(`kubectl delete deploy ${deployment}`); +}; diff --git a/src/secrets.js b/src/secrets.js new file mode 100644 index 0000000..31328de --- /dev/null +++ b/src/secrets.js @@ -0,0 +1,14 @@ +const {isRemove, run} = require('./utils'); + +module.exports = async function (args) { + const [action, key, value] = args; + if (action === 'ls') { + await run('kubectl get secrets'); + } + if (action === 'add') { + await run(`kubectl create secret generic ${key} --from-literal=${key}=${value}`); + } + if (isRemove(action)) { + await run(`kubectl delete secret ${key}`); + } +}; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..f9c6e69 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,76 @@ +const childProcess = require('child_process'); +const fs = require('fs'); +const util = require('util'); +const chalk = require('chalk'); + +const exec = util.promisify(childProcess.exec); +const stat = util.promisify(fs.stat); +const readFile = util.promisify(fs.readFile); + +function confirm(msg) { + const question = chalk.bold.red(`> ${msg}?`); + const options = chalk.gray('[y/N] '); + process.stdout.write(`${question} ${options} `); + return new Promise(resolve => { + function data(d) { + process.stdin.pause(); + const isYes = d.toString().trim().toLowerCase() === 'y'; + if (!isYes) { + console.log(`${chalk.grey('> ')} Aborted`); + } + process.stdin.removeListener('data', data).pause(); + resolve(isYes); + } + process.stdin.on('data', data).resume(); + }); +} + +function isRemove(str) { + return str === 'rm' || str === 'remove'; +} + +function pickOne(msg, options) { + const prefixes = options.map(option => option.charAt(0)); + const question = chalk.bold.red(`> ${msg}?`); + const optsStr = chalk.gray(`[${prefixes.join(',')}]`); + process.stdout.write(`${question} ${optsStr} `); + return new Promise(resolve => { + function data(d) { + const input = d.toString().trim().toLowerCase(); + const index = prefixes.indexOf(input); + const option = options[index]; + process.stdin.removeListener('data', data).pause(); + resolve(option); + } + process.stdin.on('data', data).resume(); + }); +} + +function run(str) { + console.log(chalk.white(`> ${str}`)); + return new Promise(resolve => { + function callback(error, ...rest) { + if (error) { + process.stderr.write(chalk.red(error)); + } + return resolve(rest); + } + const cmd = childProcess.exec(str, callback); + cmd.stderr.on('data', data => { + process.stdout.write(chalk.gray(data)); + }); + cmd.stdout.on('data', data => { + process.stdout.write(chalk.gray(data)); + }); + }); +} + +module.exports = { + confirm, + exec, + isRemove, + pickOne, + readFile, + run, + stat +}; From f29118a27166fe88119cdee0e2df70346ef6625a Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Wed, 19 Dec 2018 07:19:01 -0800 Subject: [PATCH 07/62] [README.md] update docs to discuss Kaniko --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e460321..d8d6779 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Enjoy effortless deployments with a clone of [now][now] on a cloud of your choos ### This is Magic 🔮 -No, it isn't. This CLI abstracts away the complexities of using [Kubernetes][kubernetes] to replicate the functionality provided by `now`. +No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [Traefik], [Kaniko], and a private [Docker Registry] together, replicating the functionality provided by `now`. ### Getting started @@ -49,20 +49,26 @@ snow Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. When you create your cluster via `snow`, we install [tiller][helm], which is used to install [traefik] as an [ingress object][ingress], which (1) automanages the SSL certificate lifecycle and (2) maps aliases to deployments. SSL terminiation occurs prior to requests reaching deployments. -When you create a deployment, your project must have `Dockerfile` and `now.json` files. An image is created from the Dockerfile, pushed to a Docker registry, and deployed to Kubernetes. Aliases from `now.json` will point to the deployment. If necessary, new SSL certificates will be created. +When you create a deployment, your project must have `Dockerfile` and `now.json` files. The `now.json` file must specify both a `name` and `files` array. On Kubernetes, an image is created from the Dockerfile, and pushed to a Docker registry, and deployed. Aliases from `now.json` will point to the deployment. If necessary, new SSL certificates will be created. For your domain name to be resolvable by Kubernetes, you must create a DNS `A` record, which points to the IP Address of your [traefik] ingress. The following CLI tools (installable via `snow install`) are necessary to orchestrate the entire end-to-end process, from Kubernetes cluster creation to managing your deployments: -- `virtualbox` (for creating docker images) -- `docker` (for running local registry) -- `helm` (for installing [tiller][helm] and [traefik] on your cluster) - `kubectl` (for managing deployments, secrets) -- one of [`minikube`, `gcloud`] +- `helm` (for installing [tiller][helm] and [traefik] on your cluster) +- CLI tool for your cloud provider (e.g., `gcloud`). + +If running Kubernetes locally on Minikube, you will additionally need these cli tools: + +- `docker` (for running local registry) +- `minikube` (for running Kubernetes locally) +- `virtualbox` (for creating docker images) +[docker registry]: https://github.com/helm/charts/tree/master/stable/docker-registry [now]: https://github.com/zeit/now-cli [ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ +[kaniko]: https://github.com/GoogleContainerTools/kaniko [kubernetes]: https://kubernetes.io/ [helm]: https://docs.helm.sh/ [docker]: https://www.docker.com/ From d1f365e938cd705a9716c6c0fa39506621b80b09 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Wed, 19 Dec 2018 08:44:55 -0800 Subject: [PATCH 08/62] [create] minikube: conditionally create deployment; add build-context files --- .gitignore | 1 + config/build-context/Dockerfile | 2 + config/build-context/README.md | 3 ++ config/build-context/index.html | 18 +++++++++ config/build-context/now.json | 9 +++++ config/deployment-gcp.yaml | 50 +++++++++++++++++++++++ config/deployment-minikube.yaml | 63 +++++++++++++++++++++++++++++ config/kaniko.yaml | 71 +++++++++++++++++++++++++++++++++ src/create.js | 16 +++++--- 9 files changed, 227 insertions(+), 6 deletions(-) create mode 100644 config/build-context/Dockerfile create mode 100644 config/build-context/README.md create mode 100644 config/build-context/index.html create mode 100644 config/build-context/now.json create mode 100644 config/deployment-gcp.yaml create mode 100644 config/deployment-minikube.yaml create mode 100644 config/kaniko.yaml diff --git a/.gitignore b/.gitignore index 3c3629e..7c42ab5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +config/build-context/context.tar.gz node_modules diff --git a/config/build-context/Dockerfile b/config/build-context/Dockerfile new file mode 100644 index 0000000..5ef646a --- /dev/null +++ b/config/build-context/Dockerfile @@ -0,0 +1,2 @@ +FROM nginx:alpine +COPY index.html /usr/share/nginx/html/index.html diff --git a/config/build-context/README.md b/config/build-context/README.md new file mode 100644 index 0000000..7e8b94c --- /dev/null +++ b/config/build-context/README.md @@ -0,0 +1,3 @@ +# build-context + +This directory is a minimal example of everything you need to create a deployment. diff --git a/config/build-context/index.html b/config/build-context/index.html new file mode 100644 index 0000000..5800c67 --- /dev/null +++ b/config/build-context/index.html @@ -0,0 +1,18 @@ + + + + + + + Hello World - Nginx Docker + + + +

Hello World - Deployed with Snow

+ + diff --git a/config/build-context/now.json b/config/build-context/now.json new file mode 100644 index 0000000..92e343f --- /dev/null +++ b/config/build-context/now.json @@ -0,0 +1,9 @@ +{ + "name": "my-example", + "files": [ + "index.html" + ], + "alias": [ + "my-example.minikube" + ] +} diff --git a/config/deployment-gcp.yaml b/config/deployment-gcp.yaml new file mode 100644 index 0000000..b31b328 --- /dev/null +++ b/config/deployment-gcp.yaml @@ -0,0 +1,50 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: helloweb + labels: + app: hello +spec: + selector: + matchLabels: + app: hello + tier: web + template: + metadata: + labels: + app: hello + tier: web + spec: + containers: + - name: hello-app + image: gcr.io/google-samples/hello-app:1.0 + ports: + - containerPort: 8080 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: helloweb + annotations: + kubernetes.io/ingress.global-static-ip-name: helloweb-ip + labels: + app: hello +spec: + backend: + serviceName: helloweb-backend + servicePort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: helloweb-backend + labels: + app: hello +spec: + type: NodePort + selector: + app: hello + tier: web + ports: + - port: 8080 + targetPort: 8080 diff --git a/config/deployment-minikube.yaml b/config/deployment-minikube.yaml new file mode 100644 index 0000000..a200cbf --- /dev/null +++ b/config/deployment-minikube.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: whoami-deployment +spec: + replicas: 5 + selector: + matchLabels: + app: whoami + template: + metadata: + labels: + app: whoami + spec: + containers: + - name: whoami-container + image: containous/whoami +--- +apiVersion: v1 +kind: Service +metadata: + name: whoami-clusterip-service +spec: + type: ClusterIP + ports: + - name: http + targetPort: 80 + port: 80 + selector: + app: whoami +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: whoami + # annotations: + # kubernetes.io/ingress.class: traefik +spec: + # THE Below will make a 'global default service' + # backend: + # serviceName: whoami + # servicePort: 80 + rules: + # whoami.minikube must be in your hosts file (pointing to `minikube ip`) + - host: whoami.minikube + http: + paths: + - path: / + backend: + serviceName: whoami-clusterip-service + servicePort: 80 + # whoami.com must be in your hosts file (pointing to `minikube ip`) + - host: whoami.com + http: + paths: + - path: / + backend: + serviceName: whoami-clusterip-service + servicePort: 80 + # tls: + # - hosts: + # - whoami.com + # - whoami.minikube diff --git a/config/kaniko.yaml b/config/kaniko.yaml new file mode 100644 index 0000000..16651cf --- /dev/null +++ b/config/kaniko.yaml @@ -0,0 +1,71 @@ +apiVersion: v1 +kind: Pod +metadata: + name: kaniko +spec: + initContainers: + - name: kaniko-init + image: alpine + args: + - "sh" + - "-c" + - "while true; do sleep 1; if [ -f /tmp/complete ]; then break; fi done" + volumeMounts: + - name: empty-folder + mountPath: /kaniko/build-context + - name: empty-folder + mountPath: /kaniko/.docker + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: + - "--context=dir:///kaniko/build-context" + - "--destination=172.17.0.15:5000/foobar:latest" + - "--insecure" + volumeMounts: + - name: empty-folder + mountPath: /kaniko/build-context + - name: empty-folder + mountPath: /kaniko/.docker + volumes: + - name: empty-folder + emptyDir: {} + +# apiVersion: v1 +# kind: Pod +# metadata: +# name: kaniko +# spec: +# initContainers: +# - name: kaniko-init +# image: alpine +# args: +# - "sh" +# - "-c" +# - "while true; do sleep 1; if [ -f /tmp/complete ]; then break; fi done" +# volumeMounts: +# - name: build-context +# mountPath: /kaniko/build-context +# containers: +# - name: kaniko +# image: gcr.io/kaniko-project/executor:latest +# args: +# - "--dockerfile=Dockerfile" +# - "--context=dir:///kaniko/build-context" +# - "--destination=172.17.0.15:5000/foobar:latest" +# - "--insecure" +# # - "--skip-tls-verify" +# # - "--tarPath=dir://kaniko/foo.tar" +# # - "--no-push" +# # - "--destination=mytag:latest" +# volumeMounts: +# - name: build-context +# mountPath: /kaniko/build-context +# - name: docker-config +# mountPath: /kaniko/.docker +# volumes: +# - name: docker-config +# configMap: +# name: docker-config +# - name: build-context +# emptyDir: {} diff --git a/src/create.js b/src/create.js index 9ff1b8c..9d3cb73 100644 --- a/src/create.js +++ b/src/create.js @@ -1,6 +1,6 @@ const path = require('path'); const chalk = require('chalk'); -const {exec, pickOne, run} = require('./utils'); +const {confirm, exec, pickOne, run} = require('./utils'); module.exports = async function () { const cloudProviders = ['minikube', 'gcp']; @@ -18,12 +18,16 @@ module.exports = async function () { await run('minikube addons enable ingress'); await run('helm init --wait'); - // Install traefik and kaniko + // Install traefik await run('helm install stable/traefik --name traefik --namespace kube-system --set serviceType=NodePort,dashboard.enabled=true,dashboard.domain=traefik-ui.minikube'); - // Put an example deployment on the server - // await run('kubectl run whoami --image=emilevauge/whoami --port=80 --replicas=5 --expose'); - // await run('kubectl apply -f whoami-ingress.yml'); - // await run(`kubectl apply -f ${path.resolve(__dirname, '../config/kaniko.yaml')}`); + + if (await confirm('Install an example app on Minikube')) { + const deployFile = path.resolve(__dirname, '../config/deployment-minikube.yaml'); + await run(`kubectl apply -f ${deployFile}`); + const {stdout: minikubeIP} = await exec('minikube ip'); + console.log(`Add "${minikubeIP.trim()} whoami.minikube" to your hosts file to access example app.`); + } + break; } case 'gcp': { From 7ed5fc62517786484ba90e797f31552d62eff3c4 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Wed, 19 Dec 2018 13:10:13 -0800 Subject: [PATCH 09/62] LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0bfb4ec --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Peter Mikitsh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 6ef98333d0486e66c5e6effc1fa51ff3b12b5268 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 20:54:13 -0800 Subject: [PATCH 10/62] [utils] add logging methods --- src/utils.js | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/utils.js b/src/utils.js index f9c6e69..64d970b 100644 --- a/src/utils.js +++ b/src/utils.js @@ -29,11 +29,23 @@ function isRemove(str) { return str === 'rm' || str === 'remove'; } +function logDebug(message) { + console.log(chalk.gray(message)); +} + +function logError(message) { + console.log(chalk.bold.red(message)); +} + +function logInfo(message) { + console.log(chalk.bold.white(message)); +} + function pickOne(msg, options) { - const prefixes = options.map(option => option.charAt(0)); const question = chalk.bold.red(`> ${msg}?`); - const optsStr = chalk.gray(`[${prefixes.join(',')}]`); - process.stdout.write(`${question} ${optsStr} `); + const prefixes = options.map(option => option.charAt(0)); + const prefixesStr = chalk.gray(`[${prefixes.join(',')}]`); + process.stdout.write(`${question} (${options.join(',')}) ${prefixesStr} `); return new Promise(resolve => { function data(d) { const input = d.toString().trim().toLowerCase(); @@ -47,15 +59,20 @@ function pickOne(msg, options) { } function run(str) { - console.log(chalk.white(`> ${str}`)); - return new Promise(resolve => { - function callback(error, ...rest) { + const runString = str.replace(/(\s+)/gm, ' ').trim(); + logInfo(`> ${runString}`); + return new Promise((resolve, reject) => { + function callback(error, stdout, stderr) { if (error) { process.stderr.write(chalk.red(error)); + return reject(error); } - return resolve(rest); + return resolve({ + stdout: stdout.trim(), + stderr: stderr.trim() + }); } - const cmd = childProcess.exec(str, callback); + const cmd = childProcess.exec(runString, callback); cmd.stderr.on('data', data => { process.stdout.write(chalk.gray(data)); }); @@ -69,6 +86,9 @@ module.exports = { confirm, exec, isRemove, + logDebug, + logError, + logInfo, pickOne, readFile, run, From 8d1a8bd2992a75fabb7598ea69624e9fed7d794c Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 20:54:59 -0800 Subject: [PATCH 11/62] [install] prefer 'run' utility cmd --- src/install.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/install.js b/src/install.js index 332669b..e7473a2 100644 --- a/src/install.js +++ b/src/install.js @@ -1,4 +1,4 @@ -const {confirm, exec, run} = require('./utils'); +const {confirm, run} = require('./utils'); module.exports = async function () { const dependencies = [{ @@ -42,7 +42,7 @@ module.exports = async function () { for (const {label, detectCmd, detectAdvanced, installCmd} of dependencies) { try { - const {stdout} = await exec(detectCmd); + const {stdout} = await run(detectCmd); if (detectAdvanced && detectAdvanced(stdout)) { tryInstall(label, installCmd); } From 5df520fd171da1eaa8f9191abb78086bb4afdaef Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 20:56:31 -0800 Subject: [PATCH 12/62] [login] implementation --- src/login.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/login.js diff --git a/src/login.js b/src/login.js new file mode 100644 index 0000000..08b5245 --- /dev/null +++ b/src/login.js @@ -0,0 +1,23 @@ +const {logError, pickOne, run} = require('./utils'); + +module.exports = async function () { + const cloudProviders = ['minikube', 'gcp']; + const question = 'Which cloud provider do you want to login to?'; + const provider = await pickOne(question, cloudProviders); + switch (provider) { + case 'minikube': { + await run('kubectl config use-context minikube'); + break; + } + case 'gcp': { + await run('gcloud auth login'); + const {stdout: clusterData} = await run('gcloud container clusters list --format="json"'); + const {location, name} = JSON.parse(clusterData)[0]; + await run(`gcloud container clusters get-credentials ${name} --zone "${location}"`); + break; + } + default: { + logError('No valid cloud provider selected.'); + } + } +}; From e3a178c45f13f7d8fcca55b75fea695c739a40fb Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 20:56:49 -0800 Subject: [PATCH 13/62] [logout] implementation --- src/logout.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/logout.js diff --git a/src/logout.js b/src/logout.js new file mode 100644 index 0000000..d4b1740 --- /dev/null +++ b/src/logout.js @@ -0,0 +1,26 @@ +const {logError, pickOne, run} = require('./utils'); + +module.exports = async function () { + const question = 'Which cloud provider do you want to logout of'; + const options = ['minikube', 'gcp']; + const provider = await pickOne(question, options); + switch (provider) { + case 'minikube': { + // In the case of minikube, this is a no-op. + break; + } + case 'gcp': { + const {stdout: projectId} = await run('gcloud config get-value core/project'); + const {stdout: clusterData} = await run('gcloud container clusters list --format="json"'); + const {location, name} = JSON.parse(clusterData)[0]; + const key = `gke_${projectId}_${location}_${name}`; + await run(`kubectl config unset clusters.${key}`); + await run(`kubectl config unset contexts.${key}`); + await run(`kubectl config unset users.${key}`); + break; + } + default: { + logError('No valid cloud provider selected.'); + } + } +}; From 6c5e4bcb37d72ece0b6501942ca7aef7df62c62a Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 20:57:31 -0800 Subject: [PATCH 14/62] [index] expose login, logout methods --- README.md | 4 ++-- src/index.js | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d8d6779..997866d 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ snow | :x: | `domains` | List domains | | :x: | `domains add [domain]` | Add domain | | :x: | `domains rm [domain]` | Remove domain | -| :x: | `login` | Login | -| :x: | `logout` | Logout | +| :white_check_mark: | `login` | Login | +| :white_check_mark: | `logout` | Logout | | :white_check_mark: | `ls` | List deployments | | :white_check_mark: | `rm [name]` | Remove deployment | | :white_check_mark: | `secrets ls` | List secrets | diff --git a/src/index.js b/src/index.js index 854f58a..5c63774 100755 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,15 @@ #!/usr/bin/env node -const chalk = require('chalk'); const mri = require('mri'); const create = require('./create'); const deploy = require('./deploy'); const install = require('./install'); +const login = require('./login'); +const logout = require('./logout'); const ls = require('./ls'); const remove = require('./remove'); const secrets = require('./secrets'); -const {isRemove} = require('./utils'); +const {isRemove, logError} = require('./utils'); async function main() { const {_} = mri(process.argv.slice(2)); @@ -28,6 +29,12 @@ async function main() { await install(rest); break; } + case 'login': + await login(rest); + break; + case 'logout': + await logout(rest); + break; case 'ls': { await ls(rest); break; @@ -42,7 +49,7 @@ async function main() { } default: { const errMsg = `Error: Invalid command: snow ${command} ${rest.join(' ')}`; - console.log(chalk.bold.red(errMsg)); + logError(errMsg); } } } From 5355204db730f0a0521c737a5958ab868f0cc346 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 21:00:09 -0800 Subject: [PATCH 15/62] [create] prefer 'run' util cmd; add some checks --- src/create.js | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/create.js b/src/create.js index 9d3cb73..71cbd14 100644 --- a/src/create.js +++ b/src/create.js @@ -1,39 +1,57 @@ const path = require('path'); -const chalk = require('chalk'); -const {confirm, exec, pickOne, run} = require('./utils'); +const {confirm, logError, logInfo, pickOne, run} = require('./utils'); module.exports = async function () { const cloudProviders = ['minikube', 'gcp']; - const question = 'Which cloud provider are you hosting with (minikube,gcp)'; + const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); switch (provider) { case 'minikube': { - const msgs = [ - 'Note: Minikube is for development purposes only.', - 'Starting Minikube. This may take a minute.' - ]; - const msg = chalk.bold.white(msgs.join('\n')); - console.log(msg); - await run('minikube start'); + logInfo('Note: Minikube is for development purposes only.'); + + // Start minikube if it isn't running + try { + await run('minikube status'); + } catch (error) { + logInfo('Starting Minikube. This may take a minute.'); + await run('minikube start'); + } + await run('minikube addons enable ingress'); await run('helm init --wait'); + const {stdout: minikubeIP} = await run('minikube ip'); + // Install traefik - await run('helm install stable/traefik --name traefik --namespace kube-system --set serviceType=NodePort,dashboard.enabled=true,dashboard.domain=traefik-ui.minikube'); + await run(` + helm install stable/traefik \ + --name traefik \ + --namespace kube-system \ + --set serviceType=NodePort \ + --set dashboard.enabled=true \ + --set dashboard.domain=traefik-ui.minikube + `); + const traefikHost = `${minikubeIP} traefik-ui.minikube`; + logInfo(`Add "${traefikHost}" to your hosts file to access traefik's dashboard.`); + + // Install docker registry + await run('helm install stable/docker-registry'); if (await confirm('Install an example app on Minikube')) { const deployFile = path.resolve(__dirname, '../config/deployment-minikube.yaml'); await run(`kubectl apply -f ${deployFile}`); - const {stdout: minikubeIP} = await exec('minikube ip'); - console.log(`Add "${minikubeIP.trim()} whoami.minikube" to your hosts file to access example app.`); + const whoAmIHost = `${minikubeIP} whoami.minikube`; + logInfo(`Add "${whoAmIHost}" to your hosts file to access example app.`); } + const completeMsg = 'Creation complete. It may take a few minutes for services to become available.'; + logInfo(completeMsg); break; } case 'gcp': { // Check if we need to authenticate. try { - const {stdout} = await exec('gcloud auth list'); + const {stdout} = await run('gcloud auth list'); const isAuthenticated = stdout.indexOf('*') > -1; if (!isAuthenticated) { await run('gcloud auth login'); @@ -42,8 +60,7 @@ module.exports = async function () { await run('gcloud auth login'); } - const {stdout} = await exec('gcloud config get-value project'); - const projectId = stdout.trim(); + const {stdout: projectId} = await run('gcloud config get-value project'); await run('gcloud services enable container.googleapis.com'); const createClusterCmd = ` gcloud beta container \ @@ -72,7 +89,7 @@ module.exports = async function () { break; } default: { - console.log(chalk.bold.red('No valid cloud provider selected.')); + logError('No valid cloud provider selected.'); } } }; From 79a59cc3c625b245368dd615c71b01526e5209e0 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 21:05:34 -0800 Subject: [PATCH 16/62] [ls] fix base case (no deployment name specified) --- src/ls.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ls.js b/src/ls.js index 8806050..fd801cc 100644 --- a/src/ls.js +++ b/src/ls.js @@ -2,5 +2,8 @@ const {run} = require('./utils'); module.exports = async function (args) { const [deployment] = args; + if (!deployment) { + return run('kubectl get deployments'); + } await run(`kubectl get deployments ${deployment}`); }; From 6e35e7c214fdc4cd7add3426fb2864fa8ab4d90d Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 21:55:19 -0800 Subject: [PATCH 17/62] [scale] implementation --- README.md | 7 +++++++ src/index.js | 5 +++++ src/scale.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 src/scale.js diff --git a/README.md b/README.md index 997866d..6782c6e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ Enjoy effortless deployments with a clone of [now][now] on a cloud of your choosing. +### Features + - ⚡️ Deploy docker images via `snow` (or `snow deploy`) + - 🔒 Auto-configured SSL + - 🔃 Auto-scaling + ### This is Magic 🔮 No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [Traefik], [Kaniko], and a private [Docker Registry] together, replicating the functionality provided by `now`. @@ -41,6 +46,8 @@ snow | :white_check_mark: | `logout` | Logout | | :white_check_mark: | `ls` | List deployments | | :white_check_mark: | `rm [name]` | Remove deployment | +| :white_check_mark: | `scale [name] [min]` | Scale deployment | +| :white_check_mark: | `scale [name] [min] [max]` | Scale deployment | | :white_check_mark: | `secrets ls` | List secrets | | :white_check_mark: | `secrets add [key] [value]` | Create secret | | :white_check_mark: | `secrets rm [key]` | Remove secret | diff --git a/src/index.js b/src/index.js index 5c63774..641581b 100755 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ const login = require('./login'); const logout = require('./logout'); const ls = require('./ls'); const remove = require('./remove'); +const scale = require('./scale'); const secrets = require('./secrets'); const {isRemove, logError} = require('./utils'); @@ -43,6 +44,10 @@ async function main() { await remove(rest); break; } + case 'scale': { + await scale(rest); + break; + } case 'secrets': { await secrets(rest); break; diff --git a/src/scale.js b/src/scale.js new file mode 100644 index 0000000..cf797ea --- /dev/null +++ b/src/scale.js @@ -0,0 +1,31 @@ +const {logError, run} = require('./utils'); + +module.exports = async function (args) { + const [name, min, max] = args; + if (!name) { + return logError('name (required): snow scale [name]'); + } + if (!min) { + return logError('min (required): snow scale [name] [min]'); + } + if (isNaN(Number(min))) { + return logError('min (typecheck: must be numberic): snow scale [name] [min]'); + } + + if (max && isNaN(Number(max))) { + return logError('max (typecheck: must be numberic): snow scale [name] [min] [max]'); + } + + // If CLI called without 'max' supplied, default to 'min'. + const actualMax = max ? max : min; + + // Check for existing Horizontal Pod Autoscaler (HPA) + try { + await run(`kubectl get hpa ${name}`); + // HPA exists. Patch it. + await run(`kubectl patch hpa ${name} --patch '{"spec":{"minReplicas":${min},"maxReplicas":${actualMax}}}'`); + } catch (error) { + // No HPA. Create one. + await run(`kubectl autoscale deployment/${name} --min=${min} --max=${actualMax}`); + } +}; From c954db69f45fd704a38734f664bb74836f7e9b1e Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 28 Dec 2018 22:38:12 -0800 Subject: [PATCH 18/62] [domains]: list functionality --- README.md | 2 +- src/domains.js | 10 ++++++++++ src/index.js | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/domains.js diff --git a/README.md b/README.md index 6782c6e..9f09b76 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ snow | :x: | \ | Create deployment | | :x: | `alias` | Alias deployment | | :x: | `deploy` | Deploy | -| :x: | `domains` | List domains | +| :white_check_mark: | `domains` | List domains | | :x: | `domains add [domain]` | Add domain | | :x: | `domains rm [domain]` | Remove domain | | :white_check_mark: | `login` | Login | diff --git a/src/domains.js b/src/domains.js new file mode 100644 index 0000000..5019b76 --- /dev/null +++ b/src/domains.js @@ -0,0 +1,10 @@ +const {run} = require('./utils'); + +module.exports = async function (args) { + const [subcommand] = args; + + if (!subcommand || subcommand === 'ls') { + const path = '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; + await run(`kubectl get ingress -o jsonpath='${path}'`); + } +}; diff --git a/src/index.js b/src/index.js index 641581b..46dcac2 100755 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,7 @@ const mri = require('mri'); const create = require('./create'); const deploy = require('./deploy'); +const domains = require('./domains'); const install = require('./install'); const login = require('./login'); const logout = require('./logout'); @@ -26,6 +27,10 @@ async function main() { await deploy(rest); break; } + case 'domains': { + await domains(rest); + break; + } case 'install': { await install(rest); break; From 78963f9d1bbdceac3cd9c3cb597ddc6f2f482657 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sat, 29 Dec 2018 14:50:14 -0800 Subject: [PATCH 19/62] [utils] run: add new fn arg --- src/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.js b/src/utils.js index 64d970b..2bb7482 100644 --- a/src/utils.js +++ b/src/utils.js @@ -58,7 +58,7 @@ function pickOne(msg, options) { }); } -function run(str) { +function run(str, opts) { const runString = str.replace(/(\s+)/gm, ' ').trim(); logInfo(`> ${runString}`); return new Promise((resolve, reject) => { @@ -72,7 +72,7 @@ function run(str) { stderr: stderr.trim() }); } - const cmd = childProcess.exec(runString, callback); + const cmd = childProcess.exec(str, opts, callback); cmd.stderr.on('data', data => { process.stdout.write(chalk.gray(data)); }); From 9b8d939a157d44dc636d87bc611ab282b2652b13 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sat, 29 Dec 2018 14:51:48 -0800 Subject: [PATCH 20/62] [create]: init helm/tiller with TLS --- src/create.js | 124 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 1 deletion(-) diff --git a/src/create.js b/src/create.js index 71cbd14..8cff413 100644 --- a/src/create.js +++ b/src/create.js @@ -62,6 +62,14 @@ module.exports = async function () { const {stdout: projectId} = await run('gcloud config get-value project'); await run('gcloud services enable container.googleapis.com'); + + // Check if we have an existing cluster + let clusterExists = false; + const {stdout: clusterData} = await run('gcloud container clusters list'); + if (clusterData.indexOf('snow-cluster') > -1) { + clusterExists = true; + } + const createClusterCmd = ` gcloud beta container \ clusters create "snow-cluster" \ @@ -85,7 +93,121 @@ module.exports = async function () { --enable-autorepair \ --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/trace.append" \ `; - await run(createClusterCmd); + + if (!clusterExists) { + await run(createClusterCmd); + } + + // Install helm with TLS. + // https://medium.com/google-cloud/install-secure-helm-in-gke-254d520061f7 + + const BYTES = 2048; + + // Create Certificate Authority + await run(`openssl genrsa -out $(helm home)/ca.key.pem ${BYTES}`); + const config = ` + [req]\\n + req_extensions=v3_ca\\n + distinguished_name=req_distinguished_name\\n + [req_distinguished_name]\\n + [ v3_ca ]\\n + basicConstraints=critical,CA:TRUE\\n + subjectKeyIdentifier=hash\\n + authorityKeyIdentifier=keyid:always,issuer:always`; + await run(` + openssl req \\ + -config <(printf '${config}') \\ + -key $(helm home)/ca.key.pem \\ + -new \\ + -x509 \\ + -days 7300 \\ + -sha256 \\ + -out $(helm home)/ca.cert.pem \\ + -extensions v3_ca \\ + -subj "/C=US"`, {shell: '/bin/bash'}); + + // Create credentials for tiller (server) + await run(`openssl genrsa -out $(helm home)/tiller.key.pem ${BYTES}`); + await run(` + openssl req \ + -new \ + -sha256 \ + -key $(helm home)/tiller.key.pem \ + -out $(helm home)/tiller.csr.pem \ + -subj "/C=US/O=Snow/CN=tiller-server"`, + {shell: '/bin/bash'}); + const tillerConfig = ` + [SAN]\\n + subjectAltName=IP:127.0.0.1`; + await run(` + openssl x509 -req -days 365 \ + -CA $(helm home)/ca.cert.pem \ + -CAkey $(helm home)/ca.key.pem \ + -CAcreateserial \ + -in $(helm home)/tiller.csr.pem \ + -out $(helm home)/tiller.cert.pem \ + -extfile <(printf '${tillerConfig}') \ + -extensions SAN`, + {shell: '/bin/bash'}); + + // Create credentials for helm (client) + await run(`openssl genrsa -out $(helm home)/helm.key.pem ${BYTES}`); + await run(` + openssl req -new -sha256 \ + -key $(helm home)/helm.key.pem \ + -out $(helm home)/helm.csr.pem \ + -subj "/C=US" + `); + await run(` + openssl x509 -req -days 365 \ + -CA $(helm home)/ca.cert.pem \ + -CAkey $(helm home)/ca.key.pem \ + -CAcreateserial \ + -in $(helm home)/helm.csr.pem \ + -out $(helm home)/helm.cert.pem + `); + + // Create service account and clusterrolebinding + await run(`kubectl create serviceaccount \ + --namespace kube-system tiller + `); + await run(`kubectl create clusterrolebinding \ + tiller-cluster-rule \ + --clusterrole=cluster-admin \ + --serviceaccount=kube-system:tiller + `); + + // Install Helm w/ 'tiller' service account + await run(` + helm init \ + --debug \ + --tiller-tls \ + --tiller-tls-cert $(helm home)/tiller.cert.pem \ + --tiller-tls-key $(helm home)/tiller.key.pem \ + --tiller-tls-verify \ + --tls-ca-cert $(helm home)/ca.cert.pem \ + --service-account tiller \ + --wait + `); + + // Verify helm installation + await run(` + helm ls --tls \ + --tls-ca-cert $(helm home)/ca.cert.pem \ + --tls-cert $(helm home)/helm.cert.pem \ + --tls-key $(helm home)/helm.key.pem + `); + + /** + * + * To remove helm: + * + * helm reset + * --tls + * --tls-ca-cert $(helm home)/ca.cert.pem + * --tls-cert $(helm home)/helm.cert.pem + * --tls-key $(helm home)/helm.key.pem + */ break; } default: { From e7c5c997866a60472697ad8ed5f87bf4627d532c Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 31 Dec 2018 22:00:27 -0800 Subject: [PATCH 21/62] [create] install traefik using helm --- src/create.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/create.js b/src/create.js index 8cff413..270eedd 100644 --- a/src/create.js +++ b/src/create.js @@ -208,6 +208,20 @@ module.exports = async function () { * --tls-cert $(helm home)/helm.cert.pem * --tls-key $(helm home)/helm.key.pem */ + + // install traefik + await run(` + helm install stable/traefik \ + --tls \ + --tls-ca-cert $(helm home)/ca.cert.pem \ + --tls-cert $(helm home)/helm.cert.pem \ + --tls-key $(helm home)/helm.key.pem \ + --name traefik \ + --namespace kube-system \ + --set kubernetes.ingressClass=traefik \ + --set rbac.enabled=true + `); + break; } default: { From 275e832b6b07530f8dbee418b324004205ff133f Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Tue, 1 Jan 2019 17:07:57 -0800 Subject: [PATCH 22/62] [create] traefik with ssl --- src/create.js | 16 ++++++++++++++-- src/utils.js | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/create.js b/src/create.js index 270eedd..eabdfec 100644 --- a/src/create.js +++ b/src/create.js @@ -1,5 +1,5 @@ const path = require('path'); -const {confirm, logError, logInfo, pickOne, run} = require('./utils'); +const {askForInput, confirm, logError, logInfo, pickOne, run} = require('./utils'); module.exports = async function () { const cloudProviders = ['minikube', 'gcp']; @@ -210,6 +210,11 @@ module.exports = async function () { */ // install traefik + let email = await askForInput('Provide an email address for Let\'s Encrypt'); + while (!await confirm(`Confirm email: "${email}"`)) { + email = await askForInput('Provide an email address for Let\'s Encrypt'); + } + await run(` helm install stable/traefik \ --tls \ @@ -219,7 +224,14 @@ module.exports = async function () { --name traefik \ --namespace kube-system \ --set kubernetes.ingressClass=traefik \ - --set rbac.enabled=true + --set rbac.enabled=true \ + --set ssl.enabled=true \ + --set ssl.enforced=true \ + --set ssl.permanentRedirect=true \ + --set acme.enabled=true \ + --set acme.challengeType=http-01 \ + --set acme.email=${email} \ + --set acme.staging=false `); break; diff --git a/src/utils.js b/src/utils.js index 2bb7482..e0a0f24 100644 --- a/src/utils.js +++ b/src/utils.js @@ -7,6 +7,19 @@ const exec = util.promisify(childProcess.exec); const stat = util.promisify(fs.stat); const readFile = util.promisify(fs.readFile); +function askForInput(msg) { + const question = chalk.bold.red(`> ${msg}: `); + process.stdout.write(question); + return new Promise(resolve => { + function data(d) { + const input = d.toString().trim(); + process.stdin.removeListener('data', data).pause(); + resolve(input); + } + process.stdin.on('data', data).resume(); + }); +} + function confirm(msg) { const question = chalk.bold.red(`> ${msg}?`); const options = chalk.gray('[y/N] '); @@ -83,6 +96,7 @@ function run(str, opts) { } module.exports = { + askForInput, confirm, exec, isRemove, From 64efa3c74b875ed1d6d5e4e9ab137d6c3dbceed7 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Tue, 1 Jan 2019 22:29:59 -0800 Subject: [PATCH 23/62] [ip] cmd implementation --- src/index.js | 5 +++++ src/ip.js | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/ip.js diff --git a/src/index.js b/src/index.js index 46dcac2..2df8d57 100755 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ const create = require('./create'); const deploy = require('./deploy'); const domains = require('./domains'); const install = require('./install'); +const ip = require('./ip'); const login = require('./login'); const logout = require('./logout'); const ls = require('./ls'); @@ -35,6 +36,10 @@ async function main() { await install(rest); break; } + case 'ip': { + await ip(rest); + break; + } case 'login': await login(rest); break; diff --git a/src/ip.js b/src/ip.js new file mode 100644 index 0000000..9abda47 --- /dev/null +++ b/src/ip.js @@ -0,0 +1,10 @@ +const {run} = require('./utils'); + +module.exports = async function () { + const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; + await run(` + kubectl get services/nginx-ingress-controller \ + --namespace=kube-system \ + -o jsonpath='${path}' + `); +}; From 64903822c877fed3688872974ecf1e05566d0e48 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Tue, 1 Jan 2019 22:31:33 -0800 Subject: [PATCH 24/62] [create] swap traefik with nginx-ingress and cert-manager --- src/create.js | 60 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/src/create.js b/src/create.js index eabdfec..2fc1b40 100644 --- a/src/create.js +++ b/src/create.js @@ -209,31 +209,59 @@ module.exports = async function () { * --tls-key $(helm home)/helm.key.pem */ - // install traefik - let email = await askForInput('Provide an email address for Let\'s Encrypt'); - while (!await confirm(`Confirm email: "${email}"`)) { - email = await askForInput('Provide an email address for Let\'s Encrypt'); - } + // install nginx ingress + await run(` + helm install stable/nginx-ingress \ + --tls \ + --tls-ca-cert $(helm home)/ca.cert.pem \ + --tls-cert $(helm home)/helm.cert.pem \ + --tls-key $(helm home)/helm.key.pem \ + --namespace kube-system \ + --name nginx-ingress \ + --set controller.ingressClass=nginx \ + --set rbac.create=true + `); + // Install cert-manager await run(` - helm install stable/traefik \ + helm install stable/cert-manager \ --tls \ --tls-ca-cert $(helm home)/ca.cert.pem \ --tls-cert $(helm home)/helm.cert.pem \ --tls-key $(helm home)/helm.key.pem \ - --name traefik \ --namespace kube-system \ - --set kubernetes.ingressClass=traefik \ - --set rbac.enabled=true \ - --set ssl.enabled=true \ - --set ssl.enforced=true \ - --set ssl.permanentRedirect=true \ - --set acme.enabled=true \ - --set acme.challengeType=http-01 \ - --set acme.email=${email} \ - --set acme.staging=false + --name cert-manager \ + --set ingressShim.defaultIssuerName=letsencrypt-prod \ + --set ingressShim.defaultIssuerKind=ClusterIssuer `); + let email = await askForInput('Provide an email address for Let\'s Encrypt'); + while (!await confirm(`Confirm email: "${email}"`)) { + email = await askForInput('Provide an email address for Let\'s Encrypt'); + } + + // Create cluster issuer + await run(` + cat < Date: Tue, 1 Jan 2019 22:34:14 -0800 Subject: [PATCH 25/62] [README] updates --- README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9f09b76..579d0cc 100644 --- a/README.md +++ b/README.md @@ -13,23 +13,23 @@ Enjoy effortless deployments with a clone of [now][now] on a cloud of your choos ### This is Magic 🔮 -No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [Traefik], [Kaniko], and a private [Docker Registry] together, replicating the functionality provided by `now`. +No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [cert-manager], [Kaniko], and a private [Docker Registry] together, replicating the functionality provided by `now`. ### Getting started ``` -npm i -g @snowjs/cli +> npm i -g @snowjs/cli # Install CLI tools -snow install +> snow install # Create your kubernetes cluster (GCP) -snow create +> snow create # Create a DNS 'A' record (e.g., myapp.com A 1.2.3.4) -# Deploy your app -snow +# Deploy +> snow ``` ### Supported commands @@ -52,18 +52,76 @@ snow | :white_check_mark: | `secrets add [key] [value]` | Create secret | | :white_check_mark: | `secrets rm [key]` | Remove secret | +### New commands + +| Command | Description | +|----------|---------------------------------| +| `create` | Run once to create cluster | +| `ip` | Get IP Address of Load Balancer | + ### Tell me more -Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. When you create your cluster via `snow`, we install [tiller][helm], which is used to install [traefik] as an [ingress object][ingress], which (1) automanages the SSL certificate lifecycle and (2) maps aliases to deployments. SSL terminiation occurs prior to requests reaching deployments. +The essential CLI commands to understand are `snow create` and `snow deploy`. + +``` +snow create +``` + +Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. Here's what happens when you run `snow create`: + + - You are authenticated to the cloud provider of your choosing. + - A Kubernetes cluster is created. + - [tiller][helm] is installed, which is used to install: + - [cert-manager] + - Will automatically watch your deployments and request new certificates for hostnames. + - Request new certificates when they're closing to expiring and seamlessly update in production. + - [ingress-nginx] + - Used for mapping hostnames to deployments. + - All HTTP traffic is permanently redirected (HTTP 308) to HTTPS. + - SSL terminiation occurs prior to requests reaching deployments. + +``` +snow deploy +``` + +Also aliased as `snow`. Your current directory must have both `Dockerfile` and `now.json` files. + +Your now.json file **must** minimally specify `name` and `files`. The `alias` property is optional. + +Example `now.json`: + +``` +{ + "name": "myapp", + "alias": [ + "api.myapp.com", + "myapp.com" + ], + "files": [ + "server.js" + ] +} +``` + +The deployment process: + + - The files listed in `now.json` plus `Dockerfile` (collectively referred to as the "build context") are assembled into a tar archive. + - [Kaniko] creates a Docker image from the build context, and pushes it to the private Docker registry in your Kubernetes cluster. + - A Kubernetes `deployment` resource is created for your image. + - A Kubernetes `service` resource exposes your deployment. + - A Kubernetes `ingress` resource maps hostnames (listed as `alias` array in now.json) to the service. + - [cert-manager] continually inspects ingresses, so if a deployment needs SSL certificates, they will be generated upon deployment. -When you create a deployment, your project must have `Dockerfile` and `now.json` files. The `now.json` file must specify both a `name` and `files` array. On Kubernetes, an image is created from the Dockerfile, and pushed to a Docker registry, and deployed. Aliases from `now.json` will point to the deployment. If necessary, new SSL certificates will be created. +For your domain name to be resolvable by Kubernetes, you **must**: + - create a DNS `A` record, which points to the IP Address of your load balancer (which can be found via `snow ip`). + - Alias the domain name to a deployment. -For your domain name to be resolvable by Kubernetes, you must create a DNS `A` record, which points to the IP Address of your [traefik] ingress. +### Dependencies The following CLI tools (installable via `snow install`) are necessary to orchestrate the entire end-to-end process, from Kubernetes cluster creation to managing your deployments: - `kubectl` (for managing deployments, secrets) -- `helm` (for installing [tiller][helm] and [traefik] on your cluster) +- `helm` (for installing [tiller], [cert-manager], and [ingress-nginx] on your cluster) - CLI tool for your cloud provider (e.g., `gcloud`). If running Kubernetes locally on Minikube, you will additionally need these cli tools: @@ -72,13 +130,14 @@ If running Kubernetes locally on Minikube, you will additionally need these cli - `minikube` (for running Kubernetes locally) - `virtualbox` (for creating docker images) +[cert-manager]: https://github.com/jetstack/cert-manager [docker registry]: https://github.com/helm/charts/tree/master/stable/docker-registry [now]: https://github.com/zeit/now-cli [ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ +[ingress-nginx]: https://github.com/kubernetes/ingress-nginx [kaniko]: https://github.com/GoogleContainerTools/kaniko [kubernetes]: https://kubernetes.io/ [helm]: https://docs.helm.sh/ [docker]: https://www.docker.com/ [letsencrypt]: https://letsencrypt.org/ [minikube]: https://kubernetes.io/docs/setup/minikube/ -[traefik]: https://traefik.io/ \ No newline at end of file From e819654037ca8ee65aceba1311aeb7e43e295fd8 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Wed, 2 Jan 2019 10:11:29 -0800 Subject: [PATCH 26/62] add prettier --- package.json | 22 +- src/create.js | 66 ++++-- src/deploy.js | 15 +- src/domains.js | 7 +- src/index.js | 8 +- src/install.js | 78 ++++--- src/ip.js | 4 +- src/login.js | 14 +- src/logout.js | 14 +- src/ls.js | 4 +- src/remove.js | 4 +- src/scale.js | 20 +- src/secrets.js | 8 +- src/utils.js | 11 +- yarn.lock | 562 +++++++++++++++++++++++++++++++++++++++++++++++-- 15 files changed, 730 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index 8f42c9c..8933eb3 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,32 @@ "mri": "1.1.1" }, "devDependencies": { + "husky": "1.3.1", + "lint-staged": "8.1.0", + "prettier": "1.15.3", "xo": "0.23.0" }, "xo": { "rules": { "no-await-in-loop": 0 }, - "space": true + "space": true, + "extends": [ + "prettier" + ] + }, + "prettier": { + "singleQuote": true + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,json,css,md}": [ + "prettier --write", + "git add" + ] } } diff --git a/src/create.js b/src/create.js index 2fc1b40..e0d1e2d 100644 --- a/src/create.js +++ b/src/create.js @@ -1,7 +1,14 @@ const path = require('path'); -const {askForInput, confirm, logError, logInfo, pickOne, run} = require('./utils'); +const { + askForInput, + confirm, + logError, + logInfo, + pickOne, + run +} = require('./utils'); -module.exports = async function () { +module.exports = async function() { const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); @@ -20,7 +27,7 @@ module.exports = async function () { await run('minikube addons enable ingress'); await run('helm init --wait'); - const {stdout: minikubeIP} = await run('minikube ip'); + const { stdout: minikubeIP } = await run('minikube ip'); // Install traefik await run(` @@ -32,26 +39,34 @@ module.exports = async function () { --set dashboard.domain=traefik-ui.minikube `); const traefikHost = `${minikubeIP} traefik-ui.minikube`; - logInfo(`Add "${traefikHost}" to your hosts file to access traefik's dashboard.`); + logInfo( + `Add "${traefikHost}" to your hosts file to access traefik's dashboard.` + ); // Install docker registry await run('helm install stable/docker-registry'); if (await confirm('Install an example app on Minikube')) { - const deployFile = path.resolve(__dirname, '../config/deployment-minikube.yaml'); + const deployFile = path.resolve( + __dirname, + '../config/deployment-minikube.yaml' + ); await run(`kubectl apply -f ${deployFile}`); const whoAmIHost = `${minikubeIP} whoami.minikube`; - logInfo(`Add "${whoAmIHost}" to your hosts file to access example app.`); + logInfo( + `Add "${whoAmIHost}" to your hosts file to access example app.` + ); } - const completeMsg = 'Creation complete. It may take a few minutes for services to become available.'; + const completeMsg = + 'Creation complete. It may take a few minutes for services to become available.'; logInfo(completeMsg); break; } case 'gcp': { // Check if we need to authenticate. try { - const {stdout} = await run('gcloud auth list'); + const { stdout } = await run('gcloud auth list'); const isAuthenticated = stdout.indexOf('*') > -1; if (!isAuthenticated) { await run('gcloud auth login'); @@ -60,12 +75,16 @@ module.exports = async function () { await run('gcloud auth login'); } - const {stdout: projectId} = await run('gcloud config get-value project'); + const { stdout: projectId } = await run( + 'gcloud config get-value project' + ); await run('gcloud services enable container.googleapis.com'); // Check if we have an existing cluster let clusterExists = false; - const {stdout: clusterData} = await run('gcloud container clusters list'); + const { stdout: clusterData } = await run( + 'gcloud container clusters list' + ); if (clusterData.indexOf('snow-cluster') > -1) { clusterExists = true; } @@ -114,7 +133,8 @@ module.exports = async function () { basicConstraints=critical,CA:TRUE\\n subjectKeyIdentifier=hash\\n authorityKeyIdentifier=keyid:always,issuer:always`; - await run(` + await run( + ` openssl req \\ -config <(printf '${config}') \\ -key $(helm home)/ca.key.pem \\ @@ -124,22 +144,27 @@ module.exports = async function () { -sha256 \\ -out $(helm home)/ca.cert.pem \\ -extensions v3_ca \\ - -subj "/C=US"`, {shell: '/bin/bash'}); + -subj "/C=US"`, + { shell: '/bin/bash' } + ); // Create credentials for tiller (server) await run(`openssl genrsa -out $(helm home)/tiller.key.pem ${BYTES}`); - await run(` + await run( + ` openssl req \ -new \ -sha256 \ -key $(helm home)/tiller.key.pem \ -out $(helm home)/tiller.csr.pem \ -subj "/C=US/O=Snow/CN=tiller-server"`, - {shell: '/bin/bash'}); + { shell: '/bin/bash' } + ); const tillerConfig = ` [SAN]\\n subjectAltName=IP:127.0.0.1`; - await run(` + await run( + ` openssl x509 -req -days 365 \ -CA $(helm home)/ca.cert.pem \ -CAkey $(helm home)/ca.key.pem \ @@ -148,7 +173,8 @@ module.exports = async function () { -out $(helm home)/tiller.cert.pem \ -extfile <(printf '${tillerConfig}') \ -extensions SAN`, - {shell: '/bin/bash'}); + { shell: '/bin/bash' } + ); // Create credentials for helm (client) await run(`openssl genrsa -out $(helm home)/helm.key.pem ${BYTES}`); @@ -235,9 +261,11 @@ module.exports = async function () { --set ingressShim.defaultIssuerKind=ClusterIssuer `); - let email = await askForInput('Provide an email address for Let\'s Encrypt'); - while (!await confirm(`Confirm email: "${email}"`)) { - email = await askForInput('Provide an email address for Let\'s Encrypt'); + let email = await askForInput( + "Provide an email address for Let's Encrypt" + ); + while (!(await confirm(`Confirm email: "${email}"`))) { + email = await askForInput("Provide an email address for Let's Encrypt"); } // Create cluster issuer diff --git a/src/deploy.js b/src/deploy.js index f461ba9..0e9c5aa 100644 --- a/src/deploy.js +++ b/src/deploy.js @@ -1,9 +1,8 @@ - const path = require('path'); const chalk = require('chalk'); -const {exec, readFile, stat} = require('./utils'); +const { exec, readFile, stat } = require('./utils'); -module.exports = async function () { +module.exports = async function() { // First: Verify we have a Dockerfile. const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); try { @@ -26,7 +25,7 @@ module.exports = async function () { } // Third: Build and tag the image. - const {name} = nowConfig; + const { name } = nowConfig; if (!name) { console.log(chalk.red('Specify a "name" in now.json')); return; @@ -42,7 +41,9 @@ module.exports = async function () { // Fourth: Start a local Docker registry, if necessary. let registryRunning = true; try { - const {stdout} = await exec('docker ps --format "{{.Names}}" -f "name=registry"'); + const { stdout } = await exec( + 'docker ps --format "{{.Names}}" -f "name=registry"' + ); if (!stdout) { registryRunning = false; } @@ -52,7 +53,9 @@ module.exports = async function () { } if (!registryRunning) { try { - await exec('docker run -d -p 5000:5000 --restart=always --name registry registry:2'); + await exec( + 'docker run -d -p 5000:5000 --restart=always --name registry registry:2' + ); } catch (error) { console.log(`Could not start local Docker registry.\n${error.message}`); } diff --git a/src/domains.js b/src/domains.js index 5019b76..a5c442e 100644 --- a/src/domains.js +++ b/src/domains.js @@ -1,10 +1,11 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [subcommand] = args; if (!subcommand || subcommand === 'ls') { - const path = '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; + const path = + '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; await run(`kubectl get ingress -o jsonpath='${path}'`); } }; diff --git a/src/index.js b/src/index.js index 2df8d57..09afe30 100755 --- a/src/index.js +++ b/src/index.js @@ -12,10 +12,10 @@ const ls = require('./ls'); const remove = require('./remove'); const scale = require('./scale'); const secrets = require('./secrets'); -const {isRemove, logError} = require('./utils'); +const { isRemove, logError } = require('./utils'); async function main() { - const {_} = mri(process.argv.slice(2)); + const { _ } = mri(process.argv.slice(2)); const [command, ...rest] = _; switch (command) { @@ -63,7 +63,9 @@ async function main() { break; } default: { - const errMsg = `Error: Invalid command: snow ${command} ${rest.join(' ')}`; + const errMsg = `Error: Invalid command: snow ${command} ${rest.join( + ' ' + )}`; logError(errMsg); } } diff --git a/src/install.js b/src/install.js index e7473a2..dab1335 100644 --- a/src/install.js +++ b/src/install.js @@ -1,38 +1,46 @@ -const {confirm, run} = require('./utils'); +const { confirm, run } = require('./utils'); -module.exports = async function () { - const dependencies = [{ - label: 'Virtualbox', - detectCmd: 'which virtualbox', - installCmd: 'brew cask install virtualbox' - }, { - label: 'Docker', - detectCmd: 'which docker', - installCmd: 'brew cask install docker' - }, { - label: 'Kubernetes', - detectCmd: 'which kubectl', - installCmd: 'brew install kubernetes-cli' - }, { - label: 'Helm', - detectCmd: 'which helm', - installCmd: 'brew install kubernetes-helm' - }, { - label: 'Minikube', - detectCmd: 'which minikube', - installCmd: 'brew cask install minikube' - }, { - label: 'Google Cloud SDK (gcloud)', - detectCmd: 'which gcloud', - installCmd: 'brew cask install google-cloud-sdk' - }, { - label: 'Google Cloud SDK (gcloud) Beta Commands', - detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', - installCmd: 'gcloud components install beta --quiet', - detectAdvanced: output => { - return output.indexOf('Not Installed | gcloud Beta Commands') > -1; +module.exports = async function() { + const dependencies = [ + { + label: 'Virtualbox', + detectCmd: 'which virtualbox', + installCmd: 'brew cask install virtualbox' + }, + { + label: 'Docker', + detectCmd: 'which docker', + installCmd: 'brew cask install docker' + }, + { + label: 'Kubernetes', + detectCmd: 'which kubectl', + installCmd: 'brew install kubernetes-cli' + }, + { + label: 'Helm', + detectCmd: 'which helm', + installCmd: 'brew install kubernetes-helm' + }, + { + label: 'Minikube', + detectCmd: 'which minikube', + installCmd: 'brew cask install minikube' + }, + { + label: 'Google Cloud SDK (gcloud)', + detectCmd: 'which gcloud', + installCmd: 'brew cask install google-cloud-sdk' + }, + { + label: 'Google Cloud SDK (gcloud) Beta Commands', + detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', + installCmd: 'gcloud components install beta --quiet', + detectAdvanced: output => { + return output.indexOf('Not Installed | gcloud Beta Commands') > -1; + } } - }]; + ]; async function tryInstall(label, installCmd) { if (await confirm(`Install ${label}`)) { @@ -40,9 +48,9 @@ module.exports = async function () { } } - for (const {label, detectCmd, detectAdvanced, installCmd} of dependencies) { + for (const { label, detectCmd, detectAdvanced, installCmd } of dependencies) { try { - const {stdout} = await run(detectCmd); + const { stdout } = await run(detectCmd); if (detectAdvanced && detectAdvanced(stdout)) { tryInstall(label, installCmd); } diff --git a/src/ip.js b/src/ip.js index 9abda47..90c3373 100644 --- a/src/ip.js +++ b/src/ip.js @@ -1,6 +1,6 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function () { +module.exports = async function() { const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; await run(` kubectl get services/nginx-ingress-controller \ diff --git a/src/login.js b/src/login.js index 08b5245..ba0f509 100644 --- a/src/login.js +++ b/src/login.js @@ -1,6 +1,6 @@ -const {logError, pickOne, run} = require('./utils'); +const { logError, pickOne, run } = require('./utils'); -module.exports = async function () { +module.exports = async function() { const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider do you want to login to?'; const provider = await pickOne(question, cloudProviders); @@ -11,9 +11,13 @@ module.exports = async function () { } case 'gcp': { await run('gcloud auth login'); - const {stdout: clusterData} = await run('gcloud container clusters list --format="json"'); - const {location, name} = JSON.parse(clusterData)[0]; - await run(`gcloud container clusters get-credentials ${name} --zone "${location}"`); + const { stdout: clusterData } = await run( + 'gcloud container clusters list --format="json"' + ); + const { location, name } = JSON.parse(clusterData)[0]; + await run( + `gcloud container clusters get-credentials ${name} --zone "${location}"` + ); break; } default: { diff --git a/src/logout.js b/src/logout.js index d4b1740..7c8dd38 100644 --- a/src/logout.js +++ b/src/logout.js @@ -1,6 +1,6 @@ -const {logError, pickOne, run} = require('./utils'); +const { logError, pickOne, run } = require('./utils'); -module.exports = async function () { +module.exports = async function() { const question = 'Which cloud provider do you want to logout of'; const options = ['minikube', 'gcp']; const provider = await pickOne(question, options); @@ -10,9 +10,13 @@ module.exports = async function () { break; } case 'gcp': { - const {stdout: projectId} = await run('gcloud config get-value core/project'); - const {stdout: clusterData} = await run('gcloud container clusters list --format="json"'); - const {location, name} = JSON.parse(clusterData)[0]; + const { stdout: projectId } = await run( + 'gcloud config get-value core/project' + ); + const { stdout: clusterData } = await run( + 'gcloud container clusters list --format="json"' + ); + const { location, name } = JSON.parse(clusterData)[0]; const key = `gke_${projectId}_${location}_${name}`; await run(`kubectl config unset clusters.${key}`); await run(`kubectl config unset contexts.${key}`); diff --git a/src/ls.js b/src/ls.js index fd801cc..bfc81da 100644 --- a/src/ls.js +++ b/src/ls.js @@ -1,6 +1,6 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [deployment] = args; if (!deployment) { return run('kubectl get deployments'); diff --git a/src/remove.js b/src/remove.js index 5ed07cb..feeb9e7 100644 --- a/src/remove.js +++ b/src/remove.js @@ -1,6 +1,6 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [deployment] = args; await run(`kubectl delete deploy ${deployment}`); }; diff --git a/src/scale.js b/src/scale.js index cf797ea..e393109 100644 --- a/src/scale.js +++ b/src/scale.js @@ -1,6 +1,6 @@ -const {logError, run} = require('./utils'); +const { logError, run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [name, min, max] = args; if (!name) { return logError('name (required): snow scale [name]'); @@ -9,11 +9,15 @@ module.exports = async function (args) { return logError('min (required): snow scale [name] [min]'); } if (isNaN(Number(min))) { - return logError('min (typecheck: must be numberic): snow scale [name] [min]'); + return logError( + 'min (typecheck: must be numberic): snow scale [name] [min]' + ); } if (max && isNaN(Number(max))) { - return logError('max (typecheck: must be numberic): snow scale [name] [min] [max]'); + return logError( + 'max (typecheck: must be numberic): snow scale [name] [min] [max]' + ); } // If CLI called without 'max' supplied, default to 'min'. @@ -23,9 +27,13 @@ module.exports = async function (args) { try { await run(`kubectl get hpa ${name}`); // HPA exists. Patch it. - await run(`kubectl patch hpa ${name} --patch '{"spec":{"minReplicas":${min},"maxReplicas":${actualMax}}}'`); + await run( + `kubectl patch hpa ${name} --patch '{"spec":{"minReplicas":${min},"maxReplicas":${actualMax}}}'` + ); } catch (error) { // No HPA. Create one. - await run(`kubectl autoscale deployment/${name} --min=${min} --max=${actualMax}`); + await run( + `kubectl autoscale deployment/${name} --min=${min} --max=${actualMax}` + ); } }; diff --git a/src/secrets.js b/src/secrets.js index 31328de..09bdb99 100644 --- a/src/secrets.js +++ b/src/secrets.js @@ -1,12 +1,14 @@ -const {isRemove, run} = require('./utils'); +const { isRemove, run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [action, key, value] = args; if (action === 'ls') { await run('kubectl get secrets'); } if (action === 'add') { - await run(`kubectl create secret generic ${key} --from-literal=${key}=${value}`); + await run( + `kubectl create secret generic ${key} --from-literal=${key}=${value}` + ); } if (isRemove(action)) { await run(`kubectl delete secret ${key}`); diff --git a/src/utils.js b/src/utils.js index e0a0f24..6388a1c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -27,7 +27,11 @@ function confirm(msg) { return new Promise(resolve => { function data(d) { process.stdin.pause(); - const isYes = d.toString().trim().toLowerCase() === 'y'; + const isYes = + d + .toString() + .trim() + .toLowerCase() === 'y'; if (!isYes) { console.log(`${chalk.grey('> ')} Aborted`); } @@ -61,7 +65,10 @@ function pickOne(msg, options) { process.stdout.write(`${question} (${options.join(',')}) ${prefixesStr} `); return new Promise(resolve => { function data(d) { - const input = d.toString().trim().toLowerCase(); + const input = d + .toString() + .trim() + .toLowerCase(); const index = prefixes.indexOf(input); const option = options[index]; process.stdin.removeListener('data', data).pause(); diff --git a/yarn.lock b/yarn.lock index 8dac550..a5de113 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,6 +18,20 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@iamstarkov/listr-update-renderer@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e" + integrity sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -31,6 +45,13 @@ resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + acorn-jsx@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz#958584ddb60990c02c97c1bd9d521fce433bb101" @@ -68,18 +89,33 @@ ansi-escapes@^3.0.0: resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-styles@^3.2.1: +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -229,6 +265,13 @@ call-me-maybe@^1.0.1: resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -236,11 +279,23 @@ caller-path@^0.1.0: dependencies: callsites "^0.2.0" +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + callsites@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -260,7 +315,7 @@ capture-stack-trace@^1.0.0: resolved "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== -chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: +chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== @@ -269,6 +324,17 @@ chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -279,6 +345,11 @@ ci-info@^1.5.0: resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" @@ -306,18 +377,31 @@ cli-boxes@^1.0.0: resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= -cli-cursor@^2.1.0: +cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -338,6 +422,11 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +commander@^2.14.1, commander@^2.9.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -383,6 +472,25 @@ core-js@^2.0.0: resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== +cosmiconfig@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +cosmiconfig@^5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" @@ -399,7 +507,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -422,6 +530,11 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -461,6 +574,11 @@ decode-uri-component@^0.2.0: resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -552,6 +670,18 @@ duplexer3@^0.1.4: resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + enhance-visitors@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz#aa945d05da465672a1ebd38fee2ed3da8518e95a" @@ -571,7 +701,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -850,6 +980,19 @@ execa@^0.9.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -933,6 +1076,14 @@ fast-levenshtein@~2.0.4: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + figures@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -958,6 +1109,11 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + find-up@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -973,6 +1129,13 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + flat-cache@^1.2.1: version "1.3.2" resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.2.tgz#7f852d70be573dac874a4c4129d340a34fba7e65" @@ -1010,6 +1173,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" + integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + get-set-props@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz#998475c178445686d0b32246da5df8dbcfbe8ea3" @@ -1025,6 +1202,13 @@ get-stream@^3.0.0: resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -1113,6 +1297,13 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1166,6 +1357,22 @@ hosted-git-info@^2.1.4: resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +husky@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" + integrity sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg== + dependencies: + cosmiconfig "^5.0.7" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^2.0.0" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1183,6 +1390,14 @@ ignore@^4.0.2, ignore@^4.0.6: resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -1283,6 +1498,13 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -1315,6 +1537,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + is-error@^2.2.0: version "2.2.1" resolved "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" @@ -1337,6 +1564,13 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -1399,11 +1633,18 @@ is-obj-prop@^1.0.0: lowercase-keys "^1.0.0" obj-props "^1.0.0" -is-obj@^1.0.0: +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -1453,6 +1694,11 @@ is-redirect@^1.0.0: resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" @@ -1505,6 +1751,21 @@ jest-docblock@^21.0.0: resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== +jest-get-type@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== + +jest-validate@^23.5.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -1515,7 +1776,7 @@ js-types@^1.0.0: resolved "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz#d242e6494ed572ad3c92809fc8bed7f7687cbf03" integrity sha1-0kLmSU7Vcq08koCfyL7X92h8vwM= -js-yaml@^3.12.0: +js-yaml@^3.12.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -1569,6 +1830,11 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1582,6 +1848,81 @@ line-column-path@^1.0.0: resolved "https://registry.npmjs.org/line-column-path/-/line-column-path-1.0.0.tgz#383b83fca8488faa7a59940ebf28b82058c16c55" integrity sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU= +lint-staged@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" + integrity sha512-yfSkyJy7EuVsaoxtUSEhrD81spdJOe/gMTGea3XaV7HyoRhTb9Gdlp6/JppRZERvKSEYXP9bjcmq6CA5oL2lYQ== + dependencies: + "@iamstarkov/listr-update-renderer" "0.4.1" + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "5.0.6" + debug "^3.1.0" + dedent "^0.7.0" + del "^3.0.0" + execa "^1.0.0" + find-parent-dir "^0.3.0" + g-status "^2.0.2" + is-glob "^4.0.0" + is-windows "^1.0.2" + jest-validate "^23.5.0" + listr "^0.14.2" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.2" + string-argv "^0.0.2" + stringify-object "^3.2.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.2: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + load-json-file@^2.0.0: version "2.0.0" resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -1610,6 +1951,14 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash.camelcase@^4.1.1: version "4.3.0" resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -1655,13 +2004,29 @@ lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== -log-symbols@^2.0.0: +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^2.0.0, log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== dependencies: chalk "^2.0.1" +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -1712,6 +2077,13 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + meow@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" @@ -1732,7 +2104,7 @@ merge2@^1.2.3: resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== -micromatch@^3.1.10: +micromatch@^3.1.10, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -1863,6 +2235,13 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== + dependencies: + which "^1.2.10" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -1870,12 +2249,26 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + obj-props@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz#626313faa442befd4a44e9a02c3cb6bde937b511" integrity sha1-YmMT+qRCvv1KROmgLDy2vek3tRE= -object-assign@^4.0.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -1903,7 +2296,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -1962,6 +2355,13 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" + integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -1969,16 +2369,33 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-map@^1.1.1: version "1.2.0" resolved "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== +p-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" + integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== + p-try@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + package-json@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -2097,6 +2514,13 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" @@ -2104,6 +2528,13 @@ pkg-up@^2.0.0: dependencies: find-up "^2.1.0" +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + plur@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" @@ -2131,11 +2562,24 @@ prepend-http@^1.0.1: resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +prettier@1.15.3: + version "1.15.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" + integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== + prettier@^1.12.1: version "1.15.2" resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + progress@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" @@ -2151,6 +2595,14 @@ pseudomap@^1.0.2: resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2205,6 +2657,15 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + redent@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" @@ -2320,7 +2781,12 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" -rxjs@^6.1.0: +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + +rxjs@^6.1.0, rxjs@^6.3.3: version "6.3.3" resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== @@ -2344,6 +2810,11 @@ safe-regex@^1.1.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -2393,6 +2864,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-git@^1.85.0: + version "1.107.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.107.0.tgz#12cffaf261c14d6f450f7fdb86c21ccee968b383" + integrity sha512-t4OK1JRlp4ayKRfcW6owrWcRVLyHRUlhGd0uN6ZZTqfDq8a5XpcUdOKiGRNobHEuMtNqzp0vcJNvhYWwh5PsQA== + dependencies: + debug "^4.0.1" + slash@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -2403,6 +2881,11 @@ slash@^2.0.0: resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" @@ -2506,6 +2989,11 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -2514,6 +3002,20 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -2522,6 +3024,22 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +stringify-object@^3.2.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -2549,6 +3067,11 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2556,6 +3079,11 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + table@^5.0.2: version "5.1.0" resolved "https://registry.npmjs.org/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" @@ -2720,7 +3248,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -which@^1.2.9: +which@^1.2.10, which@^1.2.9: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -2739,6 +3267,14 @@ wordwrap@~1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From a24b0b488adc16066b57055bf8876193cf52ac53 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Wed, 2 Jan 2019 10:26:31 -0800 Subject: [PATCH 27/62] incremental adoption --- .gitignore | 1 + package.json | 6 +- src/{secrets.js => secrets.ts} | 9 ++- src/{utils.js => utils.ts} | 114 +++++++++++++++++++-------------- tsconfig.json | 18 ++++++ yarn.lock | 10 +++ 6 files changed, 107 insertions(+), 51 deletions(-) rename src/{secrets.js => secrets.ts} (79%) rename src/{utils.js => utils.ts} (54%) create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 7c42ab5..eecd45a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ config/build-context/context.tar.gz node_modules +dist diff --git a/package.json b/package.json index 8933eb3..7825c93 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ }, "scripts": { "lint": "xo", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc && npm run build:typescript && npm run build:typescript", + "build:typescript": "tsc" }, "bin": { "snow": "src/index.js" @@ -24,6 +26,7 @@ }, "homepage": "https://github.com/snowjs/cli#readme", "dependencies": { + "@types/node": "10.12.18", "chalk": "2.4.1", "mri": "1.1.1" }, @@ -31,6 +34,7 @@ "husky": "1.3.1", "lint-staged": "8.1.0", "prettier": "1.15.3", + "typescript": "3.2.2", "xo": "0.23.0" }, "xo": { diff --git a/src/secrets.js b/src/secrets.ts similarity index 79% rename from src/secrets.js rename to src/secrets.ts index 09bdb99..c3fac9d 100644 --- a/src/secrets.js +++ b/src/secrets.ts @@ -1,16 +1,21 @@ const { isRemove, run } = require('./utils'); -module.exports = async function(args) { +type ISecret = [string, string, string]; + +export default async function(args: ISecret) { const [action, key, value] = args; + if (action === 'ls') { await run('kubectl get secrets'); } + if (action === 'add') { await run( `kubectl create secret generic ${key} --from-literal=${key}=${value}` ); } + if (isRemove(action)) { await run(`kubectl delete secret ${key}`); } -}; +} diff --git a/src/utils.js b/src/utils.ts similarity index 54% rename from src/utils.js rename to src/utils.ts index 6388a1c..df81aca 100644 --- a/src/utils.js +++ b/src/utils.ts @@ -1,117 +1,135 @@ -const childProcess = require('child_process'); -const fs = require('fs'); -const util = require('util'); -const chalk = require('chalk'); +import * as childProcess from 'child_process'; +import * as fs from 'fs'; +import { promisify } from 'util'; +import chalk from 'chalk'; -const exec = util.promisify(childProcess.exec); -const stat = util.promisify(fs.stat); -const readFile = util.promisify(fs.readFile); +export const exec = promisify(childProcess.exec); +export const stat = promisify(fs.stat); +export const readFile = promisify(fs.readFile); -function askForInput(msg) { +function normalizeString(str: string) { + return str + .toString() + .trim() + .toLowerCase(); +} + +export function askForInput(msg: string) { const question = chalk.bold.red(`> ${msg}: `); process.stdout.write(question); + return new Promise(resolve => { - function data(d) { + function data(d: any) { const input = d.toString().trim(); process.stdin.removeListener('data', data).pause(); resolve(input); } + process.stdin.on('data', data).resume(); }); } -function confirm(msg) { +export function confirm(msg: string) { const question = chalk.bold.red(`> ${msg}?`); const options = chalk.gray('[y/N] '); + process.stdout.write(`${question} ${options} `); + return new Promise(resolve => { - function data(d) { + function data(d: any) { process.stdin.pause(); - const isYes = - d - .toString() - .trim() - .toLowerCase() === 'y'; + const isYes = normalizeString(d) === 'y'; + if (!isYes) { console.log(`${chalk.grey('> ')} Aborted`); } + process.stdin.removeListener('data', data).pause(); resolve(isYes); } + process.stdin.on('data', data).resume(); }); } -function isRemove(str) { +export function isRemove(str: string) { return str === 'rm' || str === 'remove'; } -function logDebug(message) { - console.log(chalk.gray(message)); +export function logDebug(msg: string) { + console.log(chalk.gray(msg)); } -function logError(message) { - console.log(chalk.bold.red(message)); +export function logError(msg: string) { + console.log(chalk.bold.red(msg)); } -function logInfo(message) { - console.log(chalk.bold.white(message)); +export function logInfo(msg: string) { + console.log(chalk.bold.white(msg)); } -function pickOne(msg, options) { +export function pickOne(msg: string, options: string[]) { const question = chalk.bold.red(`> ${msg}?`); const prefixes = options.map(option => option.charAt(0)); const prefixesStr = chalk.gray(`[${prefixes.join(',')}]`); + process.stdout.write(`${question} (${options.join(',')}) ${prefixesStr} `); + return new Promise(resolve => { - function data(d) { - const input = d - .toString() - .trim() - .toLowerCase(); + function data(d: any) { + const input = normalizeString(d); const index = prefixes.indexOf(input); const option = options[index]; + process.stdin.removeListener('data', data).pause(); + resolve(option); } + process.stdin.on('data', data).resume(); }); } -function run(str, opts) { +export function run( + str: string, + opts: { + encoding: 'buffer' | null; + } & childProcess.ExecOptions +) { const runString = str.replace(/(\s+)/gm, ' ').trim(); + logInfo(`> ${runString}`); + return new Promise((resolve, reject) => { - function callback(error, stdout, stderr) { + function callback( + error: childProcess.ExecException | null, + stdout: string, + stderr: string + ) { if (error) { - process.stderr.write(chalk.red(error)); + process.stderr.write(chalk.red(error.message)); + + if (error.stack) { + process.stderr.write(chalk.white(error.stack)); + } + return reject(error); } + return resolve({ stdout: stdout.trim(), stderr: stderr.trim() }); } + const cmd = childProcess.exec(str, opts, callback); - cmd.stderr.on('data', data => { + + cmd.stderr.on('data', (data: string) => { process.stdout.write(chalk.gray(data)); }); - cmd.stdout.on('data', data => { + + cmd.stdout.on('data', (data: string) => { process.stdout.write(chalk.gray(data)); }); }); } - -module.exports = { - askForInput, - confirm, - exec, - isRemove, - logDebug, - logError, - logInfo, - pickOne, - readFile, - run, - stat -}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f253002 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "allowJs": true, + "lib": ["es2017"], + "moduleResolution": "node", + "downlevelIteration": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "outDir": "dist", + "preserveConstEnums": true, + "removeComments": false, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "typeRoots": ["packages/types/", "node_modules/@types/"] + }, + "include": ["src/*"] +} diff --git a/yarn.lock b/yarn.lock index a5de113..8f1828b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,6 +52,11 @@ dependencies: any-observable "^0.3.0" +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + acorn-jsx@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz#958584ddb60990c02c97c1bd9d521fce433bb101" @@ -3170,6 +3175,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +typescript@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" + integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== + union-value@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" From 6510eadcf79eb63b7b26e61b1dfbceb3e91f3738 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Wed, 2 Jan 2019 10:33:42 -0800 Subject: [PATCH 28/62] add tslint --- package.json | 19 +- src/secrets.ts | 4 +- src/utils.ts | 14 +- tslint.json | 19 + yarn.lock | 1816 +++++------------------------------------------- 5 files changed, 202 insertions(+), 1670 deletions(-) create mode 100644 tslint.json diff --git a/package.json b/package.json index 7825c93..0b50030 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,10 @@ "node": ">=8.0.0" }, "scripts": { - "lint": "xo", "test": "echo \"Error: no test specified\" && exit 1", "build": "tsc && npm run build:typescript && npm run build:typescript", - "build:typescript": "tsc" + "build:typescript": "tsc", + "lint": "tslint -p . --format stylish" }, "bin": { "snow": "src/index.js" @@ -34,17 +34,10 @@ "husky": "1.3.1", "lint-staged": "8.1.0", "prettier": "1.15.3", - "typescript": "3.2.2", - "xo": "0.23.0" - }, - "xo": { - "rules": { - "no-await-in-loop": 0 - }, - "space": true, - "extends": [ - "prettier" - ] + "tslint": "5.12.0", + "tslint-config-prettier": "1.17.0", + "tslint-xo": "0.11.0", + "typescript": "3.2.2" }, "prettier": { "singleQuote": true diff --git a/src/secrets.ts b/src/secrets.ts index c3fac9d..aa291b2 100644 --- a/src/secrets.ts +++ b/src/secrets.ts @@ -1,8 +1,8 @@ -const { isRemove, run } = require('./utils'); +import { isRemove, run } from './utils'; type ISecret = [string, string, string]; -export default async function(args: ISecret) { +export default async function secrets(args: ISecret) { const [action, key, value] = args; if (action === 'ls') { diff --git a/src/utils.ts b/src/utils.ts index df81aca..5b99869 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ +import chalk from 'chalk'; import * as childProcess from 'child_process'; import * as fs from 'fs'; -import { promisify } from 'util'; -import chalk from 'chalk'; +import {promisify} from 'util'; export const exec = promisify(childProcess.exec); export const stat = promisify(fs.stat); @@ -14,7 +14,7 @@ function normalizeString(str: string) { .toLowerCase(); } -export function askForInput(msg: string) { +export async function askForInput(msg: string) { const question = chalk.bold.red(`> ${msg}: `); process.stdout.write(question); @@ -29,7 +29,7 @@ export function askForInput(msg: string) { }); } -export function confirm(msg: string) { +export async function confirm(msg: string) { const question = chalk.bold.red(`> ${msg}?`); const options = chalk.gray('[y/N] '); @@ -68,7 +68,7 @@ export function logInfo(msg: string) { console.log(chalk.bold.white(msg)); } -export function pickOne(msg: string, options: string[]) { +export async function pickOne(msg: string, options: string[]) { const question = chalk.bold.red(`> ${msg}?`); const prefixes = options.map(option => option.charAt(0)); const prefixesStr = chalk.gray(`[${prefixes.join(',')}]`); @@ -90,9 +90,9 @@ export function pickOne(msg: string, options: string[]) { }); } -export function run( +export async function run( str: string, - opts: { + opts?: { encoding: 'buffer' | null; } & childProcess.ExecOptions ) { diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..6f69590 --- /dev/null +++ b/tslint.json @@ -0,0 +1,19 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended", + "tslint-config-prettier", + "tslint-xo/space" + ], + "jsRules": { + "no-console": false, + "object-literal-sort-keys": false, + "object-curly-spacing": false + }, + "rules": { + "no-console": false, + "object-literal-sort-keys": false, + "object-curly-spacing": false + }, + "rulesDirectory": [] +} diff --git a/yarn.lock b/yarn.lock index 8f1828b..0fe6dbf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,21 +2,24 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== +"@fimbul/bifrost@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.15.0.tgz#f3a48dee3046681e926c1f970f0b1a67e29e088e" + integrity sha512-sHTwnwA9YhxcVEJkBlfKH1KLmGQGnNYPxk+09w5NnkXelYiiP8a5f351weYfxG0CUPLt1Fgkha20Y/9+jhjn/Q== dependencies: - "@babel/highlight" "^7.0.0" + "@fimbul/ymir" "^0.15.0" + get-caller-file "^2.0.0" + tslib "^1.8.1" + tsutils "^3.1.0" -"@babel/highlight@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" - integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== +"@fimbul/ymir@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@fimbul/ymir/-/ymir-0.15.0.tgz#944c881b14fadf7b43d1ae00b445e42261bb407f" + integrity sha512-Ow0TfxxQ65vIktHcZyXHeDsGKuzJ9Vt6y77R/aOrXQXLMdYHG+XdbiUWzQbtaGOmNzYVkQfINiFnIdvn5Bn24g== dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" + inversify "^5.0.0" + reflect-metadata "^0.1.12" + tslib "^1.8.1" "@iamstarkov/listr-update-renderer@0.4.1": version "0.4.1" @@ -32,19 +35,6 @@ log-update "^2.3.0" strip-ansi "^3.0.1" -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -57,38 +47,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -acorn-jsx@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz#958584ddb60990c02c97c1bd9d521fce433bb101" - integrity sha512-XkB50fn0MURDyww9+UYL3c1yLbOBz0ZFvrdYlGB8l+Ije1oSC75qAqrzSPjYQbdnQUzhlUGNKuesryAv0gxZOg== - -acorn@^6.0.2: - version "6.0.4" - resolved "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" - integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== - -ajv@^6.5.3: - version "6.5.5" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" - integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= - dependencies: - string-width "^2.0.0" - -ansi-escapes@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" - integrity sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs= - ansi-escapes@^3.0.0: version "3.1.0" resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -143,16 +101,6 @@ arr-union@^3.1.0: resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - array-union@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -170,7 +118,7 @@ array-unique@^0.3.2: resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -arrify@^1.0.0, arrify@^1.0.1: +arrify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= @@ -185,6 +133,15 @@ atob@^2.1.1: resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -203,19 +160,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -240,12 +184,7 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -buf-compare@^1.0.0: - version "1.0.1" - resolved "http://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" - integrity sha1-/vKNqLgROgoNtEMLC2Rntpcws0o= - -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= @@ -265,11 +204,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -277,13 +211,6 @@ caller-callsite@^2.0.0: dependencies: callsites "^2.0.0" -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= - dependencies: - callsites "^0.2.0" - caller-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" @@ -291,36 +218,12 @@ caller-path@^2.0.0: dependencies: caller-callsite "^2.0.0" -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= - callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= -camelcase-keys@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" - integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= - dependencies: - camelcase "^4.1.0" - map-obj "^2.0.0" - quick-lru "^1.0.0" - -camelcase@^4.0.0, camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== - -chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: +chalk@2.4.1, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== @@ -340,26 +243,11 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -370,18 +258,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -clean-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" - integrity sha1-jffHquUf02h06PjQW5GAvBGj/tc= - dependencies: - escape-string-regexp "^1.0.5" - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= - cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -397,11 +273,6 @@ cli-truncate@^0.2.1: slice-ansi "0.0.4" string-width "^1.0.1" -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -427,7 +298,7 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -commander@^2.14.1, commander@^2.9.0: +commander@^2.12.1, commander@^2.14.1, commander@^2.9.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== @@ -442,41 +313,11 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -configstore@^3.0.0: - version "3.1.2" - resolved "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-assert@^0.2.0: - version "0.2.1" - resolved "http://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" - integrity sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8= - dependencies: - buf-compare "^1.0.0" - is-error "^2.2.0" - -core-js@^2.0.0: - version "2.5.7" - resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" - integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== - cosmiconfig@5.0.6: version "5.0.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" @@ -496,23 +337,7 @@ cosmiconfig@^5.0.7: js-yaml "^3.9.0" parse-json "^4.0.0" -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= - dependencies: - capture-stack-trace "^1.0.0" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -523,24 +348,12 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" - date-fns@^1.27.2: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== -debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -561,19 +374,6 @@ debug@^4.0.1: dependencies: ms "^2.1.1" -decamelize-keys@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -584,23 +384,6 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -deep-strict-equal@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz#4a078147a8ab57f6a0d4f5547243cd22f44eb4e4" - integrity sha1-SgeBR6irV/ag1PVUckPNIvROtOQ= - dependencies: - core-assert "^0.2.0" - define-property@^0.2.5: version "0.2.5" resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -635,45 +418,18 @@ del@^3.0.0: pify "^3.0.0" rimraf "^2.2.8" -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= - -dir-glob@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" - integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== - dependencies: - arrify "^1.0.1" - path-type "^3.0.0" - -doctrine@1.5.0: - version "1.5.0" - resolved "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== -dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== +doctrine@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523" + integrity sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM= dependencies: - is-obj "^1.0.0" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + esutils "^1.1.6" + isarray "0.0.1" elegant-spinner@^1.0.1: version "1.0.1" @@ -687,19 +443,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhance-visitors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz#aa945d05da465672a1ebd38fee2ed3da8518e95a" - integrity sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo= - dependencies: - lodash "^4.13.1" - -env-editor@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/env-editor/-/env-editor-0.3.1.tgz#30d0540c2101414f258a94d4c0a524c06c13e3c6" - integrity sha1-MNBUDCEBQU8lipTUwKUkwGwT48Y= - -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -711,280 +455,21 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -eslint-ast-utils@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz#3d58ba557801cfb1c941d68131ee9f8c34bd1586" - integrity sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA== - dependencies: - lodash.get "^4.4.2" - lodash.zip "^4.2.0" - -eslint-config-prettier@^3.0.1: - version "3.3.0" - resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz#41afc8d3b852e757f06274ed6c44ca16f939a57d" - integrity sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA== - dependencies: - get-stdin "^6.0.0" - -eslint-config-xo@^0.25.0: - version "0.25.0" - resolved "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.25.0.tgz#8e8bbdee06e3d75b47aeba03fb28d4a43cc8092f" - integrity sha512-bViV+I3smPWzzhI15U9PIk5CTt1Ym/GqdtRMIK/LePqp0yKLgw+WC51bBZEPgrKcib79uwwOLVPrv+nzoJJj+g== - -eslint-formatter-pretty@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-1.3.0.tgz#985d9e41c1f8475f4a090c5dbd2dfcf2821d607e" - integrity sha512-5DY64Y1rYCm7cfFDHEGUn54bvCnK+wSUVF07N8oXeqUJFSd+gnYOTXbzelQ1HurESluY6gnEQPmXOIkB4Wa+gA== - dependencies: - ansi-escapes "^2.0.0" - chalk "^2.1.0" - log-symbols "^2.0.0" - plur "^2.1.2" - string-width "^2.0.0" - -eslint-import-resolver-node@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" - integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== - dependencies: - debug "^2.6.9" - resolve "^1.5.0" - -eslint-module-utils@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= - dependencies: - debug "^2.6.8" - pkg-dir "^1.0.0" - -eslint-plugin-ava@^5.1.0: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-5.1.1.tgz#709a03f6c56f9f316d83ebc739952cc28cea979a" - integrity sha512-3N7geVdXTabpngQOl+ih1ejMbFOXCUYROnTIP66KAQoMcEAkPSXYc/Jwo/qC4zpRR7PXMuf5afMzTEBpyZmWzQ== - dependencies: - arrify "^1.0.1" - deep-strict-equal "^0.2.0" - enhance-visitors "^1.0.0" - esm "^3.0.82" - espree "^4.0.0" - espurify "^1.8.1" - import-modules "^1.1.0" - is-plain-object "^2.0.4" - multimatch "^2.1.0" - pkg-up "^2.0.0" - -eslint-plugin-es@^1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.3.2.tgz#6d2e94ed40db3b3d92a0eb55c7c06e3a7adbb3db" - integrity sha512-xrdbConViY20DhGrt9FwjhDo4fr/9Yus2pYf0xJsdJaCcUzMq7+pAoNH7kSXF6V08bRHMpgDWclYbcr/Sn3hNg== - dependencies: - eslint-utils "^1.3.0" - regexpp "^2.0.1" - -eslint-plugin-import@^2.14.0: - version "2.14.0" - resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== - dependencies: - contains-path "^0.1.0" - debug "^2.6.8" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" - read-pkg-up "^2.0.0" - resolve "^1.6.0" - -eslint-plugin-no-use-extend-native@^0.3.12: - version "0.3.12" - resolved "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.3.12.tgz#3ad9a00c2df23b5d7f7f6be91550985a4ab701ea" - integrity sha1-OtmgDC3yO11/f2vpFVCYWkq3Aeo= - dependencies: - is-get-set-prop "^1.0.0" - is-js-type "^2.0.0" - is-obj-prop "^1.0.0" - is-proto-prop "^1.0.0" - -eslint-plugin-node@^7.0.0: - version "7.0.1" - resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz#a6e054e50199b2edd85518b89b4e7b323c9f36db" - integrity sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw== - dependencies: - eslint-plugin-es "^1.3.1" - eslint-utils "^1.3.1" - ignore "^4.0.2" - minimatch "^3.0.4" - resolve "^1.8.1" - semver "^5.5.0" - -eslint-plugin-prettier@^2.6.0: - version "2.7.0" - resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" - integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== - dependencies: - fast-diff "^1.1.1" - jest-docblock "^21.0.0" - -eslint-plugin-promise@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" - integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== - -eslint-plugin-unicorn@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-6.0.1.tgz#4a97f0bc9449e20b82848dad12094ee2ba72347e" - integrity sha512-hjy9LhTdtL7pz8WTrzS0CGXRkWK3VAPLDjihofj8JC+uxQLfXm0WwZPPPB7xKmcjRyoH+jruPHOCrHNEINpG/Q== - dependencies: - clean-regexp "^1.0.0" - eslint-ast-utils "^1.0.0" - import-modules "^1.1.0" - lodash.camelcase "^4.1.1" - lodash.kebabcase "^4.0.1" - lodash.snakecase "^4.0.1" - lodash.upperfirst "^4.2.0" - safe-regex "^1.1.0" - -eslint-scope@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" - integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.0, eslint-utils@^1.3.1: - version "1.3.1" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== - -eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== - -eslint@^5.5.0: - version "5.9.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" - integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^2.1.0" - eslint-scope "^4.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^4.0.0" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - imurmurhash "^0.1.4" - inquirer "^6.1.0" - is-resolvable "^1.1.0" - js-yaml "^3.12.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.5" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - pluralize "^7.0.0" - progress "^2.0.0" - regexpp "^2.0.1" - require-uncached "^1.0.3" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.0.2" - text-table "^0.2.0" - -esm@^3.0.82: - version "3.0.84" - resolved "https://registry.npmjs.org/esm/-/esm-3.0.84.tgz#bb108989f4673b32d4f62406869c28eed3815a63" - integrity sha512-SzSGoZc17S7P+12R9cg21Bdb7eybX25RnIeRZ80xZs+VZ3kdQKzqTp2k4hZJjR7p9l0186TTXSgrxzlMDBktlw== - -espree@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" - integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== - dependencies: - acorn "^6.0.2" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - esprima@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -espurify@^1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz#5746c6c1ab42d302de10bd1d5bf7f0e8c0515056" - integrity sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg== - dependencies: - core-js "^2.0.0" - -esquery@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +esutils@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" + integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U= esutils@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" - integrity sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA== - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -1026,15 +511,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -external-editor@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" - integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -1049,38 +525,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-diff@^1.1.1: - version "1.2.0" - resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@^2.0.2: - version "2.2.4" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" - integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -1096,14 +540,6 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -1119,21 +555,6 @@ find-parent-dir@^0.3.0: resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -1141,16 +562,6 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -flat-cache@^1.2.1: - version "1.3.2" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.2.tgz#7f852d70be573dac874a4c4129d340a34fba7e65" - integrity sha512-KByBY8c98sLUAGpnmjEdWTrtrLZRtZdwds+kAL/ciFXTCb7AZgqKsAnVnYFQj1hxepwO8JKN/8AsRWwLq+RK0A== - dependencies: - circular-json "^0.3.1" - del "^3.0.0" - graceful-fs "^4.1.2" - write "^0.2.1" - for-in@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -1168,16 +579,6 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - g-status@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" @@ -1187,26 +588,21 @@ g-status@^2.0.2: matcher "^1.0.0" simple-git "^1.85.0" +get-caller-file@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.1.tgz#25835260d3a2b9665fcdbb08cb039a7bbf7011c0" + integrity sha512-SpOZHfz845AH0wJYVuZk2jWDqFmu7Xubsx+ldIpwzy5pDUpu7OJHK7QYNSA2NPlDSKQwM1GFaAkciOWjjW92Sg== + get-own-enumerable-property-symbols@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== -get-set-props@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz#998475c178445686d0b32246da5df8dbcfbe8ea3" - integrity sha1-mYR1wXhEVobQsyJG2l3428++jqM= - get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== -get-stream@^3.0.0: - version "3.0.0" - resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -1219,20 +615,7 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - -glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: version "7.1.3" resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== @@ -1244,18 +627,6 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= - dependencies: - ini "^1.3.4" - -globals@^11.7.0: - version "11.9.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" - integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== - globby@^6.1.0: version "6.1.0" resolved "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -1267,41 +638,6 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^8.0.0: - version "8.0.1" - resolved "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" - integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - fast-glob "^2.0.2" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -got@^6.7.1: - version "6.7.1" - resolved "http://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.15" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -1345,18 +681,6 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has-yarn@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" - integrity sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac= - -has@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" @@ -1378,23 +702,6 @@ husky@1.3.1: run-node "^1.0.0" slash "^2.0.0" -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== - -ignore@^4.0.2, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -1403,21 +710,6 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -import-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" - integrity sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - indent-string@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -1436,34 +728,10 @@ inherits@2: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^6.1.0: - version "6.2.0" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" - integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.0" - figures "^2.0.0" - lodash "^4.17.10" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -irregular-plurals@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" - integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= +inversify@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.1.tgz#500d709b1434896ce5a0d58915c4a4210e34fb6e" + integrity sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ== is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -1496,13 +764,6 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -1547,11 +808,6 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= -is-error@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" - integrity sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw= - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -1564,7 +820,7 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= @@ -1581,21 +837,6 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= -is-get-set-prop@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz#2731877e4d78a6a69edcce6bb9d68b0779e76312" - integrity sha1-JzGHfk14pqae3M5rudaLB3nnYxI= - dependencies: - get-set-props "^0.1.0" - lowercase-keys "^1.0.0" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" @@ -1603,26 +844,6 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-js-type@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz#73617006d659b4eb4729bba747d28782df0f7e22" - integrity sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI= - dependencies: - js-types "^1.0.0" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= - is-number@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -1630,15 +851,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-obj-prop@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz#b34de79c450b8d7c73ab2cdf67dc875adb85f80e" - integrity sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4= - dependencies: - lowercase-keys "^1.0.0" - obj-props "^1.0.0" - -is-obj@^1.0.0, is-obj@^1.0.1: +is-obj@^1.0.1: version "1.0.1" resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= @@ -1669,11 +882,6 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -1686,35 +894,12 @@ is-promise@^2.1.0: resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-proto-prop@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.1.tgz#c8a0455c28fe38c8843d0c22af6f95f01ed4abc4" - integrity sha512-dkmgrJB7nfJhH1ySK1/Qn9xLPMv3ZNlPSAPoyUseD6DQzBF6YmbgQnoyy9OM8derNUlDVJlUGdCEhYbcCPfN5A== - dependencies: - lowercase-keys "^1.0.0" - proto-props "^1.1.0" - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= - is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== - -is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= - -is-stream@^1.0.0, is-stream@^1.1.0: +is-stream@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -1724,12 +909,12 @@ is-windows@^1.0.2: resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= -isarray@1.0.0, isarray@^1.0.0: +isarray@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -1751,11 +936,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -jest-docblock@^21.0.0: - version "21.2.0" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" - integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== - jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" @@ -1771,17 +951,12 @@ jest-validate@^23.5.0: leven "^2.1.0" pretty-format "^23.6.0" -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-types@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz#d242e6494ed572ad3c92809fc8bed7f7687cbf03" - integrity sha1-0kLmSU7Vcq08koCfyL7X92h8vwM= +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.12.0, js-yaml@^3.9.0: +js-yaml@^3.7.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -1794,16 +969,6 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -1828,31 +993,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= - dependencies: - package-json "^4.0.0" - leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -line-column-path@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/line-column-path/-/line-column-path-1.0.0.tgz#383b83fca8488faa7a59940ebf28b82058c16c55" - integrity sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU= - lint-staged@8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" @@ -1928,34 +1073,6 @@ listr@^0.14.2: p-map "^2.0.0" rxjs "^6.3.3" -load-json-file@^2.0.0: - version "2.0.0" - resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -1964,47 +1081,7 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash.camelcase@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= - -lodash.kebabcase@^4.0.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= - -lodash.mergewith@^4.6.1: - version "4.6.1" - resolved "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== - -lodash.snakecase@^4.0.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= - -lodash.upperfirst@^4.2.0: - version "4.3.1" - resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" - integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= - -lodash.zip@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" - integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= - -lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: +lodash@^4.17.5: version "4.17.11" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -2016,7 +1093,7 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" -log-symbols@^2.0.0, log-symbols@^2.2.0: +log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== @@ -2032,49 +1109,11 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lru-cache@^4.0.1: - version "4.1.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -map-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" - integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= - map-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -2089,27 +1128,7 @@ matcher@^1.0.0: dependencies: escape-string-regexp "^1.0.4" -meow@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" - integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - yargs-parser "^10.0.0" - -merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== - -micromatch@^3.1.10, micromatch@^3.1.8: +micromatch@^3.1.8: version "3.1.10" resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -2133,31 +1152,13 @@ mimic-fn@^1.0.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist-options@^3.0.1: - version "3.0.2" - resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" - integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - -minimist@0.0.8: - version "0.0.8" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -2166,13 +1167,6 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1: - version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - mri@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1" @@ -2188,21 +1182,6 @@ ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -multimatch@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" - integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= - dependencies: - array-differ "^1.0.0" - array-union "^1.0.1" - arrify "^1.0.0" - minimatch "^3.0.0" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -2220,17 +1199,12 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== @@ -2268,11 +1242,6 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -obj-props@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz#626313faa442befd4a44e9a02c3cb6bde937b511" - integrity sha1-YmMT+qRCvv1KROmgLDy2vek3tRE= - object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2315,51 +1284,11 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -open-editor@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/open-editor/-/open-editor-1.2.0.tgz#75ca23f0b74d4b3f55ee0b8a4e0f5c2325eb775f" - integrity sha1-dcoj8LdNSz9V7guKTg9cIyXrd18= - dependencies: - env-editor "^0.3.1" - line-column-path "^1.0.0" - opn "^5.0.0" - -opn@^5.0.0: - version "5.4.0" - resolved "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" - integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== - dependencies: - is-wsl "^1.1.0" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - p-limit@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" @@ -2367,13 +1296,6 @@ p-limit@^2.0.0: dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -2391,33 +1313,11 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -2431,18 +1331,6 @@ pascalcase@^0.1.1: resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -2463,25 +1351,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: +path-parse@^1.0.6: version "1.0.6" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - pify@^2.0.0: version "2.3.0" resolved "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -2504,21 +1378,6 @@ pinkie@^2.0.0: resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pkg-conf@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" - integrity sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg= - dependencies: - find-up "^2.0.0" - load-json-file "^4.0.0" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -2526,13 +1385,6 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" @@ -2540,43 +1392,16 @@ please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: dependencies: semver-compare "^1.0.0" -plur@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" - integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= - dependencies: - irregular-plurals "^1.0.0" - -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - prettier@1.15.3: version "1.15.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== -prettier@^1.12.1: - version "1.15.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" - integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== - pretty-format@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" @@ -2585,21 +1410,6 @@ pretty-format@^23.6.0: ansi-regex "^3.0.0" ansi-styles "^3.2.0" -progress@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" - integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== - -proto-props@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/proto-props/-/proto-props-1.1.0.tgz#e2606581dd24aa22398aeeeb628fc08e2ec89c91" - integrity sha512-A377CdhQBRjYVsSWrm2jo0KJa+N/IBew6lGLm0pdzZjtVqlUT23wEqg7q1/bk5gBEgVoBBbaErZY+UUNrcKOug== - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -2608,60 +1418,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -quick-lru@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" - integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= - -rc@^1.0.1, rc@^1.1.6: - version "1.2.8" - resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - read-pkg@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" @@ -2671,13 +1427,10 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -redent@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" - integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= - dependencies: - indent-string "^3.0.0" - strip-indent "^2.0.0" +reflect-metadata@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" + integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -2687,26 +1440,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -registry-auth-token@^3.0.1: - version "3.3.2" - resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= - dependencies: - rc "^1.0.1" - repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -2717,47 +1450,22 @@ repeat-string@^1.6.1: resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -require-uncached@^1.0.3: - version "1.0.3" - resolved "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= - resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== +resolve@^1.3.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== dependencies: - path-parse "^1.0.5" + path-parse "^1.0.6" restore-cursor@^2.0.0: version "2.0.0" @@ -2779,30 +1487,18 @@ rimraf@^2.2.8: dependencies: glob "^7.0.5" -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - run-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== -rxjs@^6.1.0, rxjs@^6.3.3: +rxjs@^6.3.3: version "6.3.3" resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex@^1.1.0: version "1.1.0" resolved "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -2810,24 +1506,12 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= - dependencies: - semver "^5.0.3" - -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.5.0, semver@^5.5.1: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: version "5.6.0" resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -2876,11 +1560,6 @@ simple-git@^1.85.0: dependencies: debug "^4.0.1" -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - slash@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -2891,13 +1570,6 @@ slice-ansi@0.0.4: resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" - integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== - dependencies: - is-fullwidth-code-point "^2.0.0" - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -2928,13 +1600,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= - dependencies: - is-plain-obj "^1.0.0" - source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" @@ -3021,7 +1686,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +string-width@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -3052,26 +1717,11 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-eof@^1.0.0: version "1.0.0" resolved "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - -strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -3089,50 +1739,6 @@ symbol-observable@^1.1.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -table@^5.0.2: - version "5.1.0" - resolved "https://registry.npmjs.org/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" - integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg== - dependencies: - ajv "^6.5.3" - lodash "^4.17.10" - slice-ansi "1.0.0" - string-width "^2.1.1" - -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= - dependencies: - execa "^0.7.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -the-argv@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz#0084705005730dd84db755253c931ae398db9522" - integrity sha1-AIRwUAVzDdhNt1UlPJMa45jblSI= - -through@^2.3.6: - version "2.3.8" - resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -3158,22 +1764,93 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -trim-newlines@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" - integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== -tslib@^1.9.0: +tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= +tslint-config-prettier@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz#946ed6117f98f3659a65848279156d87628c33dc" + integrity sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw== + +tslint-consistent-codestyle@^1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.14.1.tgz#8555f1b05ccbf093166a73347f41eb101731a522" + integrity sha512-UxGRX2fF5LpZtqYpuPFaIva+2D7ASX3pTVw41yis6Hmw7PPA3cBnFEX1jqRsnyxGrca6mHxz7xDnwCHtOjWJMQ== dependencies: - prelude-ls "~1.1.2" + "@fimbul/bifrost" "^0.15.0" + tslib "^1.7.1" + tsutils "^2.29.0" + +tslint-eslint-rules@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5" + integrity sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w== + dependencies: + doctrine "0.7.2" + tslib "1.9.0" + tsutils "^3.0.0" + +tslint-microsoft-contrib@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.0.0.tgz#7bff73c9ad7a0b7eb5cdb04906de58f42a2bf7a2" + integrity sha512-R//efwn+34IUjTJeYgNDAJdzG0jyLWIehygPt/PHuZAieTolFVS56FgeFW7DOLap9ghXzMiFPTmDgm54qaL7QA== + dependencies: + tsutils "^2.27.2 <2.29.0" + +tslint-xo@0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/tslint-xo/-/tslint-xo-0.11.0.tgz#7cc78eb259823371edc71deff126a23afc28cef9" + integrity sha512-7CiaVI+5LxCtqqW3fl5/orjDmmH1MNTlw1/E2eC71XYengbINokLG1dY/024jofYDdcoWgAtxhVnV6PyNrndnQ== + dependencies: + tslint-consistent-codestyle "^1.14.1" + tslint-eslint-rules "^5.4.0" + tslint-microsoft-contrib "^6.0.0" + +tslint@5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.0.tgz#47f2dba291ed3d580752d109866fb640768fca36" + integrity sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ== + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.27.2" + +tsutils@^2.27.2, tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +"tsutils@^2.27.2 <2.29.0": + version "2.28.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.28.0.tgz#6bd71e160828f9d019b6f4e844742228f85169a1" + integrity sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA== + dependencies: + tslib "^1.8.1" + +tsutils@^3.0.0, tsutils@^3.1.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.6.0.tgz#33fc3ddb74abf5bba10789acd03eee6ea96c839c" + integrity sha512-hCG3lZz+uRmmiC4brr/kY6Yuypnl20PNe8t49DO4OUGlbxWkxYHF63EeG2XPSd0JcKiWmp9p55yQyrkxqSS5Dg== + dependencies: + tslib "^1.8.1" typescript@3.2.2: version "3.2.2" @@ -3190,13 +1867,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - unset-value@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -3205,46 +1875,11 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= - -update-notifier@^2.3.0: - version "2.5.0" - resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - urix@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - use@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -3265,18 +1900,6 @@ which@^1.2.10, which@^1.2.9: dependencies: isexe "^2.0.0" -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== - dependencies: - string-width "^2.1.1" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - wrap-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" @@ -3289,106 +1912,3 @@ wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-json-file@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" - integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - pify "^3.0.0" - sort-keys "^2.0.0" - write-file-atomic "^2.0.0" - -write-pkg@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" - integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== - dependencies: - sort-keys "^2.0.0" - write-json-file "^2.2.0" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= - dependencies: - mkdirp "^0.5.1" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - -xo-init@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/xo-init/-/xo-init-0.7.0.tgz#634b4789e366b4f87f747ef0cee1a99ce273aa15" - integrity sha512-mrrCKMu52vz0u2tiOl8DoG709pBtnSp58bb4/j58a4jeXjrb1gV7dxfOBjOlXitYtfW2QnlxxxfAojoFcpynDg== - dependencies: - arrify "^1.0.0" - execa "^0.9.0" - has-yarn "^1.0.0" - minimist "^1.1.3" - path-exists "^3.0.0" - read-pkg-up "^3.0.0" - the-argv "^1.0.0" - write-pkg "^3.1.0" - -xo@0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/xo/-/xo-0.23.0.tgz#dbc709b0e5e38060a497a39d147a173ddd36d355" - integrity sha512-jyNZrGULm1oPgL0AMWWFWr3Q2cLsULrIkBsogIGWEUw/wGu47N3XGNmUwB4AvJcMhveNK2gqndY3+z8m0CJFEA== - dependencies: - arrify "^1.0.1" - debug "^3.1.0" - eslint "^5.5.0" - eslint-config-prettier "^3.0.1" - eslint-config-xo "^0.25.0" - eslint-formatter-pretty "^1.3.0" - eslint-plugin-ava "^5.1.0" - eslint-plugin-import "^2.14.0" - eslint-plugin-no-use-extend-native "^0.3.12" - eslint-plugin-node "^7.0.0" - eslint-plugin-prettier "^2.6.0" - eslint-plugin-promise "^4.0.0" - eslint-plugin-unicorn "^6.0.1" - get-stdin "^6.0.0" - globby "^8.0.0" - has-flag "^3.0.0" - lodash.isequal "^4.5.0" - lodash.mergewith "^4.6.1" - meow "^5.0.0" - multimatch "^2.1.0" - open-editor "^1.2.0" - path-exists "^3.0.0" - pkg-conf "^2.1.0" - prettier "^1.12.1" - resolve-cwd "^2.0.0" - resolve-from "^4.0.0" - semver "^5.5.0" - slash "^2.0.0" - update-notifier "^2.3.0" - xo-init "^0.7.0" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" From 5b9eab62c437570702a4c1c086228734c7a32e99 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Wed, 2 Jan 2019 10:49:34 -0800 Subject: [PATCH 29/62] move types to devdeps --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0b50030..c7adf77 100644 --- a/package.json +++ b/package.json @@ -26,11 +26,11 @@ }, "homepage": "https://github.com/snowjs/cli#readme", "dependencies": { - "@types/node": "10.12.18", "chalk": "2.4.1", "mri": "1.1.1" }, "devDependencies": { + "@types/node": "10.12.18", "husky": "1.3.1", "lint-staged": "8.1.0", "prettier": "1.15.3", From 8f0711eb92666da74c63b933e39cbd9f71dba828 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Wed, 2 Jan 2019 10:56:43 -0800 Subject: [PATCH 30/62] add watch script --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c7adf77..9c5d6c6 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "tsc && npm run build:typescript && npm run build:typescript", - "build:typescript": "tsc", + "build": "tsc", + "watch": "tsc --watch", "lint": "tslint -p . --format stylish" }, "bin": { From 95ab13ba2a019b32dc4e190dc9e6f0d82785fcb3 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Wed, 2 Jan 2019 10:57:07 -0800 Subject: [PATCH 31/62] change main --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9c5d6c6..c2007f3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@snowjs/cli", "version": "0.0.0", "description": "Self-hosted now deployments", - "main": "src/index.js", + "main": "dist/index.js", "engines": { "node": ">=8.0.0" }, @@ -13,7 +13,7 @@ "lint": "tslint -p . --format stylish" }, "bin": { - "snow": "src/index.js" + "snow": "dist/index.js" }, "repository": { "type": "git", From 5deadfe007e34ed4099a1208977ce2576c97a5ef Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Thu, 3 Jan 2019 22:48:40 -0500 Subject: [PATCH 32/62] add prettier (#1) --- package.json | 22 +- src/create.js | 66 ++++-- src/deploy.js | 15 +- src/domains.js | 7 +- src/index.js | 8 +- src/install.js | 78 ++++--- src/ip.js | 4 +- src/login.js | 14 +- src/logout.js | 14 +- src/ls.js | 4 +- src/remove.js | 4 +- src/scale.js | 20 +- src/secrets.js | 8 +- src/utils.js | 11 +- yarn.lock | 562 +++++++++++++++++++++++++++++++++++++++++++++++-- 15 files changed, 730 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index 8f42c9c..8933eb3 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,32 @@ "mri": "1.1.1" }, "devDependencies": { + "husky": "1.3.1", + "lint-staged": "8.1.0", + "prettier": "1.15.3", "xo": "0.23.0" }, "xo": { "rules": { "no-await-in-loop": 0 }, - "space": true + "space": true, + "extends": [ + "prettier" + ] + }, + "prettier": { + "singleQuote": true + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{js,json,css,md}": [ + "prettier --write", + "git add" + ] } } diff --git a/src/create.js b/src/create.js index 2fc1b40..e0d1e2d 100644 --- a/src/create.js +++ b/src/create.js @@ -1,7 +1,14 @@ const path = require('path'); -const {askForInput, confirm, logError, logInfo, pickOne, run} = require('./utils'); +const { + askForInput, + confirm, + logError, + logInfo, + pickOne, + run +} = require('./utils'); -module.exports = async function () { +module.exports = async function() { const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); @@ -20,7 +27,7 @@ module.exports = async function () { await run('minikube addons enable ingress'); await run('helm init --wait'); - const {stdout: minikubeIP} = await run('minikube ip'); + const { stdout: minikubeIP } = await run('minikube ip'); // Install traefik await run(` @@ -32,26 +39,34 @@ module.exports = async function () { --set dashboard.domain=traefik-ui.minikube `); const traefikHost = `${minikubeIP} traefik-ui.minikube`; - logInfo(`Add "${traefikHost}" to your hosts file to access traefik's dashboard.`); + logInfo( + `Add "${traefikHost}" to your hosts file to access traefik's dashboard.` + ); // Install docker registry await run('helm install stable/docker-registry'); if (await confirm('Install an example app on Minikube')) { - const deployFile = path.resolve(__dirname, '../config/deployment-minikube.yaml'); + const deployFile = path.resolve( + __dirname, + '../config/deployment-minikube.yaml' + ); await run(`kubectl apply -f ${deployFile}`); const whoAmIHost = `${minikubeIP} whoami.minikube`; - logInfo(`Add "${whoAmIHost}" to your hosts file to access example app.`); + logInfo( + `Add "${whoAmIHost}" to your hosts file to access example app.` + ); } - const completeMsg = 'Creation complete. It may take a few minutes for services to become available.'; + const completeMsg = + 'Creation complete. It may take a few minutes for services to become available.'; logInfo(completeMsg); break; } case 'gcp': { // Check if we need to authenticate. try { - const {stdout} = await run('gcloud auth list'); + const { stdout } = await run('gcloud auth list'); const isAuthenticated = stdout.indexOf('*') > -1; if (!isAuthenticated) { await run('gcloud auth login'); @@ -60,12 +75,16 @@ module.exports = async function () { await run('gcloud auth login'); } - const {stdout: projectId} = await run('gcloud config get-value project'); + const { stdout: projectId } = await run( + 'gcloud config get-value project' + ); await run('gcloud services enable container.googleapis.com'); // Check if we have an existing cluster let clusterExists = false; - const {stdout: clusterData} = await run('gcloud container clusters list'); + const { stdout: clusterData } = await run( + 'gcloud container clusters list' + ); if (clusterData.indexOf('snow-cluster') > -1) { clusterExists = true; } @@ -114,7 +133,8 @@ module.exports = async function () { basicConstraints=critical,CA:TRUE\\n subjectKeyIdentifier=hash\\n authorityKeyIdentifier=keyid:always,issuer:always`; - await run(` + await run( + ` openssl req \\ -config <(printf '${config}') \\ -key $(helm home)/ca.key.pem \\ @@ -124,22 +144,27 @@ module.exports = async function () { -sha256 \\ -out $(helm home)/ca.cert.pem \\ -extensions v3_ca \\ - -subj "/C=US"`, {shell: '/bin/bash'}); + -subj "/C=US"`, + { shell: '/bin/bash' } + ); // Create credentials for tiller (server) await run(`openssl genrsa -out $(helm home)/tiller.key.pem ${BYTES}`); - await run(` + await run( + ` openssl req \ -new \ -sha256 \ -key $(helm home)/tiller.key.pem \ -out $(helm home)/tiller.csr.pem \ -subj "/C=US/O=Snow/CN=tiller-server"`, - {shell: '/bin/bash'}); + { shell: '/bin/bash' } + ); const tillerConfig = ` [SAN]\\n subjectAltName=IP:127.0.0.1`; - await run(` + await run( + ` openssl x509 -req -days 365 \ -CA $(helm home)/ca.cert.pem \ -CAkey $(helm home)/ca.key.pem \ @@ -148,7 +173,8 @@ module.exports = async function () { -out $(helm home)/tiller.cert.pem \ -extfile <(printf '${tillerConfig}') \ -extensions SAN`, - {shell: '/bin/bash'}); + { shell: '/bin/bash' } + ); // Create credentials for helm (client) await run(`openssl genrsa -out $(helm home)/helm.key.pem ${BYTES}`); @@ -235,9 +261,11 @@ module.exports = async function () { --set ingressShim.defaultIssuerKind=ClusterIssuer `); - let email = await askForInput('Provide an email address for Let\'s Encrypt'); - while (!await confirm(`Confirm email: "${email}"`)) { - email = await askForInput('Provide an email address for Let\'s Encrypt'); + let email = await askForInput( + "Provide an email address for Let's Encrypt" + ); + while (!(await confirm(`Confirm email: "${email}"`))) { + email = await askForInput("Provide an email address for Let's Encrypt"); } // Create cluster issuer diff --git a/src/deploy.js b/src/deploy.js index f461ba9..0e9c5aa 100644 --- a/src/deploy.js +++ b/src/deploy.js @@ -1,9 +1,8 @@ - const path = require('path'); const chalk = require('chalk'); -const {exec, readFile, stat} = require('./utils'); +const { exec, readFile, stat } = require('./utils'); -module.exports = async function () { +module.exports = async function() { // First: Verify we have a Dockerfile. const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); try { @@ -26,7 +25,7 @@ module.exports = async function () { } // Third: Build and tag the image. - const {name} = nowConfig; + const { name } = nowConfig; if (!name) { console.log(chalk.red('Specify a "name" in now.json')); return; @@ -42,7 +41,9 @@ module.exports = async function () { // Fourth: Start a local Docker registry, if necessary. let registryRunning = true; try { - const {stdout} = await exec('docker ps --format "{{.Names}}" -f "name=registry"'); + const { stdout } = await exec( + 'docker ps --format "{{.Names}}" -f "name=registry"' + ); if (!stdout) { registryRunning = false; } @@ -52,7 +53,9 @@ module.exports = async function () { } if (!registryRunning) { try { - await exec('docker run -d -p 5000:5000 --restart=always --name registry registry:2'); + await exec( + 'docker run -d -p 5000:5000 --restart=always --name registry registry:2' + ); } catch (error) { console.log(`Could not start local Docker registry.\n${error.message}`); } diff --git a/src/domains.js b/src/domains.js index 5019b76..a5c442e 100644 --- a/src/domains.js +++ b/src/domains.js @@ -1,10 +1,11 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [subcommand] = args; if (!subcommand || subcommand === 'ls') { - const path = '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; + const path = + '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; await run(`kubectl get ingress -o jsonpath='${path}'`); } }; diff --git a/src/index.js b/src/index.js index 2df8d57..09afe30 100755 --- a/src/index.js +++ b/src/index.js @@ -12,10 +12,10 @@ const ls = require('./ls'); const remove = require('./remove'); const scale = require('./scale'); const secrets = require('./secrets'); -const {isRemove, logError} = require('./utils'); +const { isRemove, logError } = require('./utils'); async function main() { - const {_} = mri(process.argv.slice(2)); + const { _ } = mri(process.argv.slice(2)); const [command, ...rest] = _; switch (command) { @@ -63,7 +63,9 @@ async function main() { break; } default: { - const errMsg = `Error: Invalid command: snow ${command} ${rest.join(' ')}`; + const errMsg = `Error: Invalid command: snow ${command} ${rest.join( + ' ' + )}`; logError(errMsg); } } diff --git a/src/install.js b/src/install.js index e7473a2..dab1335 100644 --- a/src/install.js +++ b/src/install.js @@ -1,38 +1,46 @@ -const {confirm, run} = require('./utils'); +const { confirm, run } = require('./utils'); -module.exports = async function () { - const dependencies = [{ - label: 'Virtualbox', - detectCmd: 'which virtualbox', - installCmd: 'brew cask install virtualbox' - }, { - label: 'Docker', - detectCmd: 'which docker', - installCmd: 'brew cask install docker' - }, { - label: 'Kubernetes', - detectCmd: 'which kubectl', - installCmd: 'brew install kubernetes-cli' - }, { - label: 'Helm', - detectCmd: 'which helm', - installCmd: 'brew install kubernetes-helm' - }, { - label: 'Minikube', - detectCmd: 'which minikube', - installCmd: 'brew cask install minikube' - }, { - label: 'Google Cloud SDK (gcloud)', - detectCmd: 'which gcloud', - installCmd: 'brew cask install google-cloud-sdk' - }, { - label: 'Google Cloud SDK (gcloud) Beta Commands', - detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', - installCmd: 'gcloud components install beta --quiet', - detectAdvanced: output => { - return output.indexOf('Not Installed | gcloud Beta Commands') > -1; +module.exports = async function() { + const dependencies = [ + { + label: 'Virtualbox', + detectCmd: 'which virtualbox', + installCmd: 'brew cask install virtualbox' + }, + { + label: 'Docker', + detectCmd: 'which docker', + installCmd: 'brew cask install docker' + }, + { + label: 'Kubernetes', + detectCmd: 'which kubectl', + installCmd: 'brew install kubernetes-cli' + }, + { + label: 'Helm', + detectCmd: 'which helm', + installCmd: 'brew install kubernetes-helm' + }, + { + label: 'Minikube', + detectCmd: 'which minikube', + installCmd: 'brew cask install minikube' + }, + { + label: 'Google Cloud SDK (gcloud)', + detectCmd: 'which gcloud', + installCmd: 'brew cask install google-cloud-sdk' + }, + { + label: 'Google Cloud SDK (gcloud) Beta Commands', + detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', + installCmd: 'gcloud components install beta --quiet', + detectAdvanced: output => { + return output.indexOf('Not Installed | gcloud Beta Commands') > -1; + } } - }]; + ]; async function tryInstall(label, installCmd) { if (await confirm(`Install ${label}`)) { @@ -40,9 +48,9 @@ module.exports = async function () { } } - for (const {label, detectCmd, detectAdvanced, installCmd} of dependencies) { + for (const { label, detectCmd, detectAdvanced, installCmd } of dependencies) { try { - const {stdout} = await run(detectCmd); + const { stdout } = await run(detectCmd); if (detectAdvanced && detectAdvanced(stdout)) { tryInstall(label, installCmd); } diff --git a/src/ip.js b/src/ip.js index 9abda47..90c3373 100644 --- a/src/ip.js +++ b/src/ip.js @@ -1,6 +1,6 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function () { +module.exports = async function() { const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; await run(` kubectl get services/nginx-ingress-controller \ diff --git a/src/login.js b/src/login.js index 08b5245..ba0f509 100644 --- a/src/login.js +++ b/src/login.js @@ -1,6 +1,6 @@ -const {logError, pickOne, run} = require('./utils'); +const { logError, pickOne, run } = require('./utils'); -module.exports = async function () { +module.exports = async function() { const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider do you want to login to?'; const provider = await pickOne(question, cloudProviders); @@ -11,9 +11,13 @@ module.exports = async function () { } case 'gcp': { await run('gcloud auth login'); - const {stdout: clusterData} = await run('gcloud container clusters list --format="json"'); - const {location, name} = JSON.parse(clusterData)[0]; - await run(`gcloud container clusters get-credentials ${name} --zone "${location}"`); + const { stdout: clusterData } = await run( + 'gcloud container clusters list --format="json"' + ); + const { location, name } = JSON.parse(clusterData)[0]; + await run( + `gcloud container clusters get-credentials ${name} --zone "${location}"` + ); break; } default: { diff --git a/src/logout.js b/src/logout.js index d4b1740..7c8dd38 100644 --- a/src/logout.js +++ b/src/logout.js @@ -1,6 +1,6 @@ -const {logError, pickOne, run} = require('./utils'); +const { logError, pickOne, run } = require('./utils'); -module.exports = async function () { +module.exports = async function() { const question = 'Which cloud provider do you want to logout of'; const options = ['minikube', 'gcp']; const provider = await pickOne(question, options); @@ -10,9 +10,13 @@ module.exports = async function () { break; } case 'gcp': { - const {stdout: projectId} = await run('gcloud config get-value core/project'); - const {stdout: clusterData} = await run('gcloud container clusters list --format="json"'); - const {location, name} = JSON.parse(clusterData)[0]; + const { stdout: projectId } = await run( + 'gcloud config get-value core/project' + ); + const { stdout: clusterData } = await run( + 'gcloud container clusters list --format="json"' + ); + const { location, name } = JSON.parse(clusterData)[0]; const key = `gke_${projectId}_${location}_${name}`; await run(`kubectl config unset clusters.${key}`); await run(`kubectl config unset contexts.${key}`); diff --git a/src/ls.js b/src/ls.js index fd801cc..bfc81da 100644 --- a/src/ls.js +++ b/src/ls.js @@ -1,6 +1,6 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [deployment] = args; if (!deployment) { return run('kubectl get deployments'); diff --git a/src/remove.js b/src/remove.js index 5ed07cb..feeb9e7 100644 --- a/src/remove.js +++ b/src/remove.js @@ -1,6 +1,6 @@ -const {run} = require('./utils'); +const { run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [deployment] = args; await run(`kubectl delete deploy ${deployment}`); }; diff --git a/src/scale.js b/src/scale.js index cf797ea..e393109 100644 --- a/src/scale.js +++ b/src/scale.js @@ -1,6 +1,6 @@ -const {logError, run} = require('./utils'); +const { logError, run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [name, min, max] = args; if (!name) { return logError('name (required): snow scale [name]'); @@ -9,11 +9,15 @@ module.exports = async function (args) { return logError('min (required): snow scale [name] [min]'); } if (isNaN(Number(min))) { - return logError('min (typecheck: must be numberic): snow scale [name] [min]'); + return logError( + 'min (typecheck: must be numberic): snow scale [name] [min]' + ); } if (max && isNaN(Number(max))) { - return logError('max (typecheck: must be numberic): snow scale [name] [min] [max]'); + return logError( + 'max (typecheck: must be numberic): snow scale [name] [min] [max]' + ); } // If CLI called without 'max' supplied, default to 'min'. @@ -23,9 +27,13 @@ module.exports = async function (args) { try { await run(`kubectl get hpa ${name}`); // HPA exists. Patch it. - await run(`kubectl patch hpa ${name} --patch '{"spec":{"minReplicas":${min},"maxReplicas":${actualMax}}}'`); + await run( + `kubectl patch hpa ${name} --patch '{"spec":{"minReplicas":${min},"maxReplicas":${actualMax}}}'` + ); } catch (error) { // No HPA. Create one. - await run(`kubectl autoscale deployment/${name} --min=${min} --max=${actualMax}`); + await run( + `kubectl autoscale deployment/${name} --min=${min} --max=${actualMax}` + ); } }; diff --git a/src/secrets.js b/src/secrets.js index 31328de..09bdb99 100644 --- a/src/secrets.js +++ b/src/secrets.js @@ -1,12 +1,14 @@ -const {isRemove, run} = require('./utils'); +const { isRemove, run } = require('./utils'); -module.exports = async function (args) { +module.exports = async function(args) { const [action, key, value] = args; if (action === 'ls') { await run('kubectl get secrets'); } if (action === 'add') { - await run(`kubectl create secret generic ${key} --from-literal=${key}=${value}`); + await run( + `kubectl create secret generic ${key} --from-literal=${key}=${value}` + ); } if (isRemove(action)) { await run(`kubectl delete secret ${key}`); diff --git a/src/utils.js b/src/utils.js index e0a0f24..6388a1c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -27,7 +27,11 @@ function confirm(msg) { return new Promise(resolve => { function data(d) { process.stdin.pause(); - const isYes = d.toString().trim().toLowerCase() === 'y'; + const isYes = + d + .toString() + .trim() + .toLowerCase() === 'y'; if (!isYes) { console.log(`${chalk.grey('> ')} Aborted`); } @@ -61,7 +65,10 @@ function pickOne(msg, options) { process.stdout.write(`${question} (${options.join(',')}) ${prefixesStr} `); return new Promise(resolve => { function data(d) { - const input = d.toString().trim().toLowerCase(); + const input = d + .toString() + .trim() + .toLowerCase(); const index = prefixes.indexOf(input); const option = options[index]; process.stdin.removeListener('data', data).pause(); diff --git a/yarn.lock b/yarn.lock index 8dac550..a5de113 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,6 +18,20 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@iamstarkov/listr-update-renderer@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e" + integrity sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -31,6 +45,13 @@ resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + acorn-jsx@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz#958584ddb60990c02c97c1bd9d521fce433bb101" @@ -68,18 +89,33 @@ ansi-escapes@^3.0.0: resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-styles@^3.2.1: +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -229,6 +265,13 @@ call-me-maybe@^1.0.1: resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -236,11 +279,23 @@ caller-path@^0.1.0: dependencies: callsites "^0.2.0" +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + callsites@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -260,7 +315,7 @@ capture-stack-trace@^1.0.0: resolved "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== -chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: +chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== @@ -269,6 +324,17 @@ chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -279,6 +345,11 @@ ci-info@^1.5.0: resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" @@ -306,18 +377,31 @@ cli-boxes@^1.0.0: resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= -cli-cursor@^2.1.0: +cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -338,6 +422,11 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +commander@^2.14.1, commander@^2.9.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" @@ -383,6 +472,25 @@ core-js@^2.0.0: resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== +cosmiconfig@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +cosmiconfig@^5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" @@ -399,7 +507,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -422,6 +530,11 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -461,6 +574,11 @@ decode-uri-component@^0.2.0: resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -552,6 +670,18 @@ duplexer3@^0.1.4: resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + enhance-visitors@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz#aa945d05da465672a1ebd38fee2ed3da8518e95a" @@ -571,7 +701,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -850,6 +980,19 @@ execa@^0.9.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -933,6 +1076,14 @@ fast-levenshtein@~2.0.4: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + figures@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -958,6 +1109,11 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + find-up@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -973,6 +1129,13 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + flat-cache@^1.2.1: version "1.3.2" resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.2.tgz#7f852d70be573dac874a4c4129d340a34fba7e65" @@ -1010,6 +1173,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" + integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + get-set-props@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz#998475c178445686d0b32246da5df8dbcfbe8ea3" @@ -1025,6 +1202,13 @@ get-stream@^3.0.0: resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -1113,6 +1297,13 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1166,6 +1357,22 @@ hosted-git-info@^2.1.4: resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== +husky@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" + integrity sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg== + dependencies: + cosmiconfig "^5.0.7" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^2.0.0" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1183,6 +1390,14 @@ ignore@^4.0.2, ignore@^4.0.6: resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -1283,6 +1498,13 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -1315,6 +1537,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + is-error@^2.2.0: version "2.2.1" resolved "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" @@ -1337,6 +1564,13 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -1399,11 +1633,18 @@ is-obj-prop@^1.0.0: lowercase-keys "^1.0.0" obj-props "^1.0.0" -is-obj@^1.0.0: +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -1453,6 +1694,11 @@ is-redirect@^1.0.0: resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" @@ -1505,6 +1751,21 @@ jest-docblock@^21.0.0: resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== +jest-get-type@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== + +jest-validate@^23.5.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -1515,7 +1776,7 @@ js-types@^1.0.0: resolved "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz#d242e6494ed572ad3c92809fc8bed7f7687cbf03" integrity sha1-0kLmSU7Vcq08koCfyL7X92h8vwM= -js-yaml@^3.12.0: +js-yaml@^3.12.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -1569,6 +1830,11 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1582,6 +1848,81 @@ line-column-path@^1.0.0: resolved "https://registry.npmjs.org/line-column-path/-/line-column-path-1.0.0.tgz#383b83fca8488faa7a59940ebf28b82058c16c55" integrity sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU= +lint-staged@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" + integrity sha512-yfSkyJy7EuVsaoxtUSEhrD81spdJOe/gMTGea3XaV7HyoRhTb9Gdlp6/JppRZERvKSEYXP9bjcmq6CA5oL2lYQ== + dependencies: + "@iamstarkov/listr-update-renderer" "0.4.1" + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "5.0.6" + debug "^3.1.0" + dedent "^0.7.0" + del "^3.0.0" + execa "^1.0.0" + find-parent-dir "^0.3.0" + g-status "^2.0.2" + is-glob "^4.0.0" + is-windows "^1.0.2" + jest-validate "^23.5.0" + listr "^0.14.2" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.2" + string-argv "^0.0.2" + stringify-object "^3.2.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.2: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + load-json-file@^2.0.0: version "2.0.0" resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -1610,6 +1951,14 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash.camelcase@^4.1.1: version "4.3.0" resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -1655,13 +2004,29 @@ lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== -log-symbols@^2.0.0: +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^2.0.0, log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== dependencies: chalk "^2.0.1" +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -1712,6 +2077,13 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + meow@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" @@ -1732,7 +2104,7 @@ merge2@^1.2.3: resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== -micromatch@^3.1.10: +micromatch@^3.1.10, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -1863,6 +2235,13 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== + dependencies: + which "^1.2.10" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -1870,12 +2249,26 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + obj-props@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz#626313faa442befd4a44e9a02c3cb6bde937b511" integrity sha1-YmMT+qRCvv1KROmgLDy2vek3tRE= -object-assign@^4.0.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -1903,7 +2296,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -1962,6 +2355,13 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" + integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -1969,16 +2369,33 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-map@^1.1.1: version "1.2.0" resolved "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== +p-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" + integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== + p-try@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + package-json@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -2097,6 +2514,13 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" @@ -2104,6 +2528,13 @@ pkg-up@^2.0.0: dependencies: find-up "^2.1.0" +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + plur@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" @@ -2131,11 +2562,24 @@ prepend-http@^1.0.1: resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= +prettier@1.15.3: + version "1.15.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" + integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== + prettier@^1.12.1: version "1.15.2" resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + progress@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" @@ -2151,6 +2595,14 @@ pseudomap@^1.0.2: resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2205,6 +2657,15 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + redent@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" @@ -2320,7 +2781,12 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" -rxjs@^6.1.0: +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + +rxjs@^6.1.0, rxjs@^6.3.3: version "6.3.3" resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== @@ -2344,6 +2810,11 @@ safe-regex@^1.1.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -2393,6 +2864,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-git@^1.85.0: + version "1.107.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.107.0.tgz#12cffaf261c14d6f450f7fdb86c21ccee968b383" + integrity sha512-t4OK1JRlp4ayKRfcW6owrWcRVLyHRUlhGd0uN6ZZTqfDq8a5XpcUdOKiGRNobHEuMtNqzp0vcJNvhYWwh5PsQA== + dependencies: + debug "^4.0.1" + slash@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -2403,6 +2881,11 @@ slash@^2.0.0: resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" @@ -2506,6 +2989,11 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -2514,6 +3002,20 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -2522,6 +3024,22 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +stringify-object@^3.2.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -2549,6 +3067,11 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2556,6 +3079,11 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + table@^5.0.2: version "5.1.0" resolved "https://registry.npmjs.org/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" @@ -2720,7 +3248,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -which@^1.2.9: +which@^1.2.10, which@^1.2.9: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -2739,6 +3267,14 @@ wordwrap@~1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From 308ea2b1450ae1492083939a73b59600156fa0f3 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Thu, 3 Jan 2019 20:13:19 -0800 Subject: [PATCH 33/62] [utils.js] fix compilation error --- src/utils.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 5b99869..287bb46 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -92,9 +92,7 @@ export async function pickOne(msg: string, options: string[]) { export async function run( str: string, - opts?: { - encoding: 'buffer' | null; - } & childProcess.ExecOptions + opts?: childProcess.ExecOptions ) { const runString = str.replace(/(\s+)/gm, ' ').trim(); @@ -103,8 +101,8 @@ export async function run( return new Promise((resolve, reject) => { function callback( error: childProcess.ExecException | null, - stdout: string, - stderr: string + stdout: string | Buffer, + stderr: string | Buffer ) { if (error) { process.stderr.write(chalk.red(error.message)); @@ -117,8 +115,8 @@ export async function run( } return resolve({ - stdout: stdout.trim(), - stderr: stderr.trim() + stdout: stdout.toString().trim(), + stderr: stderr.toString().trim() }); } From 34a540644c8c7149022e48a7edd775d863e1828f Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Thu, 3 Jan 2019 21:24:13 -0800 Subject: [PATCH 34/62] [src] javascript => typescript --- package.json | 1 + src/{create.js => create.ts} | 8 ++-- src/{deploy.js => deploy.ts} | 8 ++-- src/{domains.js => domains.ts} | 4 +- src/index.js | 74 --------------------------------- src/index.ts | 75 ++++++++++++++++++++++++++++++++++ src/{install.js => install.ts} | 17 +++++--- src/{ip.js => ip.ts} | 4 +- src/{login.js => login.ts} | 14 +++---- src/{logout.js => logout.ts} | 10 ++--- src/{ls.js => ls.ts} | 5 +-- src/remove.js | 6 --- src/remove.ts | 8 ++++ src/{scale.js => scale.ts} | 13 +++--- src/secrets.ts | 17 ++++---- src/utils.ts | 11 +++-- yarn.lock | 5 +++ 17 files changed, 148 insertions(+), 132 deletions(-) rename src/{create.js => create.ts} (98%) rename src/{deploy.js => deploy.ts} (92%) rename src/{domains.js => domains.ts} (78%) delete mode 100755 src/index.js create mode 100755 src/index.ts rename src/{install.js => install.ts} (80%) rename src/{ip.js => ip.ts} (73%) rename src/{login.js => login.ts} (50%) rename src/{logout.js => logout.ts} (70%) rename src/{ls.js => ls.ts} (54%) delete mode 100644 src/remove.js create mode 100644 src/remove.ts rename src/{scale.js => scale.ts} (63%) diff --git a/package.json b/package.json index c2007f3..24f2f53 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "mri": "1.1.1" }, "devDependencies": { + "@types/mri": "1.1.0", "@types/node": "10.12.18", "husky": "1.3.1", "lint-staged": "8.1.0", diff --git a/src/create.js b/src/create.ts similarity index 98% rename from src/create.js rename to src/create.ts index e0d1e2d..dd64abd 100644 --- a/src/create.js +++ b/src/create.ts @@ -1,14 +1,14 @@ -const path = require('path'); -const { +import * as path from 'path'; +import { askForInput, confirm, logError, logInfo, pickOne, run -} = require('./utils'); +} from './utils'; -module.exports = async function() { +export default async function() { const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); diff --git a/src/deploy.js b/src/deploy.ts similarity index 92% rename from src/deploy.js rename to src/deploy.ts index 0e9c5aa..e4ea97e 100644 --- a/src/deploy.js +++ b/src/deploy.ts @@ -1,8 +1,8 @@ -const path = require('path'); -const chalk = require('chalk'); -const { exec, readFile, stat } = require('./utils'); +import * as path from 'path'; +import chalk from 'chalk'; +import {exec, readFile, stat} from './utils'; -module.exports = async function() { +export default async function() { // First: Verify we have a Dockerfile. const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); try { diff --git a/src/domains.js b/src/domains.ts similarity index 78% rename from src/domains.js rename to src/domains.ts index a5c442e..18913f0 100644 --- a/src/domains.js +++ b/src/domains.ts @@ -1,8 +1,6 @@ const { run } = require('./utils'); -module.exports = async function(args) { - const [subcommand] = args; - +export default async function(subcommand?: string) { if (!subcommand || subcommand === 'ls') { const path = '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; diff --git a/src/index.js b/src/index.js deleted file mode 100755 index 09afe30..0000000 --- a/src/index.js +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env node - -const mri = require('mri'); -const create = require('./create'); -const deploy = require('./deploy'); -const domains = require('./domains'); -const install = require('./install'); -const ip = require('./ip'); -const login = require('./login'); -const logout = require('./logout'); -const ls = require('./ls'); -const remove = require('./remove'); -const scale = require('./scale'); -const secrets = require('./secrets'); -const { isRemove, logError } = require('./utils'); - -async function main() { - const { _ } = mri(process.argv.slice(2)); - const [command, ...rest] = _; - - switch (command) { - case 'create': { - await create(rest); - break; - } - case undefined: - case 'deploy': { - await deploy(rest); - break; - } - case 'domains': { - await domains(rest); - break; - } - case 'install': { - await install(rest); - break; - } - case 'ip': { - await ip(rest); - break; - } - case 'login': - await login(rest); - break; - case 'logout': - await logout(rest); - break; - case 'ls': { - await ls(rest); - break; - } - case isRemove(command): { - await remove(rest); - break; - } - case 'scale': { - await scale(rest); - break; - } - case 'secrets': { - await secrets(rest); - break; - } - default: { - const errMsg = `Error: Invalid command: snow ${command} ${rest.join( - ' ' - )}`; - logError(errMsg); - } - } -} - -main(); diff --git a/src/index.ts b/src/index.ts new file mode 100755 index 0000000..6b131ed --- /dev/null +++ b/src/index.ts @@ -0,0 +1,75 @@ +#!/usr/bin/env node + +import * as mri from 'mri'; +import create from './create'; +import deploy from './deploy'; +import domains from './domains'; +import install from './install'; +import ip from './ip'; +import login from './login'; +import logout from './logout'; +import ls from './ls'; +import remove from './remove'; +import scale from './scale'; +import secrets from './secrets'; +import { logError } from './utils'; + +async function main() { + const { _ } = mri(process.argv.slice(2)); + const [command, ...rest] = _; + + switch (command) { + case 'create': { + await create(); + break; + } + case undefined: + case 'deploy': { + await deploy(); + break; + } + case 'domains': { + await domains(rest[0]); + break; + } + case 'install': { + await install(); + break; + } + case 'ip': { + await ip(); + break; + } + case 'login': + await login(); + break; + case 'logout': + await logout(); + break; + case 'ls': { + await ls(); + break; + } + case 'remove': + case 'rm': { + await remove(rest[0]); + break; + } + case 'scale': { + await scale(...rest); + break; + } + case 'secrets': { + await secrets(...rest); + break; + } + default: { + const errMsg = `Error: Invalid command: snow ${command} ${rest.join( + ' ' + )}`; + logError(errMsg); + } + } +} + +main(); diff --git a/src/install.js b/src/install.ts similarity index 80% rename from src/install.js rename to src/install.ts index dab1335..83f32ce 100644 --- a/src/install.js +++ b/src/install.ts @@ -1,7 +1,14 @@ -const { confirm, run } = require('./utils'); +import {confirm, run} from './utils'; -module.exports = async function() { - const dependencies = [ +export default async function() { + type IDependency = { + label: string, + detectCmd: string, + installCmd: string, + detectAdvanced?: Function + }; + + const dependencies: IDependency[] = [ { label: 'Virtualbox', detectCmd: 'which virtualbox', @@ -36,13 +43,13 @@ module.exports = async function() { label: 'Google Cloud SDK (gcloud) Beta Commands', detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', installCmd: 'gcloud components install beta --quiet', - detectAdvanced: output => { + detectAdvanced: (output: string) => { return output.indexOf('Not Installed | gcloud Beta Commands') > -1; } } ]; - async function tryInstall(label, installCmd) { + async function tryInstall(label: string, installCmd: string) { if (await confirm(`Install ${label}`)) { await run(installCmd); } diff --git a/src/ip.js b/src/ip.ts similarity index 73% rename from src/ip.js rename to src/ip.ts index 90c3373..9df3b3c 100644 --- a/src/ip.js +++ b/src/ip.ts @@ -1,6 +1,6 @@ -const { run } = require('./utils'); +import { run } from './utils'; -module.exports = async function() { +export default async function() { const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; await run(` kubectl get services/nginx-ingress-controller \ diff --git a/src/login.js b/src/login.ts similarity index 50% rename from src/login.js rename to src/login.ts index ba0f509..0204e73 100644 --- a/src/login.js +++ b/src/login.ts @@ -1,9 +1,9 @@ -const { logError, pickOne, run } = require('./utils'); +import { logError, pickOne, run } from './utils'; -module.exports = async function() { - const cloudProviders = ['minikube', 'gcp']; - const question = 'Which cloud provider do you want to login to?'; - const provider = await pickOne(question, cloudProviders); +export default async function() { + const cloudProviders: string[] = ['minikube', 'gcp']; + const question: string = 'Which cloud provider do you want to login to?'; + const provider: string = await pickOne(question, cloudProviders); switch (provider) { case 'minikube': { await run('kubectl config use-context minikube'); @@ -11,10 +11,10 @@ module.exports = async function() { } case 'gcp': { await run('gcloud auth login'); - const { stdout: clusterData } = await run( + const { stdout: clusterData }: {stdout: string} = await run( 'gcloud container clusters list --format="json"' ); - const { location, name } = JSON.parse(clusterData)[0]; + const { location, name }: {location: string, name: string} = JSON.parse(clusterData)[0]; await run( `gcloud container clusters get-credentials ${name} --zone "${location}"` ); diff --git a/src/logout.js b/src/logout.ts similarity index 70% rename from src/logout.js rename to src/logout.ts index 7c8dd38..1496f98 100644 --- a/src/logout.js +++ b/src/logout.ts @@ -1,6 +1,6 @@ -const { logError, pickOne, run } = require('./utils'); +import { logError, pickOne, run } from './utils'; -module.exports = async function() { +export default async function() { const question = 'Which cloud provider do you want to logout of'; const options = ['minikube', 'gcp']; const provider = await pickOne(question, options); @@ -10,13 +10,13 @@ module.exports = async function() { break; } case 'gcp': { - const { stdout: projectId } = await run( + const { stdout: projectId } : {stdout: string} = await run( 'gcloud config get-value core/project' ); - const { stdout: clusterData } = await run( + const { stdout: clusterData } : {stdout: string} = await run( 'gcloud container clusters list --format="json"' ); - const { location, name } = JSON.parse(clusterData)[0]; + const { location, name } : {location: string, name: string} = JSON.parse(clusterData)[0]; const key = `gke_${projectId}_${location}_${name}`; await run(`kubectl config unset clusters.${key}`); await run(`kubectl config unset contexts.${key}`); diff --git a/src/ls.js b/src/ls.ts similarity index 54% rename from src/ls.js rename to src/ls.ts index bfc81da..ea0a30e 100644 --- a/src/ls.js +++ b/src/ls.ts @@ -1,7 +1,6 @@ -const { run } = require('./utils'); +import { run } from './utils'; -module.exports = async function(args) { - const [deployment] = args; +export default async function(deployment?: string) { if (!deployment) { return run('kubectl get deployments'); } diff --git a/src/remove.js b/src/remove.js deleted file mode 100644 index feeb9e7..0000000 --- a/src/remove.js +++ /dev/null @@ -1,6 +0,0 @@ -const { run } = require('./utils'); - -module.exports = async function(args) { - const [deployment] = args; - await run(`kubectl delete deploy ${deployment}`); -}; diff --git a/src/remove.ts b/src/remove.ts new file mode 100644 index 0000000..7d3614a --- /dev/null +++ b/src/remove.ts @@ -0,0 +1,8 @@ +import { logError, run } from './utils'; + +export default async function(deployment?: string) { + if (!deployment) { + return logError('No deployment specified.'); + } + await run(`kubectl delete deploy ${deployment}`); +}; diff --git a/src/scale.js b/src/scale.ts similarity index 63% rename from src/scale.js rename to src/scale.ts index e393109..bd2fe67 100644 --- a/src/scale.js +++ b/src/scale.ts @@ -1,22 +1,21 @@ -const { logError, run } = require('./utils'); +import {logError, run} from './utils'; -module.exports = async function(args) { - const [name, min, max] = args; +export default async function(name?: string, min?: string, max?: string) { if (!name) { - return logError('name (required): snow scale [name]'); + return logError('name (required): snow scale '); } if (!min) { - return logError('min (required): snow scale [name] [min]'); + return logError('min (required): snow scale '); } if (isNaN(Number(min))) { return logError( - 'min (typecheck: must be numberic): snow scale [name] [min]' + 'min (typecheck: must be numberic): snow scale ' ); } if (max && isNaN(Number(max))) { return logError( - 'max (typecheck: must be numberic): snow scale [name] [min] [max]' + 'max (typecheck: must be numberic): snow scale ' ); } diff --git a/src/secrets.ts b/src/secrets.ts index aa291b2..4925e3a 100644 --- a/src/secrets.ts +++ b/src/secrets.ts @@ -1,21 +1,20 @@ -import { isRemove, run } from './utils'; +import { isRemove, logError, run } from './utils'; -type ISecret = [string, string, string]; - -export default async function secrets(args: ISecret) { - const [action, key, value] = args; - - if (action === 'ls') { +export default async function secrets(subcommand?: string, key?: string, value?: string) { + if (subcommand === 'ls') { await run('kubectl get secrets'); } - if (action === 'add') { + if (subcommand === 'add') { + if (!key || !value) { + return logError('Key or value missing. Usage: now secrets add ') + } await run( `kubectl create secret generic ${key} --from-literal=${key}=${value}` ); } - if (isRemove(action)) { + if (isRemove(subcommand)) { await run(`kubectl delete secret ${key}`); } } diff --git a/src/utils.ts b/src/utils.ts index 287bb46..23840c2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -52,7 +52,7 @@ export async function confirm(msg: string) { }); } -export function isRemove(str: string) { +export function isRemove(str: string | undefined) { return str === 'rm' || str === 'remove'; } @@ -68,7 +68,7 @@ export function logInfo(msg: string) { console.log(chalk.bold.white(msg)); } -export async function pickOne(msg: string, options: string[]) { +export async function pickOne(msg: string, options: string[]) : Promise { const question = chalk.bold.red(`> ${msg}?`); const prefixes = options.map(option => option.charAt(0)); const prefixesStr = chalk.gray(`[${prefixes.join(',')}]`); @@ -90,10 +90,15 @@ export async function pickOne(msg: string, options: string[]) { }); } +type IRunResolve = { + stdout: string, + stderr: string +}; + export async function run( str: string, opts?: childProcess.ExecOptions -) { +) : Promise { const runString = str.replace(/(\s+)/gm, ' ').trim(); logInfo(`> ${runString}`); diff --git a/yarn.lock b/yarn.lock index 0fe6dbf..6ef70ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,6 +42,11 @@ dependencies: any-observable "^0.3.0" +"@types/mri@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@types/mri/-/mri-1.1.0.tgz#66555e4d797713789ea0fefdae0898d8170bf5af" + integrity sha512-fMl88ZoZXOB7VKazJ6wUMpZc9QIn+jcigSFRf2K/rrw4DcXn+/uGxlWX8DDlcE7JkwgIZ7BDH+JgxZPlc/Ap3g== + "@types/node@10.12.18": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" From fc489af89d953187d7c189fa6376808fd31f8f0a Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Thu, 3 Jan 2019 22:10:27 -0800 Subject: [PATCH 35/62] [src] resolve linter errs --- src/create.ts | 14 ++++++++------ src/deploy.ts | 23 +++++++++++++---------- src/domains.ts | 16 ++++++++++------ src/index.ts | 1 + src/install.ts | 20 ++++++++++---------- src/ip.ts | 2 +- src/login.ts | 12 ++++++------ src/logout.ts | 2 +- src/ls.ts | 2 +- src/remove.ts | 2 +- src/scale.ts | 2 +- src/secrets.ts | 5 +++-- src/utils.ts | 8 ++++---- tslint.json | 2 ++ 14 files changed, 62 insertions(+), 49 deletions(-) diff --git a/src/create.ts b/src/create.ts index dd64abd..811e429 100644 --- a/src/create.ts +++ b/src/create.ts @@ -8,7 +8,7 @@ import { run } from './utils'; -export default async function() { +export default async () => { const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); @@ -117,8 +117,10 @@ export default async function() { await run(createClusterCmd); } - // Install helm with TLS. - // https://medium.com/google-cloud/install-secure-helm-in-gke-254d520061f7 + /* + * Install helm with TLS. + * https://medium.com/google-cloud/install-secure-helm-in-gke-254d520061f7 + */ const BYTES = 2048; @@ -235,7 +237,7 @@ export default async function() { * --tls-key $(helm home)/helm.key.pem */ - // install nginx ingress + // Install nginx ingress await run(` helm install stable/nginx-ingress \ --tls \ @@ -262,10 +264,10 @@ export default async function() { `); let email = await askForInput( - "Provide an email address for Let's Encrypt" + 'Provide an email address for Let\'s Encrypt' ); while (!(await confirm(`Confirm email: "${email}"`))) { - email = await askForInput("Provide an email address for Let's Encrypt"); + email = await askForInput('Provide an email address for Let\'s Encrypt'); } // Create cluster issuer diff --git a/src/deploy.ts b/src/deploy.ts index e4ea97e..f77d6ce 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -1,8 +1,8 @@ -import * as path from 'path'; import chalk from 'chalk'; +import * as path from 'path'; import {exec, readFile, stat} from './utils'; -export default async function() { +export default async () => { // First: Verify we have a Dockerfile. const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); try { @@ -51,14 +51,17 @@ export default async function() { console.log(`Could not determine if registry started.\n${error.message}`); return; } - if (!registryRunning) { - try { - await exec( - 'docker run -d -p 5000:5000 --restart=always --name registry registry:2' - ); - } catch (error) { - console.log(`Could not start local Docker registry.\n${error.message}`); - } + + if (registryRunning) { + return; + } + + try { + await exec( + 'docker run -d -p 5000:5000 --restart=always --name registry registry:2' + ); + } catch (error) { + console.log(`Could not start local Docker registry.\n${error.message}`); } // Fifth: Push image to local registry. diff --git a/src/domains.ts b/src/domains.ts index 18913f0..f1b7532 100644 --- a/src/domains.ts +++ b/src/domains.ts @@ -1,9 +1,13 @@ -const { run } = require('./utils'); +import { run } from './utils'; -export default async function(subcommand?: string) { - if (!subcommand || subcommand === 'ls') { - const path = - '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; - await run(`kubectl get ingress -o jsonpath='${path}'`); +export default async (subcommand?: string) => { + const isLs = !subcommand || subcommand === 'ls'; + + if (!isLs) { + return; } + + const path = + '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; + await run(`kubectl get ingress -o jsonpath='${path}'`); }; diff --git a/src/index.ts b/src/index.ts index 6b131ed..39ee6e3 100755 --- a/src/index.ts +++ b/src/index.ts @@ -72,4 +72,5 @@ async function main() { } } +// tslint:disable-next-line:no-floating-promises main(); diff --git a/src/install.ts b/src/install.ts index 83f32ce..188ad13 100644 --- a/src/install.ts +++ b/src/install.ts @@ -1,12 +1,12 @@ import {confirm, run} from './utils'; -export default async function() { - type IDependency = { - label: string, - detectCmd: string, - installCmd: string, - detectAdvanced?: Function - }; +export default async () => { + interface IDependency { + label: string; + detectCmd: string; + installCmd: string; + detectAdvanced?(output: string): boolean; + } const dependencies: IDependency[] = [ { @@ -43,7 +43,7 @@ export default async function() { label: 'Google Cloud SDK (gcloud) Beta Commands', detectCmd: 'gcloud components list --filter="gcloud Beta Commands"', installCmd: 'gcloud components install beta --quiet', - detectAdvanced: (output: string) => { + detectAdvanced: output => { return output.indexOf('Not Installed | gcloud Beta Commands') > -1; } } @@ -59,10 +59,10 @@ export default async function() { try { const { stdout } = await run(detectCmd); if (detectAdvanced && detectAdvanced(stdout)) { - tryInstall(label, installCmd); + await tryInstall(label, installCmd); } } catch (error) { - tryInstall(label, installCmd); + await tryInstall(label, installCmd); } } }; diff --git a/src/ip.ts b/src/ip.ts index 9df3b3c..5b41052 100644 --- a/src/ip.ts +++ b/src/ip.ts @@ -1,6 +1,6 @@ import { run } from './utils'; -export default async function() { +export default async () => { const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; await run(` kubectl get services/nginx-ingress-controller \ diff --git a/src/login.ts b/src/login.ts index 0204e73..f9ea468 100644 --- a/src/login.ts +++ b/src/login.ts @@ -1,9 +1,9 @@ import { logError, pickOne, run } from './utils'; -export default async function() { - const cloudProviders: string[] = ['minikube', 'gcp']; - const question: string = 'Which cloud provider do you want to login to?'; - const provider: string = await pickOne(question, cloudProviders); +export default async () => { + const cloudProviders = ['minikube', 'gcp']; + const question = 'Which cloud provider do you want to login to'; + const provider = await pickOne(question, cloudProviders); switch (provider) { case 'minikube': { await run('kubectl config use-context minikube'); @@ -11,10 +11,10 @@ export default async function() { } case 'gcp': { await run('gcloud auth login'); - const { stdout: clusterData }: {stdout: string} = await run( + const { stdout: clusterData } = await run( 'gcloud container clusters list --format="json"' ); - const { location, name }: {location: string, name: string} = JSON.parse(clusterData)[0]; + const { location, name } = JSON.parse(clusterData)[0]; await run( `gcloud container clusters get-credentials ${name} --zone "${location}"` ); diff --git a/src/logout.ts b/src/logout.ts index 2c1649b..5f2530f 100644 --- a/src/logout.ts +++ b/src/logout.ts @@ -1,6 +1,6 @@ import { logError, pickOne, run } from './utils'; -export default async function() { +export default async () => { const question = 'Which cloud provider do you want to logout of'; const options = ['minikube', 'gcp']; const provider = await pickOne(question, options); diff --git a/src/ls.ts b/src/ls.ts index ea0a30e..f5dd61c 100644 --- a/src/ls.ts +++ b/src/ls.ts @@ -1,6 +1,6 @@ import { run } from './utils'; -export default async function(deployment?: string) { +export default async (deployment?: string) => { if (!deployment) { return run('kubectl get deployments'); } diff --git a/src/remove.ts b/src/remove.ts index 7d3614a..d8f1bd1 100644 --- a/src/remove.ts +++ b/src/remove.ts @@ -1,6 +1,6 @@ import { logError, run } from './utils'; -export default async function(deployment?: string) { +export default async (deployment?: string) => { if (!deployment) { return logError('No deployment specified.'); } diff --git a/src/scale.ts b/src/scale.ts index bd2fe67..4500bdd 100644 --- a/src/scale.ts +++ b/src/scale.ts @@ -1,6 +1,6 @@ import {logError, run} from './utils'; -export default async function(name?: string, min?: string, max?: string) { +export default async (name?: string, min?: string, max?: string) => { if (!name) { return logError('name (required): snow scale '); } diff --git a/src/secrets.ts b/src/secrets.ts index 4925e3a..71c0287 100644 --- a/src/secrets.ts +++ b/src/secrets.ts @@ -1,13 +1,14 @@ import { isRemove, logError, run } from './utils'; export default async function secrets(subcommand?: string, key?: string, value?: string) { - if (subcommand === 'ls') { + if (!subcommand || subcommand === 'ls') { await run('kubectl get secrets'); + return; } if (subcommand === 'add') { if (!key || !value) { - return logError('Key or value missing. Usage: now secrets add ') + return logError('Key or value missing. Usage: now secrets add '); } await run( `kubectl create secret generic ${key} --from-literal=${key}=${value}` diff --git a/src/utils.ts b/src/utils.ts index 23840c2..c4243e4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -90,10 +90,10 @@ export async function pickOne(msg: string, options: string[]) : Promise }); } -type IRunResolve = { - stdout: string, - stderr: string -}; +interface IRunResolve { + stdout: string; + stderr: string; +} export async function run( str: string, diff --git a/tslint.json b/tslint.json index 6f69590..0977773 100644 --- a/tslint.json +++ b/tslint.json @@ -7,11 +7,13 @@ ], "jsRules": { "no-console": false, + "no-unused": false, "object-literal-sort-keys": false, "object-curly-spacing": false }, "rules": { "no-console": false, + "no-unused": false, "object-literal-sort-keys": false, "object-curly-spacing": false }, From dbc5943962544b3607e5350f0ffb461197513824 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Thu, 3 Jan 2019 22:12:22 -0800 Subject: [PATCH 36/62] update README --- README.md | 81 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 579d0cc..4d73d13 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,15 @@ -> :snowflake: **S**elf-hosted **now** deployments +> :snowflake: **S**elf-hosted **now** deployments Enjoy effortless deployments with a clone of [now][now] on a cloud of your choosing. ### Features - - ⚡️ Deploy docker images via `snow` (or `snow deploy`) - - 🔒 Auto-configured SSL - - 🔃 Auto-scaling + +- ⚡️ Deploy docker images via `snow` (or `snow deploy`) +- 🔒 Auto-configured SSL +- 🔃 Auto-scaling ### This is Magic 🔮 @@ -34,28 +35,27 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c ### Supported commands -| Support | Command | Description | -|--------------------|-----------------------------|-------------------| -| :x: | \ | Create deployment | -| :x: | `alias` | Alias deployment | -| :x: | `deploy` | Deploy | -| :white_check_mark: | `domains` | List domains | -| :x: | `domains add [domain]` | Add domain | -| :x: | `domains rm [domain]` | Remove domain | -| :white_check_mark: | `login` | Login | -| :white_check_mark: | `logout` | Logout | -| :white_check_mark: | `ls` | List deployments | -| :white_check_mark: | `rm [name]` | Remove deployment | -| :white_check_mark: | `scale [name] [min]` | Scale deployment | -| :white_check_mark: | `scale [name] [min] [max]` | Scale deployment | -| :white_check_mark: | `secrets ls` | List secrets | -| :white_check_mark: | `secrets add [key] [value]` | Create secret | -| :white_check_mark: | `secrets rm [key]` | Remove secret | +| Support | Command | Description | +| ------------------ | ---------------------------- | ----------------- | +| :x: | \ | Create deployment | +| :x: | `alias` | Alias deployment | +| :x: | `deploy` | Deploy | +| :white_check_mark: | `domains [ls]` | List domains | +| :x: | `domains add ` | Add domain | +| :x: | `domains rm ` | Remove domain | +| :white_check_mark: | `login` | Login | +| :white_check_mark: | `logout` | Logout | +| :white_check_mark: | `ls` | List deployments | +| :white_check_mark: | `rm ` | Remove deployment | +| :white_check_mark: | `scale []` | Scale deployment | +| :white_check_mark: | `secrets [ls]` | List secrets | +| :white_check_mark: | `secrets add ` | Create secret | +| :white_check_mark: | `secrets rm ` | Remove secret | ### New commands | Command | Description | -|----------|---------------------------------| +| -------- | ------------------------------- | | `create` | Run once to create cluster | | `ip` | Get IP Address of Load Balancer | @@ -69,16 +69,16 @@ snow create Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. Here's what happens when you run `snow create`: - - You are authenticated to the cloud provider of your choosing. - - A Kubernetes cluster is created. - - [tiller][helm] is installed, which is used to install: - - [cert-manager] - - Will automatically watch your deployments and request new certificates for hostnames. - - Request new certificates when they're closing to expiring and seamlessly update in production. - - [ingress-nginx] - - Used for mapping hostnames to deployments. - - All HTTP traffic is permanently redirected (HTTP 308) to HTTPS. - - SSL terminiation occurs prior to requests reaching deployments. +- You are authenticated to the cloud provider of your choosing. +- A Kubernetes cluster is created. +- [tiller][helm] is installed, which is used to install: + - [cert-manager] + - Will automatically watch your deployments and request new certificates for hostnames. + - Request new certificates when they're closing to expiring and seamlessly update in production. + - [ingress-nginx] + - Used for mapping hostnames to deployments. + - All HTTP traffic is permanently redirected (HTTP 308) to HTTPS. + - SSL terminiation occurs prior to requests reaching deployments. ``` snow deploy @@ -105,16 +105,17 @@ Example `now.json`: The deployment process: - - The files listed in `now.json` plus `Dockerfile` (collectively referred to as the "build context") are assembled into a tar archive. - - [Kaniko] creates a Docker image from the build context, and pushes it to the private Docker registry in your Kubernetes cluster. - - A Kubernetes `deployment` resource is created for your image. - - A Kubernetes `service` resource exposes your deployment. - - A Kubernetes `ingress` resource maps hostnames (listed as `alias` array in now.json) to the service. - - [cert-manager] continually inspects ingresses, so if a deployment needs SSL certificates, they will be generated upon deployment. +- The files listed in `now.json` plus `Dockerfile` (collectively referred to as the "build context") are assembled into a tar archive. +- [Kaniko] creates a Docker image from the build context, and pushes it to the private Docker registry in your Kubernetes cluster. +- A Kubernetes `deployment` resource is created for your image. +- A Kubernetes `service` resource exposes your deployment. +- A Kubernetes `ingress` resource maps hostnames (listed as `alias` array in now.json) to the service. +- [cert-manager] continually inspects ingresses, so if a deployment needs SSL certificates, they will be generated upon deployment. For your domain name to be resolvable by Kubernetes, you **must**: - - create a DNS `A` record, which points to the IP Address of your load balancer (which can be found via `snow ip`). - - Alias the domain name to a deployment. + +- create a DNS `A` record, which points to the IP Address of your load balancer (which can be found via `snow ip`). +- Alias the domain name to a deployment. ### Dependencies From 1839557f6420ab9f5329c134908da8e62980f191 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Thu, 3 Jan 2019 22:13:46 -0800 Subject: [PATCH 37/62] update README --- README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4d73d13..a9d2927 100644 --- a/README.md +++ b/README.md @@ -90,16 +90,11 @@ Your now.json file **must** minimally specify `name` and `files`. The `alias` pr Example `now.json`: -``` +```json { "name": "myapp", - "alias": [ - "api.myapp.com", - "myapp.com" - ], - "files": [ - "server.js" - ] + "alias": ["api.myapp.com", "myapp.com"], + "files": ["server.js"] } ``` From 8cf692269c95433feffb56b209e041de28f83ab2 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Thu, 3 Jan 2019 22:16:32 -0800 Subject: [PATCH 38/62] update README --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a9d2927..21b17f8 100644 --- a/README.md +++ b/README.md @@ -84,15 +84,11 @@ Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. Here's wh snow deploy ``` -Also aliased as `snow`. Your current directory must have both `Dockerfile` and `now.json` files. - -Your now.json file **must** minimally specify `name` and `files`. The `alias` property is optional. - -Example `now.json`: +Also aliased as `snow`. Your current directory must have both `Dockerfile` and `now.json` files. Example `now.json`: ```json { - "name": "myapp", + "name": "myapp", // required "alias": ["api.myapp.com", "myapp.com"], "files": ["server.js"] } From cf4d1e4c01ae3c8d26b7b6446e12840c96437b8c Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Fri, 4 Jan 2019 21:35:35 -0800 Subject: [PATCH 39/62] [domains] add, rm functionality & docs --- README.md | 30 +++++++++- src/create.ts | 24 ++++++++ src/domains.ts | 148 ++++++++++++++++++++++++++++++++++++++++++++++--- src/index.ts | 2 +- src/ip.ts | 13 +++-- 5 files changed, 199 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 21b17f8..e722794 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c | :x: | `alias` | Alias deployment | | :x: | `deploy` | Deploy | | :white_check_mark: | `domains [ls]` | List domains | -| :x: | `domains add ` | Add domain | -| :x: | `domains rm ` | Remove domain | +| :white_check_mark: | `domains add ` | Add domain | +| :white_check_mark: | `domains rm ` | Remove domain | | :white_check_mark: | `login` | Login | | :white_check_mark: | `logout` | Logout | | :white_check_mark: | `ls` | List deployments | @@ -108,6 +108,30 @@ For your domain name to be resolvable by Kubernetes, you **must**: - create a DNS `A` record, which points to the IP Address of your load balancer (which can be found via `snow ip`). - Alias the domain name to a deployment. +``` +snow domains [ls] +``` + +List all configured domain names. + +``` +snow domains add +``` + +Verifies DNS records are configure properly for ``. Creates rule to redirect traffic from `` to the [default backend]. Requests an SSL certificate, if one is not available, and sets up SSL termination. + +``` +snow domains rm +``` + +Removes any traffic redirect rules. Removes SSL termination with the Let's Encrypt SSL certificate for `` (the [default certificate] will be used instead). The Let's Encrypt SSL certificate will remain persistented. Traffic from `` will redirect to the [default backend]. + +``` +snow ip +``` + +Prints the IP address of your cluster. + ### Dependencies The following CLI tools (installable via `snow install`) are necessary to orchestrate the entire end-to-end process, from Kubernetes cluster creation to managing your deployments: @@ -123,6 +147,8 @@ If running Kubernetes locally on Minikube, you will additionally need these cli - `virtualbox` (for creating docker images) [cert-manager]: https://github.com/jetstack/cert-manager +[default backend]: https://kubernetes.github.io/ingress-nginx/user-guide/default-backend/ +[default certificate]: https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate [docker registry]: https://github.com/helm/charts/tree/master/stable/docker-registry [now]: https://github.com/zeit/now-cli [ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ diff --git a/src/create.ts b/src/create.ts index 811e429..e6c3c8e 100644 --- a/src/create.ts +++ b/src/create.ts @@ -292,6 +292,30 @@ export default async () => { } \nEOF`); + // Create global ingress controller + await run(` + cat < { - const isLs = !subcommand || subcommand === 'ls'; +const dnsResolve = promisify(dns.resolve); - if (!isLs) { - return; - } +const domainHasCorrectDNSRecords = async (domainName: string) => { + return new Promise(async (resolve, reject) => { + const dnsIPs = await dnsResolve(domainName, 'A'); + const {stdout: clusterIP} = await exec(cmd); + + dnsIPs.forEach(dnsIP => { + if (clusterIP.trim() === dnsIP) { + return; + } + + logError(`⚠️ Domain name '${domainName}' has an A record for IP address ${dnsIP}, but should be set to ${clusterIP.trim()}.`); + logError(`⚠️ Update DNS records for '${domainName}'.`); + return reject(); + }); + + resolve(); + }); +}; + +interface IngressSpec { + spec: { + rules: [{ + host: string; + }]; + tls: [{ + hosts: string[]; + secretName: string; + }]; + }; +} + +function addDomainToIngress(domainName: string, ingressConfig: string): IngressSpec { + const ingress = JSON.parse(ingressConfig); + const {spec: {rules = [], tls = []}} = ingress; + rules.push({host: domainName}); + tls.push({ + hosts: [domainName], + secretName: domainName + }); + return {spec: {rules, tls}}; +} + +export default async (subcommand?: string, domainName?: string) => { + switch (subcommand) { + case 'add': { + if (!domainName) { + logError('Usage: snow domains add [name]'); + return; + } + + // Check that domain has proper DNS records. + // Bail early if they're bad. + try { + await domainHasCorrectDNSRecords(domainName); + } catch (error) { + return; + } + + // Check if domain already is already associated with an ingress. + // Bail early if it is. + const {stdout} = await exec('kubectl get ingress/snow-ingress -o jsonpath="{range .spec.rules[*]}{@.host}{\'\\n\'}{end}"'); + const domains = stdout.split('\n'); + if (domains.indexOf(domainName) !== -1) { + logError(`Domain '${domainName}' already configured.`); + return; + } - const path = - '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; - await run(`kubectl get ingress -o jsonpath='${path}'`); + /* Domain not in ingress. Add it to 'rules' and 'tls'. By default, traffic + * will go to ingress default backend ("default backend - 404") + */ + const {stdout: addIngressConfig} = await exec('kubectl get ingress/snow-ingress -o json'); + const {spec: addSpec} = addDomainToIngress(domainName, addIngressConfig); + await exec(`kubectl patch ingress snow-ingress --patch '${JSON.stringify({spec: addSpec})}'`); + + let hasSSLCert = true; + try { + await exec(`kubectl get secrets/${domainName}`); + } catch (e) { + hasSSLCert = false; + } + + logInfo(`✅ Domain '${domainName}' added.`); + + if (!hasSSLCert) { + logInfo('ℹ️ Wait a minute for SSL Certificate creation.'); + } + + break; + } + case undefined: + case 'ls': { + const path = + '{"Domains"}{"\\n\\n"}{range .items[*].spec.rules[*]}{.host}{"\\n"}{end}{"\\n"}'; + await run(`kubectl get ingress -o jsonpath='${path}'`); + break; + } + case 'remove': + case 'rm': + if (!domainName) { + logError('⚠️ No domain name specified.'); + return; + } + + const {stdout: rmIngressConfig} = await exec('kubectl get ingress/snow-ingress -o json'); + const {spec: {rules = [], tls = []}} = JSON.parse(rmIngressConfig); + const patch = [ + rules.length && { + op: 'replace', + path: '/spec/rules', + value: rules.filter(({host}: { host: string; }) => (host !== domainName)) + }, + tls.length && { + op: 'replace', + path: '/spec/tls', + value: tls.filter(({secretName}: { secretName: string; }) => (secretName !== domainName)) + } + ].filter(Boolean); + + // Check if domain already is already associated with an ingress. + // Bail early if it is. + const {stdout: domainList} = await exec('kubectl get ingress/snow-ingress -o jsonpath="{range .spec.rules[*]}{@.host}{\'\\n\'}{end}"'); + const currDomains = domainList.split('\n'); + if (currDomains.indexOf(domainName) === -1) { + logError(`⚠️ Domain '${domainName}' has no existing configuration.`); + return; + } + + await exec(`kubectl patch ingress snow-ingress --type='json' --patch '${JSON.stringify(patch)}'`); + logInfo(`✅ Domain '${domainName}' removed.`); + + break; + default: { + console.log('usage error'); + } + } }; diff --git a/src/index.ts b/src/index.ts index 39ee6e3..c41b39e 100755 --- a/src/index.ts +++ b/src/index.ts @@ -29,7 +29,7 @@ async function main() { break; } case 'domains': { - await domains(rest[0]); + await domains(...rest); break; } case 'install': { diff --git a/src/ip.ts b/src/ip.ts index 5b41052..8c2008c 100644 --- a/src/ip.ts +++ b/src/ip.ts @@ -1,10 +1,11 @@ import { run } from './utils'; +const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; +export const cmd = ` + kubectl get services/nginx-ingress-controller \ + --namespace=kube-system \ + -o jsonpath='${path}'`; + export default async () => { - const path = '{.status.loadBalancer.ingress[0].ip}{"\\n"}'; - await run(` - kubectl get services/nginx-ingress-controller \ - --namespace=kube-system \ - -o jsonpath='${path}' - `); + await run(cmd); }; From 17a7cf0e78344b323928e510bd45791d22faca6e Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 7 Jan 2019 10:17:18 -0800 Subject: [PATCH 40/62] [docs] add comparison between snow vs. now --- docs/comparison.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 docs/comparison.md diff --git a/docs/comparison.md b/docs/comparison.md new file mode 100644 index 0000000..1ce31a4 --- /dev/null +++ b/docs/comparison.md @@ -0,0 +1,47 @@ +# Snow vs Now + +There are tradeoffs to using `snow` and `now`. + +## Features + +| Feature | ❄ snow | ▲ now | Details | +| ------------------------- | ------------------ | --------------------- | ------------------------------------------------ | +| Autoscaling | :white_check_mark: | :white_check_mark: \* | [Now plans] Pro & Advanced only. | +| SSL Termination | :white_check_mark: | :white_check_mark: | Certificates self-renew; both use Let's Encrypt. | +| Multi-region deployments | :x: | :white_check_mark: | Snow: Dependent upon [Multicluster SIG]. | +| Internal deployments | :white_check_mark: | :x: | Deploy internally accessible Dockerfiles. | +| HTTP(S)/WS(S) connections | :white_check_mark: | :white_check_mark: | Insecure connections are upgraded. | +| TCP connections | :white_check_mark: | :x: | Useful for deploying things like Redis. | +| Serverless lambdas | :x: | :white_check_mark: \* | Now v2 only. | + +### Multi-region deployments + +Now's Anycast DNS service and load balancers allows serving content as close as possible to users. Since the load balancer implementations used by Kubernetes provide similar functionality (e.g., [Google Cloud Load Balancing]), it may be possible to provide this functionality in the future when the [Multicluster SIG] API's reach general availability. A beta [multicluster ingress](`kubemci`) serves as a working proof-of-concept. + +### Internal deployments + +On snow, each deployment is associated with a kubernetes service. Each service is assigned an address from the service [address range] (e.g., `10.0.0.0/20`). You can use this IP Address to talk between deployments, without exposing the deployment on the public internet. + +On some cloud providers, by keeping traffic between deployments in the same zone/region, you might save on network ingress/egress costs as well. + +### Serverless lambdas + +Today, Serverless lambdas are out of scope for `snow`. + +## Operating Cost + +Costs will vary depend on which cloud you choose. Here's an example of what you might minimally need to run on Google Cloud in Region `us-west2`. + +| Resource | Resource Count | Monthly Cost | +| -------------------------------------- | -------------- | ------------ | +| `g1-small` compute instance | 1 | \$15.74 | +| Load balancer w/ 100GB Network Ingress | 1 | \$21.44 | +| 100GB Network Egress - Americas | 100GB | \$11.88 | +| Cloud Storage (for Docker Registry) | 8GB | \$0.07 | +| Total | | \$49.13 | + +[multicluster ingress]: https://github.com/GoogleCloudPlatform/k8s-multicluster-ingress +[google cloud load balancing]: https://cloud.google.com/load-balancing/docs/choosing-load-balancer +[address range]: https://www.mediawiki.org/wiki/Help:Range_blocks#Table_of_sample_ranges +[now plans]: https://zeit.co/pricing/v1 +[multicluster sig]: https://github.com/kubernetes/community/tree/master/sig-multicluster From ea532afe0abfa54c9c6d30c27cebdf9edcfd38fd Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Tue, 8 Jan 2019 18:59:04 -0800 Subject: [PATCH 41/62] [Comparison] add Digital Ocean costs --- docs/comparison.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/docs/comparison.md b/docs/comparison.md index 1ce31a4..cae75df 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -30,15 +30,27 @@ Today, Serverless lambdas are out of scope for `snow`. ## Operating Cost -Costs will vary depend on which cloud you choose. Here's an example of what you might minimally need to run on Google Cloud in Region `us-west2`. - -| Resource | Resource Count | Monthly Cost | -| -------------------------------------- | -------------- | ------------ | -| `g1-small` compute instance | 1 | \$15.74 | -| Load balancer w/ 100GB Network Ingress | 1 | \$21.44 | -| 100GB Network Egress - Americas | 100GB | \$11.88 | -| Cloud Storage (for Docker Registry) | 8GB | \$0.07 | -| Total | | \$49.13 | +Costs will vary depend on which cloud you choose. These are minimal costs-- in a production setting, you might want a minimum of 2 compute instances, for example, to ensure high availability. + +Cost table for Google Cloud Plaform in region `us-east4`. + +| Resource | Count | Cost | +| ----------------------------------------- | ----- | ---------- | +| `g1-small` compute instance (1vCPU/1.7GB) | 1 | \$14.77 | +| Load balancer w/ 100GB Network Ingress | 1 | \$21.34 | +| 100GB Network Egress - Americas | 100GB | \$11.88 | +| Persistent Disk | 8GB | \$0.35 | +| Total | | \$48.34/mo | + +Cost table for Digital Ocean in `nyc1`: + +| Resource | Count | Cost | +| ------------------------------------------- | ----- | ---------- | +| `s-1vcpu-2gb` standard droplet (1vCPU/2GB) | 1 | \$10.00 | +| Load Balancer w/ ∞GB Network Ingress | 1 | \$10.00 | +| 100GB Network Egress (first 1000GB/mo free) | 100GB | \$0.00 | +| Block Storage (\$0.10/GB/mo) | 8GB | \$0.80 | +| Total | | \$20.80/mo | [multicluster ingress]: https://github.com/GoogleCloudPlatform/k8s-multicluster-ingress [google cloud load balancing]: https://cloud.google.com/load-balancing/docs/choosing-load-balancer From 58b73e5aaae0cd01a4b8cccfd6601c87eff070ae Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Tue, 8 Jan 2019 22:19:47 -0800 Subject: [PATCH 42/62] typescript improvements - cloud providers (#5) --- src/create.ts | 16 +++++----------- src/deploy.ts | 2 +- src/index.ts | 2 +- src/login.ts | 3 ++- src/logout.ts | 5 +++-- src/providers.ts | 4 ++++ 6 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 src/providers.ts diff --git a/src/create.ts b/src/create.ts index e6c3c8e..9af34d3 100644 --- a/src/create.ts +++ b/src/create.ts @@ -1,17 +1,11 @@ import * as path from 'path'; -import { - askForInput, - confirm, - logError, - logInfo, - pickOne, - run -} from './utils'; +import { askForInput, confirm, logError, logInfo, pickOne, run } from './utils'; +import cloudProviders from './providers'; export default async () => { - const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); + switch (provider) { case 'minikube': { logInfo('Note: Minikube is for development purposes only.'); @@ -264,10 +258,10 @@ export default async () => { `); let email = await askForInput( - 'Provide an email address for Let\'s Encrypt' + "Provide an email address for Let's Encrypt" ); while (!(await confirm(`Confirm email: "${email}"`))) { - email = await askForInput('Provide an email address for Let\'s Encrypt'); + email = await askForInput("Provide an email address for Let's Encrypt"); } // Create cluster issuer diff --git a/src/deploy.ts b/src/deploy.ts index f77d6ce..eed1ab3 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -1,6 +1,6 @@ import chalk from 'chalk'; import * as path from 'path'; -import {exec, readFile, stat} from './utils'; +import { exec, readFile, stat } from './utils'; export default async () => { // First: Verify we have a Dockerfile. diff --git a/src/index.ts b/src/index.ts index c41b39e..17428e4 100755 --- a/src/index.ts +++ b/src/index.ts @@ -56,7 +56,7 @@ async function main() { break; } case 'scale': { - await scale(...rest); + await scale(rest[0], rest[1], rest[2]); break; } case 'secrets': { diff --git a/src/login.ts b/src/login.ts index f9ea468..fdcbf5d 100644 --- a/src/login.ts +++ b/src/login.ts @@ -1,9 +1,10 @@ import { logError, pickOne, run } from './utils'; +import cloudProviders from './providers'; export default async () => { - const cloudProviders = ['minikube', 'gcp']; const question = 'Which cloud provider do you want to login to'; const provider = await pickOne(question, cloudProviders); + switch (provider) { case 'minikube': { await run('kubectl config use-context minikube'); diff --git a/src/logout.ts b/src/logout.ts index 5f2530f..2157718 100644 --- a/src/logout.ts +++ b/src/logout.ts @@ -1,9 +1,10 @@ import { logError, pickOne, run } from './utils'; +import cloudProviders from './providers'; export default async () => { const question = 'Which cloud provider do you want to logout of'; - const options = ['minikube', 'gcp']; - const provider = await pickOne(question, options); + const provider = await pickOne(question, cloudProviders); + switch (provider) { case 'minikube': { // In the case of minikube, this is a no-op. diff --git a/src/providers.ts b/src/providers.ts new file mode 100644 index 0000000..0a5214a --- /dev/null +++ b/src/providers.ts @@ -0,0 +1,4 @@ +type Provider = 'minikube' | 'gcp'; +const cloudProviders: Provider[] = ['minikube', 'gcp']; + +export default cloudProviders; From 8daa0ff246a4d79eba848bd7e5f2d3a734e0f82d Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Wed, 16 Jan 2019 20:52:00 -0800 Subject: [PATCH 43/62] alias/certs cmds; secrets rename cmd; docs updates --- README.md | 136 +++++++++++----------------------------- docs/commands.md | 133 +++++++++++++++++++++++++++++++++++++++ docs/comparison.md | 20 +++--- src/alias.ts | 152 +++++++++++++++++++++++++++++++++++++++++++++ src/certs.ts | 51 +++++++++++++++ src/domains.ts | 20 ++++-- src/index.ts | 10 +++ src/secrets.ts | 55 +++++++++++++--- 8 files changed, 457 insertions(+), 120 deletions(-) create mode 100644 docs/commands.md create mode 100644 src/alias.ts create mode 100644 src/certs.ts diff --git a/README.md b/README.md index e722794..a9c6cae 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > :snowflake: **S**elf-hosted **now** deployments -Enjoy effortless deployments with a clone of [now][now] on a cloud of your choosing. +Enjoy effortless deployments with a clone of [now] on a cloud of your choosing. ### Features @@ -27,111 +27,54 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c # Create your kubernetes cluster (GCP) > snow create -# Create a DNS 'A' record (e.g., myapp.com A 1.2.3.4) +# Get your cluster load balancer IP address +# And create a DNS 'A' record (e.g., myapp.com A 1.2.3.4) +> snow ip # Deploy > snow ``` -### Supported commands +### New commands -| Support | Command | Description | -| ------------------ | ---------------------------- | ----------------- | -| :x: | \ | Create deployment | -| :x: | `alias` | Alias deployment | -| :x: | `deploy` | Deploy | -| :white_check_mark: | `domains [ls]` | List domains | -| :white_check_mark: | `domains add ` | Add domain | -| :white_check_mark: | `domains rm ` | Remove domain | -| :white_check_mark: | `login` | Login | -| :white_check_mark: | `logout` | Logout | -| :white_check_mark: | `ls` | List deployments | -| :white_check_mark: | `rm ` | Remove deployment | -| :white_check_mark: | `scale []` | Scale deployment | -| :white_check_mark: | `secrets [ls]` | List secrets | -| :white_check_mark: | `secrets add ` | Create secret | -| :white_check_mark: | `secrets rm ` | Remove secret | +| Command | Description | +| --------- | ------------------------------------------- | +| `create` | Run once to create cluster | +| `install` | Uses brew to install necessary dependencies | +| `ip` | Get IP Address of Load Balancer | -### New commands +### Supported commands -| Command | Description | -| -------- | ------------------------------- | -| `create` | Run once to create cluster | -| `ip` | Get IP Address of Load Balancer | +**Detailed** descriptions of supported commands at [docs/commands.md](docs/commands.md). + +| Support | Command | Description | +| ------------------ | ------------------------------------ | --------------------- | +| :x: | \ | Deploy | +| :white_check_mark: | `alias [ls]` | List aliases | +| :white_check_mark: | `alias set ` | Create alias | +| :white_check_mark: | `alias rm ` | Remove alias | +| :white_check_mark: | `certs [ls]` | List SSL Certificates | +| :white_check_mark: | `certs issue []` | Issue certificate | +| :white_check_mark: | `certs rm ` | Remove a certificate | +| :x: | `deploy` | Deploy | +| :white_check_mark: | `domains [ls]` | List domains | +| :white_check_mark: | `domains add ` | Add domain | +| :no_entry: | `domains buy ` | Buy domain | +| :white_check_mark: | `domains rm ` | Remove domain | +| :white_check_mark: | `login` | Login | +| :white_check_mark: | `logout` | Logout | +| :white_check_mark: | `ls` | List deployments | +| :white_check_mark: | `rm ` | Remove deployment | +| :white_check_mark: | `scale []` | Scale deployment | +| :white_check_mark: | `secrets [ls]` | List secrets | +| :white_check_mark: | `secrets add ` | Create secret | +| :white_check_mark: | `secrets rename ` | Rename secret | +| :white_check_mark: | `secrets rm ` | Remove secret | ### Tell me more The essential CLI commands to understand are `snow create` and `snow deploy`. -``` -snow create -``` - -Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. Here's what happens when you run `snow create`: - -- You are authenticated to the cloud provider of your choosing. -- A Kubernetes cluster is created. -- [tiller][helm] is installed, which is used to install: - - [cert-manager] - - Will automatically watch your deployments and request new certificates for hostnames. - - Request new certificates when they're closing to expiring and seamlessly update in production. - - [ingress-nginx] - - Used for mapping hostnames to deployments. - - All HTTP traffic is permanently redirected (HTTP 308) to HTTPS. - - SSL terminiation occurs prior to requests reaching deployments. - -``` -snow deploy -``` - -Also aliased as `snow`. Your current directory must have both `Dockerfile` and `now.json` files. Example `now.json`: - -```json -{ - "name": "myapp", // required - "alias": ["api.myapp.com", "myapp.com"], - "files": ["server.js"] -} -``` - -The deployment process: - -- The files listed in `now.json` plus `Dockerfile` (collectively referred to as the "build context") are assembled into a tar archive. -- [Kaniko] creates a Docker image from the build context, and pushes it to the private Docker registry in your Kubernetes cluster. -- A Kubernetes `deployment` resource is created for your image. -- A Kubernetes `service` resource exposes your deployment. -- A Kubernetes `ingress` resource maps hostnames (listed as `alias` array in now.json) to the service. -- [cert-manager] continually inspects ingresses, so if a deployment needs SSL certificates, they will be generated upon deployment. - -For your domain name to be resolvable by Kubernetes, you **must**: - -- create a DNS `A` record, which points to the IP Address of your load balancer (which can be found via `snow ip`). -- Alias the domain name to a deployment. - -``` -snow domains [ls] -``` - -List all configured domain names. - -``` -snow domains add -``` - -Verifies DNS records are configure properly for ``. Creates rule to redirect traffic from `` to the [default backend]. Requests an SSL certificate, if one is not available, and sets up SSL termination. - -``` -snow domains rm -``` - -Removes any traffic redirect rules. Removes SSL termination with the Let's Encrypt SSL certificate for `` (the [default certificate] will be used instead). The Let's Encrypt SSL certificate will remain persistented. Traffic from `` will redirect to the [default backend]. - -``` -snow ip -``` - -Prints the IP address of your cluster. - ### Dependencies The following CLI tools (installable via `snow install`) are necessary to orchestrate the entire end-to-end process, from Kubernetes cluster creation to managing your deployments: @@ -147,15 +90,8 @@ If running Kubernetes locally on Minikube, you will additionally need these cli - `virtualbox` (for creating docker images) [cert-manager]: https://github.com/jetstack/cert-manager -[default backend]: https://kubernetes.github.io/ingress-nginx/user-guide/default-backend/ -[default certificate]: https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate [docker registry]: https://github.com/helm/charts/tree/master/stable/docker-registry [now]: https://github.com/zeit/now-cli -[ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ [ingress-nginx]: https://github.com/kubernetes/ingress-nginx [kaniko]: https://github.com/GoogleContainerTools/kaniko [kubernetes]: https://kubernetes.io/ -[helm]: https://docs.helm.sh/ -[docker]: https://www.docker.com/ -[letsencrypt]: https://letsencrypt.org/ -[minikube]: https://kubernetes.io/docs/setup/minikube/ diff --git a/docs/commands.md b/docs/commands.md new file mode 100644 index 0000000..a6da67d --- /dev/null +++ b/docs/commands.md @@ -0,0 +1,133 @@ +# CLI Commands + +Below is a description of each command. While you normally won't need exposure to the implementation details of each command, having a working knowledge of Kubernetes will be beneficial in understanding their behavior. + +## snow alias [ls] + +List all aliases (hostnames that map to deployments). + +## snow alias set \ \ + +Configures your Kubernetes cluster so hostname `alias` points to a deployment named `deployment`. + +## snow alias rm \ + +Remove host name `alias` from any deployment in may point to, and any associated SSL configuration for `alias`. If you continue to have a DNS A record for `alias` that points to your Kubernetes cluster, all responses for hostname `alias` will be served with the [default certificate]. + +## snow certs [ls] + +Lists all certificates. + +## snow certs issue \ [\] + +Creates a certificate with the first common name (`cn`) listed. The first and all subsequent common names are also listed in the certificate's Subject Alternative Names (SANs) section. This allows you to create a single certificate for multiple domain names. + +## snow certs rm \ + +Delete a Kubernetes `certificate` object. Does _not_ delete the Kubernetes `secret` holding the certificate/private key pair. + +## snow create + +Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. Here's what happens when you run `snow create`: + +- You are authenticated to the cloud provider of your choosing. +- A Kubernetes cluster is created. +- [tiller][helm] is installed, which is used to install: + - [cert-manager] + - Will automatically watch your deployments and request new certificates for hostnames. + - Request new certificates when they're closing to expiring and seamlessly update in production. + - [ingress-nginx] + - Installing ingress-nginx will instantiate a load balancer, e.g., on GCP this instantiate a [TCP Proxy Load Balancer]. + - The nginx controller is a Kubernetes object of type `service`. + - The type of service is `LoadBalancer`. + - Used for mapping hostnames to deployments. + - All HTTP traffic is permanently redirected (HTTP 308) to HTTPS. + - SSL terminiation occurs prior to requests reaching deployments. + +## snow [deploy] + +Also aliased as `snow`. Your current directory must have both `Dockerfile` and `now.json` files. Example `now.json`: + +```json +{ + "name": "myapp", // required + "alias": ["api.myapp.com", "myapp.com"], + "files": ["server.js"] +} +``` + +The deployment process: + +- The files listed in `now.json` plus `Dockerfile` (collectively referred to as the "build context") are assembled into a tar archive. +- [Kaniko] creates a Docker image from the build context, and pushes it to the private Docker registry in your Kubernetes cluster. +- A Kubernetes `deployment` resource is created for your image. +- A Kubernetes `service` resource exposes your deployment. +- A Kubernetes `ingress` resource maps hostnames (listed as `alias` array in now.json) to the service. +- [cert-manager] continually inspects ingresses, so if a deployment needs SSL certificates, they will be generated upon deployment. + +For your domain name to be resolvable by Kubernetes, you **must**: + +- create a DNS `A` record, which points to the IP Address of your load balancer (which can be found via `snow ip`). +- Alias the domain name to a deployment. + +## snow domains [ls] + +List all configured domain names. + +## snow domains add \ + +Verifies DNS records are configure properly for `domain`. Creates rule to redirect traffic from `domain` to the [default backend]. Requests an SSL certificate, if one is not available, and sets up SSL termination. + +## snow domains rm \ + +Removes any traffic redirect rules. Removes SSL termination with the Let's Encrypt SSL certificate for `domain` (the [default certificate] will be used instead). The Let's Encrypt SSL certificate will remain persistented. Traffic from `domain` will redirect to the [default backend]. + +## snow ip + +Prints the IP address of your cluster's load balancer. You'll need this for configuring DNS `A` records that point to your load balancer. + +## snow login + +Asks which cloud provider you are using, and configures your kube config file (typically at `~/.kube/config`). Since you will need credentials to your Kubernetes cluster to perform operations on it, you must login (or have a properly configured kube file) prior to running snow commands. + +## snow logout + +Remove all credentials from your kube config file (typically at `~/.kube/config`). + +## snow ls + +List all deployments. + +## snow rm \ + +Deplete deployment `name`. + +## snow scale [] + +Configure a deployment named `deployment` to scale to a `min` / `max` number of instances. If no `max` is specified, the `min` is used as the `max`. + +## snow secrets [ls] + +List all secrets. This will only show secrets created by the snow API, which are annotated in Kubernetes with label `snowsecret=true`. + +## snow secrets add + +Create a secret named `key`. + +## snow secrets rename \ \ + +Rename a secret from `old-key` to `new-key`. In Kubernetes, this means removing the old key, and creating a new key with identical info. + +## snow secrets rm \ + +Delete a secret with name `key`. + +[cert-manager]: https://github.com/jetstack/cert-manager +[default backend]: https://kubernetes.github.io/ingress-nginx/user-guide/default-backend/ +[default certificate]: https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate +[helm]: https://docs.helm.sh/ +[ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ +[ingress-nginx]: https://github.com/kubernetes/ingress-nginx +[kaniko]: https://github.com/GoogleContainerTools/kaniko +[minikube]: https://kubernetes.io/docs/setup/minikube/ +[tcp proxy load balancer]: https://cloud.google.com/load-balancing/docs/choosing-load-balancer diff --git a/docs/comparison.md b/docs/comparison.md index cae75df..937788b 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -4,15 +4,17 @@ There are tradeoffs to using `snow` and `now`. ## Features -| Feature | ❄ snow | ▲ now | Details | -| ------------------------- | ------------------ | --------------------- | ------------------------------------------------ | -| Autoscaling | :white_check_mark: | :white_check_mark: \* | [Now plans] Pro & Advanced only. | -| SSL Termination | :white_check_mark: | :white_check_mark: | Certificates self-renew; both use Let's Encrypt. | -| Multi-region deployments | :x: | :white_check_mark: | Snow: Dependent upon [Multicluster SIG]. | -| Internal deployments | :white_check_mark: | :x: | Deploy internally accessible Dockerfiles. | -| HTTP(S)/WS(S) connections | :white_check_mark: | :white_check_mark: | Insecure connections are upgraded. | -| TCP connections | :white_check_mark: | :x: | Useful for deploying things like Redis. | -| Serverless lambdas | :x: | :white_check_mark: \* | Now v2 only. | +| Feature | ❄ snow | 𝚫 now | Details | +| ------------------------------ | ------------------ | --------------------- | ------------------------------------------------ | +| Doesn't require DNS TXT record | :white_check_mark: | :x: | Needed by now to validate domain ownership. | +| Autoscaling | :white_check_mark: | :white_check_mark: \* | [Now plans] Pro & Advanced only. | +| SSL Termination | :white_check_mark: | :white_check_mark: | Certificates self-renew; both use Let's Encrypt. | +| Wildcard Certificates | :x: | :white_check_mark: \* | Supported on Now when using Zeit's name servers. | +| Multi-region deployments | :x: | :white_check_mark: | Snow: Dependent upon [Multicluster SIG]. | +| Internal deployments | :white_check_mark: | :x: | Deploy internally accessible Dockerfiles. | +| HTTP(S)/WS(S) connections | :white_check_mark: | :white_check_mark: | Insecure connections are upgraded. | +| TCP connections | :white_check_mark: | :x: | Useful for deploying things like Redis. | +| Serverless lambdas | :x: | :white_check_mark: \* | Now v2 only. | ### Multi-region deployments diff --git a/src/alias.ts b/src/alias.ts new file mode 100644 index 0000000..84a8498 --- /dev/null +++ b/src/alias.ts @@ -0,0 +1,152 @@ +import {domainHasCorrectDNSRecords} from './domains'; +import { exec, isRemove, logError, run } from './utils'; + +export default async (subcommand?: string, aliasOrDeploymentPrefix?: string, hostname?: string) => { + interface IRule { + host: string; + } + + interface ITLS { + hosts: string[]; + } + + function hasExistingRuleFactory(host?: string) { + return function hasExistingRule(rule: IRule) { + return rule.host === host; + }; + } + + function hasExistingTLSFactory(host?: string) { + return function hasExistingTLS(tls: ITLS) { + if (!host) { + return false; + } + return tls.hosts.indexOf(host) !== -1; + }; + } + + if (!subcommand || subcommand === 'ls') { + await run('kubectl get ingress/snow-ingress -o=jsonpath=\"{\'Host\'} {\'\'}{\'\\n\'}{range .spec.rules[*]}{.host} {.http.paths[*].backend.serviceName}{\'\\n\'}{end}\" | column -t'); + return; + } + + if (subcommand === 'set') { + const deployment = aliasOrDeploymentPrefix; + + if (!aliasOrDeploymentPrefix) { + logError('deployment (required): snow alias set '); + return; + } + + if (!hostname) { + logError('alias (required): snow alias set '); + return; + } + + // Verify the domain name has the correct DNS records. + try { + await domainHasCorrectDNSRecords(hostname); + } catch (e) { + return; + } + + // Given a deployment name, verify both a deployment and service exist. + try { + await run(`kubectl get service/${deployment}-service`); + } catch (e) { + logError(`No service exists for deployment '${deployment}'`); + return; + } + + try { + await run(`kubectl get deployment/${deployment}-deployment`); + } catch (e) { + logError(`No deployment exists for '${deployment}'`); + return; + } + + // Fetch the ingress spec. + const { stdout } = await exec('kubectl get ingress/snow-ingress -o json'); + const ingressSpec = JSON.parse(stdout).spec; + + const rule = { + host: hostname, + http: { + paths: [ + { + backend: { + serviceName: `${deployment}-service`, + servicePort: 80 + } + } + ] + } + }; + + // See if an existing rule exists. + const ruleIndex = ingressSpec.rules.findIndex(hasExistingRuleFactory(hostname)); + + if (ruleIndex === -1) { + // No rule exists. Create one. + ingressSpec.rules.push(rule); + } else { + // Update existing rule. + ingressSpec.rules[ruleIndex] = rule; + } + + // See if an existing TLS entry exists. + const tlsIndex = ingressSpec.tls.findIndex(hasExistingTLSFactory(hostname)); + if (tlsIndex === -1) { + ingressSpec.tls.push({ + hosts: [hostname], + secretName: hostname + }); + } + + const ingressPatchString = JSON.stringify({spec: ingressSpec}); + + // Patch the ingress resource. + await run(`kubectl patch ingress/snow-ingress --patch '${ingressPatchString}'`); + + return; + } + + if (isRemove(subcommand)) { + const alias = aliasOrDeploymentPrefix; + + if (!alias) { + logError('alias (required): snow alias rm '); + return; + } + + // Fetch the ingress spec. + const { stdout } = await exec('kubectl get ingress/snow-ingress -o json'); + const ingressSpec = JSON.parse(stdout).spec; + + // See if an existing rule exists. + const ruleIndex = ingressSpec.rules.findIndex(hasExistingRuleFactory(alias)); + + if (ruleIndex !== -1) { + ingressSpec.rules.splice(ruleIndex, 1); + } + + // See if an existing TLS entry exists. + const tlsIndex = ingressSpec.tls.findIndex(hasExistingTLSFactory(alias)); + + /* Only remove the TLS entry if it exists as a certificate with + * a single hostname (e.g., the certificate has no SANs). + */ + if (tlsIndex !== -1 && ingressSpec.tls[tlsIndex].hosts.length === 1) { + ingressSpec.tls.splice(tlsIndex, 1); + } + + const ingressPatchString = JSON.stringify({spec: ingressSpec}); + + // Patch the ingress resource. + await run(`kubectl patch ingress/snow-ingress --patch '${ingressPatchString}'`); + + return; + } + + logError('Invalid usage'); +}; diff --git a/src/certs.ts b/src/certs.ts new file mode 100644 index 0000000..5a2eaea --- /dev/null +++ b/src/certs.ts @@ -0,0 +1,51 @@ +import { isRemove, logError, run } from './utils'; + +export default async function certs(subcommand?: string, commonName?: string, ...subAltNames: string[]) { + if (!subcommand || subcommand === 'ls') { + await run('kubectl get certificates -o=custom-columns="Common Name":.metadata.name,SANs:.spec.dnsNames[*],"Created At":.metadata.creationTimestamp'); + return; + } + + if (subcommand === 'issue') { + if (!commonName) { + logError('cn (required): snow certs []'); + return; + } + const domains = [commonName, ...subAltNames].map(domain => `"${domain}"`).join(); + await run(` + cat < { +export const domainHasCorrectDNSRecords = async (domainName: string) => { return new Promise(async (resolve, reject) => { - const dnsIPs = await dnsResolve(domainName, 'A'); - const {stdout: clusterIP} = await exec(cmd); + let dnsIPs; + let {stdout: clusterIP} = await exec(cmd); + clusterIP = clusterIP.trim(); + try { + dnsIPs = await dnsResolve(domainName, 'A'); + } catch (e) { + if (e.code === 'ENOTFOUND') { + logError(`⚠️ Domain name '${domainName}' has no DNS records.`); + logError(`⚠️ Create an A record for '${domainName}' and set its value to ${clusterIP}.`); + } else { + logError('⚠️ Unknown error occurred while verifying DNS records.'); + } + return; + } dnsIPs.forEach(dnsIP => { if (clusterIP.trim() === dnsIP) { return; } - logError(`⚠️ Domain name '${domainName}' has an A record for IP address ${dnsIP}, but should be set to ${clusterIP.trim()}.`); + logError(`⚠️ Domain name '${domainName}' has an A record for IP address ${dnsIP}, but should be set to ${clusterIP}.`); logError(`⚠️ Update DNS records for '${domainName}'.`); return reject(); }); diff --git a/src/index.ts b/src/index.ts index 17428e4..303d54a 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ #!/usr/bin/env node import * as mri from 'mri'; +import alias from './alias'; +import certs from './certs'; import create from './create'; import deploy from './deploy'; import domains from './domains'; @@ -19,6 +21,14 @@ async function main() { const [command, ...rest] = _; switch (command) { + case 'alias': { + await alias(rest[0], rest[1], rest[2]); + break; + } + case 'certs': { + await certs(...rest); + break; + } case 'create': { await create(); break; diff --git a/src/secrets.ts b/src/secrets.ts index 71c0287..c4e8726 100644 --- a/src/secrets.ts +++ b/src/secrets.ts @@ -1,18 +1,59 @@ -import { isRemove, logError, run } from './utils'; +import { exec, isRemove, logError, run } from './utils'; -export default async function secrets(subcommand?: string, key?: string, value?: string) { +/* + * All secrets are stored as individual objects with a single key-value pair (key is string "key"). + * All secrets created via the snow API are labelled with {"snowsecret":"true"}. + */ +export default async function secrets(subcommand?: string, key?: string, valueOrNewKey?: string) { if (!subcommand || subcommand === 'ls') { - await run('kubectl get secrets'); + await run('kubectl get secrets -l snowsecret=true -o=custom-columns=Name:.metadata.name,Age:.metadata.creationTimestamp'); return; } if (subcommand === 'add') { - if (!key || !value) { + if (!key || !valueOrNewKey) { return logError('Key or value missing. Usage: now secrets add '); } - await run( - `kubectl create secret generic ${key} --from-literal=${key}=${value}` - ); + const value = valueOrNewKey; + const valueBase64 = Buffer.from(value).toString('base64'); + await run(` + cat < '); + } + + const {stdout: valueBase64} = await exec(`kubectl get secret/${oldKey} --output=jsonpath=\'{.data.key}\'`); + const newValue = Buffer.from(valueBase64, 'base64').toString(); + + // Create secret with name 'newKey' + await exec(`kubectl create secret generic ${newKey} --from-literal=key=${newValue}`); + + // Delete secret with name 'oldKey' + await exec(`kubectl delete secret/${oldKey}`); + return; } if (isRemove(subcommand)) { From bc147b73e690b25110e0c901193b15f431987a29 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Wed, 16 Jan 2019 20:54:15 -0800 Subject: [PATCH 44/62] [commands] escape special chars in headers --- docs/commands.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index a6da67d..0dd5b40 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -102,7 +102,7 @@ List all deployments. Deplete deployment `name`. -## snow scale [] +## snow scale \ \ [\] Configure a deployment named `deployment` to scale to a `min` / `max` number of instances. If no `max` is specified, the `min` is used as the `max`. @@ -110,7 +110,7 @@ Configure a deployment named `deployment` to scale to a `min` / `max` number of List all secrets. This will only show secrets created by the snow API, which are annotated in Kubernetes with label `snowsecret=true`. -## snow secrets add +## snow secrets add \ \ Create a secret named `key`. From a068337167e438be7d65bf19be933b5cd581f8b6 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 17:49:18 -0800 Subject: [PATCH 45/62] [login] gcp: set default project --- src/login.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/login.ts b/src/login.ts index fdcbf5d..6e3ce51 100644 --- a/src/login.ts +++ b/src/login.ts @@ -1,5 +1,5 @@ -import { logError, pickOne, run } from './utils'; import cloudProviders from './providers'; +import { logError, pickOne, run } from './utils'; export default async () => { const question = 'Which cloud provider do you want to login to'; @@ -12,6 +12,20 @@ export default async () => { } case 'gcp': { await run('gcloud auth login'); + + // Setup default project + const {stdout: projectsStr} = await run('gcloud projects list --format json'); + const projects = JSON.parse(projectsStr); + + if (projects.length === 0) { + logError('No projects exist. Create a project.'); + return; + } + + const {projectId} = projects[0]; + await run(`gcloud config set project ${projectId}`); + + // Get cluster credentials const { stdout: clusterData } = await run( 'gcloud container clusters list --format="json"' ); From 7e10c042dd8066b40bbefa9943f0faa05a01acd4 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 17:49:42 -0800 Subject: [PATCH 46/62] [create] fix linter warnings --- src/create.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/create.ts b/src/create.ts index 9af34d3..7c26928 100644 --- a/src/create.ts +++ b/src/create.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { askForInput, confirm, logError, logInfo, pickOne, run } from './utils'; import cloudProviders from './providers'; +import { askForInput, confirm, logError, logInfo, pickOne, run } from './utils'; export default async () => { const question = 'Which cloud provider are you hosting with'; @@ -258,10 +258,10 @@ export default async () => { `); let email = await askForInput( - "Provide an email address for Let's Encrypt" + 'Provide an email address for Let\'s Encrypt' ); while (!(await confirm(`Confirm email: "${email}"`))) { - email = await askForInput("Provide an email address for Let's Encrypt"); + email = await askForInput('Provide an email address for Let\'s Encrypt'); } // Create cluster issuer From 9247c8c5082ec094f6c9b2c80a203640b8c8fdae Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 17:50:39 -0800 Subject: [PATCH 47/62] [alias] don't apply suffix to kubernetes object names --- src/alias.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/alias.ts b/src/alias.ts index 84a8498..58b22d9 100644 --- a/src/alias.ts +++ b/src/alias.ts @@ -52,14 +52,14 @@ export default async (subcommand?: string, aliasOrDeploymentPrefix?: string, hos // Given a deployment name, verify both a deployment and service exist. try { - await run(`kubectl get service/${deployment}-service`); + await run(`kubectl get service/${deployment}`); } catch (e) { logError(`No service exists for deployment '${deployment}'`); return; } try { - await run(`kubectl get deployment/${deployment}-deployment`); + await run(`kubectl get deployment/${deployment}`); } catch (e) { logError(`No deployment exists for '${deployment}'`); return; @@ -75,8 +75,8 @@ export default async (subcommand?: string, aliasOrDeploymentPrefix?: string, hos paths: [ { backend: { - serviceName: `${deployment}-service`, - servicePort: 80 + serviceName: deployment, + servicePort: 8080 } } ] From 3fb9d4eb404735539590300fb09e78bbcecff16b Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 17:51:23 -0800 Subject: [PATCH 48/62] [commands] update cmd docs --- docs/commands.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 0dd5b40..1e25d65 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -20,15 +20,17 @@ Lists all certificates. ## snow certs issue \ [\] -Creates a certificate with the first common name (`cn`) listed. The first and all subsequent common names are also listed in the certificate's Subject Alternative Names (SANs) section. This allows you to create a single certificate for multiple domain names. +Creates a certificate with the first common name (`cn`) listed. The first and all subsequent `cn` are listed in the certificate's Subject Alternative Names (SANs) section. + +This allows you to create a single certificate for multiple domain names. ## snow certs rm \ -Delete a Kubernetes `certificate` object. Does _not_ delete the Kubernetes `secret` holding the certificate/private key pair. +Delete a Kubernetes `certificate` object with id `cn`. Does _not_ delete the Kubernetes `secret` holding the certificate/private key pair. ## snow create -Under the hood, `snow`'s simple CLI is served by a Kubernetes cluster. Here's what happens when you run `snow create`: +Creates a Kubernetes cluster to host your deployments. - You are authenticated to the cloud provider of your choosing. - A Kubernetes cluster is created. @@ -76,11 +78,17 @@ List all configured domain names. ## snow domains add \ -Verifies DNS records are configure properly for `domain`. Creates rule to redirect traffic from `domain` to the [default backend]. Requests an SSL certificate, if one is not available, and sets up SSL termination. +Verifies DNS records are configure properly for `domain`. Creates rule to redirect traffic from `domain` to the [default backend]. Requests an SSL certificate from Let's Encrypt, if one is not present in the cluster, and sets up SSL termination. ## snow domains rm \ -Removes any traffic redirect rules. Removes SSL termination with the Let's Encrypt SSL certificate for `domain` (the [default certificate] will be used instead). The Let's Encrypt SSL certificate will remain persistented. Traffic from `domain` will redirect to the [default backend]. +Removes any traffic redirect rules from `domain`. Removes SSL termination with the Let's Encrypt SSL certificate for `domain` (the [default certificate] will be used instead). + +The Let's Encrypt SSL certificate will remain persistented (which is helpful if the domain is added later, and it avoids an unnecessary request for a new certificate: requests are limited by Let's Encrypt [rate limits]). Traffic from `domain` will redirect to the [default backend]. + +## snow install + +Install dependencies using `brew`. ## snow ip @@ -131,3 +139,4 @@ Delete a secret with name `key`. [kaniko]: https://github.com/GoogleContainerTools/kaniko [minikube]: https://kubernetes.io/docs/setup/minikube/ [tcp proxy load balancer]: https://cloud.google.com/load-balancing/docs/choosing-load-balancer +[rate limits]: https://letsencrypt.org/docs/rate-limits/ From ae7cdb00a53748ea79f819a4c1bdc17135c10b42 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 17:53:26 -0800 Subject: [PATCH 49/62] [deploy] implementation --- README.md | 59 +- package.json | 1 + src/deploy.ts | 371 ++++++++-- yarn.lock | 1843 ++++++------------------------------------------- 4 files changed, 556 insertions(+), 1718 deletions(-) diff --git a/README.md b/README.md index a9c6cae..6d2bd2b 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c # Create your kubernetes cluster (GCP) > snow create -# Get your cluster load balancer IP address +# Get your deployment's IP address # And create a DNS 'A' record (e.g., myapp.com A 1.2.3.4) > snow ip @@ -35,41 +35,36 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c > snow ``` -### New commands - -| Command | Description | -| --------- | ------------------------------------------- | -| `create` | Run once to create cluster | -| `install` | Uses brew to install necessary dependencies | -| `ip` | Get IP Address of Load Balancer | - ### Supported commands **Detailed** descriptions of supported commands at [docs/commands.md](docs/commands.md). -| Support | Command | Description | -| ------------------ | ------------------------------------ | --------------------- | -| :x: | \ | Deploy | -| :white_check_mark: | `alias [ls]` | List aliases | -| :white_check_mark: | `alias set ` | Create alias | -| :white_check_mark: | `alias rm ` | Remove alias | -| :white_check_mark: | `certs [ls]` | List SSL Certificates | -| :white_check_mark: | `certs issue []` | Issue certificate | -| :white_check_mark: | `certs rm ` | Remove a certificate | -| :x: | `deploy` | Deploy | -| :white_check_mark: | `domains [ls]` | List domains | -| :white_check_mark: | `domains add ` | Add domain | -| :no_entry: | `domains buy ` | Buy domain | -| :white_check_mark: | `domains rm ` | Remove domain | -| :white_check_mark: | `login` | Login | -| :white_check_mark: | `logout` | Logout | -| :white_check_mark: | `ls` | List deployments | -| :white_check_mark: | `rm ` | Remove deployment | -| :white_check_mark: | `scale []` | Scale deployment | -| :white_check_mark: | `secrets [ls]` | List secrets | -| :white_check_mark: | `secrets add ` | Create secret | -| :white_check_mark: | `secrets rename ` | Rename secret | -| :white_check_mark: | `secrets rm ` | Remove secret | +| Support | Command | Description | +| ------------------ | ------------------------------------ | ----------------------------- | +| :x: | \ | Deploy | +| :white_check_mark: | `alias [ls]` | List aliases | +| :white_check_mark: | `alias set ` | Create alias | +| :white_check_mark: | `alias rm ` | Remove alias | +| :white_check_mark: | `certs [ls]` | List SSL Certificates | +| :white_check_mark: | `certs issue []` | Issue certificate | +| :white_check_mark: | `certs rm ` | Remove a certificate | +| :new: | `create` | Create Kubernetes cluster | +| :white_check_mark: | `deploy` | Deploy | +| :white_check_mark: | `domains [ls]` | List domains | +| :white_check_mark: | `domains add ` | Add domain | +| :no_entry: | `domains buy ` | Buy domain | +| :white_check_mark: | `domains rm ` | Remove domain | +| :white_check_mark: | `login` | Login | +| :white_check_mark: | `logout` | Logout | +| :white_check_mark: | `ls` | List deployments | +| :new: | `install` | Install CLI tools (via brew) | +| :new: | `ip` | Get IP Address of deployments | +| :white_check_mark: | `rm ` | Remove deployment | +| :white_check_mark: | `scale []` | Scale deployment | +| :white_check_mark: | `secrets [ls]` | List secrets | +| :white_check_mark: | `secrets add ` | Create secret | +| :white_check_mark: | `secrets rename ` | Rename secret | +| :white_check_mark: | `secrets rm ` | Remove secret | ### Tell me more diff --git a/package.json b/package.json index 24f2f53..ab28288 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "homepage": "https://github.com/snowjs/cli#readme", "dependencies": { "chalk": "2.4.1", + "docker-file-parser": "1.0.4", "mri": "1.1.1" }, "devDependencies": { diff --git a/src/deploy.ts b/src/deploy.ts index eed1ab3..b599b13 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -1,74 +1,359 @@ -import chalk from 'chalk'; +import * as parser from 'docker-file-parser'; import * as path from 'path'; -import { exec, readFile, stat } from './utils'; +import { logError, readFile, run } from './utils'; + +interface INowJSON { + name?: string; + files?: string[]; + alias?: string[]; +} + +interface IDeployment { + metadata: { + generation: number; + }; + spec: { + template: { + spec: { + containers: [{ + image: string; + }]; + }; + }; + }; +} + +function verifyNowJSON({alias, name}: INowJSON): Promise { + if (!name) { + const msg = 'Specify a "name" (string) property in now.json'; + logError(msg); + return Promise.reject(); + } + + if (!alias) { + const msg = 'Specify an "alias" (string[]) property in now.json'; + logError(msg); + return Promise.reject(); + } + + return Promise.resolve(); +} + +function getDockerfilePort(commands: parser.CommandEntry[]): Promise { + let dockerFilePort: string | undefined; + commands.forEach(({args, name}) => { + if (name !== 'EXPOSE') { + return; + } + console.log('args is', args); + if (typeof args === 'string') { + const port = args.match(/\d/g); + if (port) { + dockerFilePort = port.join(''); + } + } else if (Array.isArray(args)) { + const argsAsString = args.join(' '); + const port = argsAsString.match(/\d/g); + if (port) { + dockerFilePort = port.join(''); + } + } + }); + + if (!dockerFilePort) { + return Promise.reject(); + } + + return Promise.resolve(dockerFilePort); +} export default async () => { - // First: Verify we have a Dockerfile. + // Verify we have a Dockerfile + let dockerFile: parser.CommandEntry[]; const dockerFilePath = path.resolve(process.cwd(), 'Dockerfile'); try { - await stat(dockerFilePath); + const content = await readFile(dockerFilePath); + dockerFile = parser.parse(content.toString()); } catch (error) { const msg = `Error finding Dockerfile.\n${error.message}`; - console.log(chalk.red(msg)); + logError(msg); return; } - // Second: Verify we have a now.json file. + // Verify we have a well-formatted now.json file const nowFilePath = path.resolve(process.cwd(), 'now.json'); let nowConfig; try { const nowFile = await readFile(nowFilePath); nowConfig = JSON.parse(nowFile.toString()); } catch (error) { - console.log(chalk.red(`Error reading now.json.\n${error.message}`)); + const msg = `Error reading now.json.\n${error.message}`; + logError(msg); return; } + verifyNowJSON(nowConfig); + const {name, files} = nowConfig; - // Third: Build and tag the image. - const { name } = nowConfig; - if (!name) { - console.log(chalk.red('Specify a "name" in now.json')); - return; - } - const imageName = `${name}:latest`; + // Get revision number. + let deployment: IDeployment | undefined; + let revision: number; try { - await exec(`docker build -t ${imageName} -f ./Dockerfile .`); - console.log(`Docker image built => ${imageName}`); - } catch (error) { - console.log(`Could not build image from Dockerfile.\n${error.message}`); + // See if we have a deployment. + const {stdout: deploymentStr} = await run(`kubectl get deployments/${name} -o json`); + // Deployment exists. Update it. + deployment = JSON.parse(deploymentStr); + const {metadata: {generation}} = JSON.parse(deploymentStr); + revision = generation + 1; + } catch (e) { + // No deployment exists. + revision = 0; } - // Fourth: Start a local Docker registry, if necessary. - let registryRunning = true; - try { - const { stdout } = await exec( - 'docker ps --format "{{.Names}}" -f "name=registry"' - ); - if (!stdout) { - registryRunning = false; + // Create a volume for persisting the build context + const pvcName = `${name}-buildctx`; + await run(` + cat <= 2.1.2 < 3" - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== - -ignore@^4.0.2, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -1398,21 +729,6 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -import-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" - integrity sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - indent-string@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -1431,34 +747,10 @@ inherits@2: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^6.1.0: - version "6.2.0" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" - integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.0" - figures "^2.0.0" - lodash "^4.17.10" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.1.0" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -irregular-plurals@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" - integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= +inversify@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.1.tgz#500d709b1434896ce5a0d58915c4a4210e34fb6e" + integrity sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ== is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -1491,13 +783,6 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -1542,11 +827,6 @@ is-directory@^0.3.1: resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= -is-error@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" - integrity sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw= - is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -1559,7 +839,7 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= @@ -1576,21 +856,6 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= -is-get-set-prop@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz#2731877e4d78a6a69edcce6bb9d68b0779e76312" - integrity sha1-JzGHfk14pqae3M5rudaLB3nnYxI= - dependencies: - get-set-props "^0.1.0" - lowercase-keys "^1.0.0" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" @@ -1598,26 +863,6 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-js-type@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz#73617006d659b4eb4729bba747d28782df0f7e22" - integrity sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI= - dependencies: - js-types "^1.0.0" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= - is-number@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -1625,15 +870,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-obj-prop@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz#b34de79c450b8d7c73ab2cdf67dc875adb85f80e" - integrity sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4= - dependencies: - lowercase-keys "^1.0.0" - obj-props "^1.0.0" - -is-obj@^1.0.0, is-obj@^1.0.1: +is-obj@^1.0.1: version "1.0.1" resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= @@ -1664,11 +901,6 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -1681,35 +913,12 @@ is-promise@^2.1.0: resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-proto-prop@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.1.tgz#c8a0455c28fe38c8843d0c22af6f95f01ed4abc4" - integrity sha512-dkmgrJB7nfJhH1ySK1/Qn9xLPMv3ZNlPSAPoyUseD6DQzBF6YmbgQnoyy9OM8derNUlDVJlUGdCEhYbcCPfN5A== - dependencies: - lowercase-keys "^1.0.0" - proto-props "^1.1.0" - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= - is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== - -is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= - -is-stream@^1.0.0, is-stream@^1.1.0: +is-stream@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -1719,12 +928,12 @@ is-windows@^1.0.2: resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= -isarray@1.0.0, isarray@^1.0.0: +isarray@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -1746,11 +955,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -jest-docblock@^21.0.0: - version "21.2.0" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" - integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== - jest-get-type@^22.1.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" @@ -1766,17 +970,20 @@ jest-validate@^23.5.0: leven "^2.1.0" pretty-format "^23.6.0" -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-types@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz#d242e6494ed572ad3c92809fc8bed7f7687cbf03" - integrity sha1-0kLmSU7Vcq08koCfyL7X92h8vwM= +js-yaml@^3.7.0: + version "3.12.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" + integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" -js-yaml@^3.12.0, js-yaml@^3.9.0: +js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -1789,16 +996,6 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -1823,31 +1020,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= - dependencies: - package-json "^4.0.0" - leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -line-column-path@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/line-column-path/-/line-column-path-1.0.0.tgz#383b83fca8488faa7a59940ebf28b82058c16c55" - integrity sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU= - lint-staged@8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" @@ -1923,34 +1100,6 @@ listr@^0.14.2: p-map "^2.0.0" rxjs "^6.3.3" -load-json-file@^2.0.0: - version "2.0.0" - resolved "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -1959,47 +1108,7 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash.camelcase@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= - -lodash.kebabcase@^4.0.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= - -lodash.mergewith@^4.6.1: - version "4.6.1" - resolved "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== - -lodash.snakecase@^4.0.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= - -lodash.upperfirst@^4.2.0: - version "4.3.1" - resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" - integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= - -lodash.zip@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" - integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= - -lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5: +lodash@^4.17.5: version "4.17.11" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -2011,7 +1120,7 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" -log-symbols@^2.0.0, log-symbols@^2.2.0: +log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== @@ -2027,49 +1136,11 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lru-cache@^4.0.1: - version "4.1.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -map-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" - integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= - map-visit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -2084,27 +1155,7 @@ matcher@^1.0.0: dependencies: escape-string-regexp "^1.0.4" -meow@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" - integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - yargs-parser "^10.0.0" - -merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== - -micromatch@^3.1.10, micromatch@^3.1.8: +micromatch@^3.1.8: version "3.1.10" resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -2128,31 +1179,13 @@ mimic-fn@^1.0.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist-options@^3.0.1: - version "3.0.2" - resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" - integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - -minimist@0.0.8: - version "0.0.8" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -2161,13 +1194,6 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1: - version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - mri@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1" @@ -2183,21 +1209,6 @@ ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -multimatch@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" - integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= - dependencies: - array-differ "^1.0.0" - array-union "^1.0.1" - arrify "^1.0.0" - minimatch "^3.0.0" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -2215,17 +1226,12 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== @@ -2263,11 +1269,6 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -obj-props@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz#626313faa442befd4a44e9a02c3cb6bde937b511" - integrity sha1-YmMT+qRCvv1KROmgLDy2vek3tRE= - object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2310,51 +1311,11 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -open-editor@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/open-editor/-/open-editor-1.2.0.tgz#75ca23f0b74d4b3f55ee0b8a4e0f5c2325eb775f" - integrity sha1-dcoj8LdNSz9V7guKTg9cIyXrd18= - dependencies: - env-editor "^0.3.1" - line-column-path "^1.0.0" - opn "^5.0.0" - -opn@^5.0.0: - version "5.4.0" - resolved "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" - integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== - dependencies: - is-wsl "^1.1.0" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - p-limit@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" @@ -2362,13 +1323,6 @@ p-limit@^2.0.0: dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -2386,33 +1340,11 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -2426,18 +1358,6 @@ pascalcase@^0.1.1: resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -2458,25 +1378,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.5: +path-parse@^1.0.6: version "1.0.6" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - pify@^2.0.0: version "2.3.0" resolved "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -2499,21 +1405,6 @@ pinkie@^2.0.0: resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pkg-conf@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" - integrity sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg= - dependencies: - find-up "^2.0.0" - load-json-file "^4.0.0" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -2521,13 +1412,6 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" @@ -2535,43 +1419,16 @@ please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: dependencies: semver-compare "^1.0.0" -plur@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" - integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= - dependencies: - irregular-plurals "^1.0.0" - -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - prettier@1.15.3: version "1.15.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== -prettier@^1.12.1: - version "1.15.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" - integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== - pretty-format@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" @@ -2580,21 +1437,6 @@ pretty-format@^23.6.0: ansi-regex "^3.0.0" ansi-styles "^3.2.0" -progress@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" - integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== - -proto-props@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/proto-props/-/proto-props-1.1.0.tgz#e2606581dd24aa22398aeeeb628fc08e2ec89c91" - integrity sha512-A377CdhQBRjYVsSWrm2jo0KJa+N/IBew6lGLm0pdzZjtVqlUT23wEqg7q1/bk5gBEgVoBBbaErZY+UUNrcKOug== - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -2603,60 +1445,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -quick-lru@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" - integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= - -rc@^1.0.1, rc@^1.1.6: - version "1.2.8" - resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - read-pkg@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" @@ -2666,13 +1454,10 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -redent@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" - integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= - dependencies: - indent-string "^3.0.0" - strip-indent "^2.0.0" +reflect-metadata@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -2682,26 +1467,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -registry-auth-token@^3.0.1: - version "3.3.2" - resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= - dependencies: - rc "^1.0.1" - repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -2712,47 +1477,22 @@ repeat-string@^1.6.1: resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -require-uncached@^1.0.3: - version "1.0.3" - resolved "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= - resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" - integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== +resolve@^1.3.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== dependencies: - path-parse "^1.0.5" + path-parse "^1.0.6" restore-cursor@^2.0.0: version "2.0.0" @@ -2774,30 +1514,18 @@ rimraf@^2.2.8: dependencies: glob "^7.0.5" -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - run-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== -rxjs@^6.1.0, rxjs@^6.3.3: +rxjs@^6.3.3: version "6.3.3" resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex@^1.1.0: version "1.1.0" resolved "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -2805,24 +1533,12 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= - dependencies: - semver "^5.0.3" - -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.5.0, semver@^5.5.1: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: version "5.6.0" resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -2871,11 +1587,6 @@ simple-git@^1.85.0: dependencies: debug "^4.0.1" -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - slash@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -2886,13 +1597,6 @@ slice-ansi@0.0.4: resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" - integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== - dependencies: - is-fullwidth-code-point "^2.0.0" - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -2923,13 +1627,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= - dependencies: - is-plain-obj "^1.0.0" - source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" @@ -3016,7 +1713,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +string-width@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -3047,26 +1744,11 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-eof@^1.0.0: version "1.0.0" resolved "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - -strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -3084,50 +1766,6 @@ symbol-observable@^1.1.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -table@^5.0.2: - version "5.1.0" - resolved "https://registry.npmjs.org/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" - integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg== - dependencies: - ajv "^6.5.3" - lodash "^4.17.10" - slice-ansi "1.0.0" - string-width "^2.1.1" - -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= - dependencies: - execa "^0.7.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -the-argv@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz#0084705005730dd84db755253c931ae398db9522" - integrity sha1-AIRwUAVzDdhNt1UlPJMa45jblSI= - -through@^2.3.6: - version "2.3.8" - resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -3153,22 +1791,98 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -trim-newlines@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" - integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== -tslib@^1.9.0: +tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= +tslint-config-prettier@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz#946ed6117f98f3659a65848279156d87628c33dc" + integrity sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw== + +tslint-consistent-codestyle@^1.14.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.15.0.tgz#a3acf8d0a3ca0dc7d1285705102ba1fe4a17c4cb" + integrity sha512-6BNDBbZh2K0ibRXe70Mkl9gfVttxQ3t3hqV1BRDfpIcjrUoOgD946iH4SrXp+IggDgeMs3dJORjD5tqL5j4jXg== + dependencies: + "@fimbul/bifrost" "^0.17.0" + tslib "^1.7.1" + tsutils "^2.29.0" + +tslint-eslint-rules@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5" + integrity sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w== + dependencies: + doctrine "0.7.2" + tslib "1.9.0" + tsutils "^3.0.0" + +tslint-microsoft-contrib@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.0.0.tgz#7bff73c9ad7a0b7eb5cdb04906de58f42a2bf7a2" + integrity sha512-R//efwn+34IUjTJeYgNDAJdzG0jyLWIehygPt/PHuZAieTolFVS56FgeFW7DOLap9ghXzMiFPTmDgm54qaL7QA== + dependencies: + tsutils "^2.27.2 <2.29.0" + +tslint-xo@0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/tslint-xo/-/tslint-xo-0.11.0.tgz#7cc78eb259823371edc71deff126a23afc28cef9" + integrity sha512-7CiaVI+5LxCtqqW3fl5/orjDmmH1MNTlw1/E2eC71XYengbINokLG1dY/024jofYDdcoWgAtxhVnV6PyNrndnQ== + dependencies: + tslint-consistent-codestyle "^1.14.1" + tslint-eslint-rules "^5.4.0" + tslint-microsoft-contrib "^6.0.0" + +tslint@5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.0.tgz#47f2dba291ed3d580752d109866fb640768fca36" + integrity sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ== + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.27.2" + +tsutils@^2.27.2, tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +"tsutils@^2.27.2 <2.29.0": + version "2.28.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.28.0.tgz#6bd71e160828f9d019b6f4e844742228f85169a1" + integrity sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA== dependencies: - prelude-ls "~1.1.2" + tslib "^1.8.1" + +tsutils@^3.0.0, tsutils@^3.5.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.7.0.tgz#f97bdd2f109070bd1865467183e015b25734b477" + integrity sha512-n+e+3q7Jx2kfZw7tjfI9axEIWBY0sFMOlC+1K70X0SeXpO/UYSB+PN+E9tIJNqViB7oiXQdqD7dNchnvoneZew== + dependencies: + tslib "^1.8.1" + +typescript@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" + integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== union-value@^1.0.0: version "1.0.0" @@ -3180,13 +1894,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - unset-value@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -3195,46 +1902,11 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= - -update-notifier@^2.3.0: - version "2.5.0" - resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - urix@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - use@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -3255,18 +1927,6 @@ which@^1.2.10, which@^1.2.9: dependencies: isexe "^2.0.0" -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== - dependencies: - string-width "^2.1.1" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - wrap-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" @@ -3279,106 +1939,3 @@ wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-json-file@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" - integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - pify "^3.0.0" - sort-keys "^2.0.0" - write-file-atomic "^2.0.0" - -write-pkg@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" - integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== - dependencies: - sort-keys "^2.0.0" - write-json-file "^2.2.0" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= - dependencies: - mkdirp "^0.5.1" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - -xo-init@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/xo-init/-/xo-init-0.7.0.tgz#634b4789e366b4f87f747ef0cee1a99ce273aa15" - integrity sha512-mrrCKMu52vz0u2tiOl8DoG709pBtnSp58bb4/j58a4jeXjrb1gV7dxfOBjOlXitYtfW2QnlxxxfAojoFcpynDg== - dependencies: - arrify "^1.0.0" - execa "^0.9.0" - has-yarn "^1.0.0" - minimist "^1.1.3" - path-exists "^3.0.0" - read-pkg-up "^3.0.0" - the-argv "^1.0.0" - write-pkg "^3.1.0" - -xo@0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/xo/-/xo-0.23.0.tgz#dbc709b0e5e38060a497a39d147a173ddd36d355" - integrity sha512-jyNZrGULm1oPgL0AMWWFWr3Q2cLsULrIkBsogIGWEUw/wGu47N3XGNmUwB4AvJcMhveNK2gqndY3+z8m0CJFEA== - dependencies: - arrify "^1.0.1" - debug "^3.1.0" - eslint "^5.5.0" - eslint-config-prettier "^3.0.1" - eslint-config-xo "^0.25.0" - eslint-formatter-pretty "^1.3.0" - eslint-plugin-ava "^5.1.0" - eslint-plugin-import "^2.14.0" - eslint-plugin-no-use-extend-native "^0.3.12" - eslint-plugin-node "^7.0.0" - eslint-plugin-prettier "^2.6.0" - eslint-plugin-promise "^4.0.0" - eslint-plugin-unicorn "^6.0.1" - get-stdin "^6.0.0" - globby "^8.0.0" - has-flag "^3.0.0" - lodash.isequal "^4.5.0" - lodash.mergewith "^4.6.1" - meow "^5.0.0" - multimatch "^2.1.0" - open-editor "^1.2.0" - path-exists "^3.0.0" - pkg-conf "^2.1.0" - prettier "^1.12.1" - resolve-cwd "^2.0.0" - resolve-from "^4.0.0" - semver "^5.5.0" - slash "^2.0.0" - update-notifier "^2.3.0" - xo-init "^0.7.0" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" From b8928c997e939dadbd6e6a19ad9e56c759fd072f Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 17:54:39 -0800 Subject: [PATCH 50/62] [README] update supported cmds table --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d2bd2b..c9cfa00 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c | Support | Command | Description | | ------------------ | ------------------------------------ | ----------------------------- | -| :x: | \ | Deploy | +| :white_check_mark: | \ | Deploy | | :white_check_mark: | `alias [ls]` | List aliases | | :white_check_mark: | `alias set ` | Create alias | | :white_check_mark: | `alias rm ` | Remove alias | From 212de51eff712c64849516bcc026b06247b4c344 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Mon, 21 Jan 2019 22:24:13 -0800 Subject: [PATCH 51/62] [deploy] set first revision to 1 --- src/deploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deploy.ts b/src/deploy.ts index b599b13..68bbc29 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -106,7 +106,7 @@ export default async () => { revision = generation + 1; } catch (e) { // No deployment exists. - revision = 0; + revision = 1; } // Create a volume for persisting the build context From 67ae3964e098f29c7cef6d3fea889a080f0f5884 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sat, 2 Mar 2019 11:34:05 -0800 Subject: [PATCH 52/62] [index] proper source maps for stack traces --- package.json | 4 +- src/index.ts | 3 + yarn.lock | 465 +++++++++++++++++++++++++++------------------------ 3 files changed, 249 insertions(+), 223 deletions(-) diff --git a/package.json b/package.json index ab28288..f6346da 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,13 @@ "dependencies": { "chalk": "2.4.1", "docker-file-parser": "1.0.4", - "mri": "1.1.1" + "mri": "1.1.1", + "source-map-support": "0.5.10" }, "devDependencies": { "@types/mri": "1.1.0", "@types/node": "10.12.18", + "@types/source-map-support": "0.4.2", "husky": "1.3.1", "lint-staged": "8.1.0", "prettier": "1.15.3", diff --git a/src/index.ts b/src/index.ts index 303d54a..2038668 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,8 @@ #!/usr/bin/env node +import * as sourcemapsupport from 'source-map-support'; +sourcemapsupport.install(); + import * as mri from 'mri'; import alias from './alias'; import certs from './certs'; diff --git a/yarn.lock b/yarn.lock index e1a04de..b991dc8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -47,15 +47,27 @@ resolved "https://registry.yarnpkg.com/@types/mri/-/mri-1.1.0.tgz#66555e4d797713789ea0fefdae0898d8170bf5af" integrity sha512-fMl88ZoZXOB7VKazJ6wUMpZc9QIn+jcigSFRf2K/rrw4DcXn+/uGxlWX8DDlcE7JkwgIZ7BDH+JgxZPlc/Ap3g== +"@types/node@*": + version "11.9.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.9.5.tgz#011eece9d3f839a806b63973e228f85967b79ed3" + integrity sha512-vVjM0SVzgaOUpflq4GYBvCpozes8OgIIS5gVXVka+OfK3hvnkC1i93U8WiY2OtNE4XUWyyy/86Kf6e0IHTQw1Q== + "@types/node@10.12.18": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== +"@types/source-map-support@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@types/source-map-support/-/source-map-support-0.4.2.tgz#5b9f4502183430511bb90e84a6e4bf4214e55a67" + integrity sha512-GbGWx39O8NdUHSChdrU0XeigBAgu1Teg3llwE0slSVcH2qISaQT70ftAiH+h4HIt3VIObFU34PSpXIKJuXCybQ== + dependencies: + "@types/node" "*" + ansi-escapes@^3.0.0: - version "3.1.0" - resolved "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" - integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-regex@^2.0.0: version "2.1.1" @@ -64,7 +76,7 @@ ansi-regex@^2.0.0: ansi-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-styles@^2.2.1: @@ -74,7 +86,7 @@ ansi-styles@^2.2.1: ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" @@ -86,56 +98,56 @@ any-observable@^0.3.0: argparse@^1.0.7: version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" arr-diff@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-union@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= dependencies: array-uniq "^1.0.1" array-uniq@^1.0.1: version "1.0.3" - resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.3.2: version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= arrify@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= atob@^2.1.1: version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== babel-code-frame@^6.22.0: @@ -149,12 +161,12 @@ babel-code-frame@^6.22.0: balanced-match@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base@^0.11.1: version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" @@ -167,7 +179,7 @@ base@^0.11.1: brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -175,7 +187,7 @@ brace-expansion@^1.1.7: braces@^2.3.1: version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" @@ -189,14 +201,19 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -builtin-modules@^1.0.0, builtin-modules@^1.1.1: +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +builtin-modules@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= cache-base@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" @@ -228,9 +245,9 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= -chalk@2.4.1, chalk@^2.0.1, chalk@^2.3.1, chalk@^2.4.1: +chalk@2.4.1: version "2.4.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== dependencies: ansi-styles "^3.2.1" @@ -248,7 +265,7 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.3.0: +chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -264,7 +281,7 @@ ci-info@^2.0.0: class-utils@^0.3.5: version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" @@ -274,7 +291,7 @@ class-utils@^0.3.5: cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" @@ -294,7 +311,7 @@ code-point-at@^1.0.0: collection-visit@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" @@ -302,14 +319,14 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= commander@^2.12.1, commander@^2.14.1, commander@^2.9.0: @@ -319,17 +336,17 @@ commander@^2.12.1, commander@^2.14.1, commander@^2.9.0: component-emitter@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= copy-descriptor@^0.1.0: version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= cosmiconfig@5.0.6: @@ -342,18 +359,19 @@ cosmiconfig@5.0.6: parse-json "^4.0.0" cosmiconfig@^5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" - integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + version "5.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.1.0.tgz#6c5c35e97f37f985061cdf653f114784231185cf" + integrity sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q== dependencies: 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" cross-spawn@^6.0.0: version "6.0.5" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" @@ -369,28 +387,28 @@ date-fns@^1.27.2: debug@^2.2.0, debug@^2.3.3: version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.1.0: version "3.2.6" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" debug@^4.0.1: - version "4.1.0" - resolved "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" - integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" decode-uri-component@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= dedent@^0.7.0: @@ -400,21 +418,21 @@ dedent@^0.7.0: define-property@^0.2.5: version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" @@ -422,7 +440,7 @@ define-property@^2.0.2: del@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= dependencies: globby "^6.1.0" @@ -464,19 +482,19 @@ end-of-stream@^1.1.0: error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= esprima@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esutils@^1.1.6: @@ -486,7 +504,7 @@ esutils@^1.1.6: esutils@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= execa@^1.0.0: @@ -504,7 +522,7 @@ execa@^1.0.0: expand-brackets@^2.1.4: version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" @@ -517,14 +535,14 @@ expand-brackets@^2.1.4: extend-shallow@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" @@ -532,7 +550,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: extglob@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" @@ -554,14 +572,14 @@ figures@^1.7.0: figures@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" fill-range@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" @@ -583,19 +601,19 @@ find-up@^3.0.0: for-in@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= fragment-cache@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= g-status@^2.0.2: @@ -619,7 +637,7 @@ get-own-enumerable-property-symbols@^3.0.0: get-stdin@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== get-stream@^4.0.0: @@ -631,12 +649,12 @@ get-stream@^4.0.0: get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: +glob@^7.0.3, glob@^7.1.1, glob@^7.1.3: version "7.1.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" @@ -648,7 +666,7 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: globby@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= dependencies: array-union "^1.0.1" @@ -666,12 +684,12 @@ has-ansi@^2.0.0: has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-value@^0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" @@ -680,7 +698,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" @@ -689,12 +707,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" @@ -702,7 +720,7 @@ has-values@^1.0.0: hosted-git-info@^2.1.4: version "2.7.1" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== husky@1.3.1: @@ -731,12 +749,12 @@ import-fresh@^2.0.0: indent-string@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" @@ -744,7 +762,7 @@ inflight@^1.0.4: inherits@2: version "2.0.3" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= inversify@^5.0.0: @@ -754,35 +772,28 @@ inversify@^5.0.0: is-accessor-descriptor@^0.1.6: version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-buffer@^1.1.5: version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= - dependencies: - builtin-modules "^1.0.0" - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -792,21 +803,21 @@ is-ci@^2.0.0: is-data-descriptor@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-descriptor@^0.1.0: version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" @@ -815,7 +826,7 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" @@ -829,19 +840,19 @@ is-directory@^0.3.1: is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^1.0.0: @@ -853,26 +864,26 @@ is-fullwidth-code-point@^1.0.0: is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-glob@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= dependencies: is-extglob "^2.1.1" is-number@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-obj@^1.0.1: version "1.0.1" - resolved "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-observable@^1.1.0: @@ -884,33 +895,33 @@ is-observable@^1.1.0: is-path-cwd@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= is-path-in-cwd@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== dependencies: is-path-inside "^1.0.0" is-path-inside@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= dependencies: path-is-inside "^1.0.1" is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-promise@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-regexp@^1.0.0: @@ -920,12 +931,12 @@ is-regexp@^1.0.0: is-stream@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-windows@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@0.0.1: @@ -935,24 +946,24 @@ isarray@0.0.1: isarray@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= jest-get-type@^22.1.0: @@ -975,49 +986,41 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.7.0: - version "3.12.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" - integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.9.0: - version "3.12.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" - integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== +js-yaml@^3.7.0, js-yaml@^3.9.0: + version "3.12.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.2.tgz#ef1d067c5a9d9cb65bd72f285b5d8105c77f14fc" + integrity sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q== dependencies: argparse "^1.0.7" esprima "^4.0.0" json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== leven@^2.1.0: @@ -1108,9 +1111,14 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + lodash@^4.17.5: version "4.17.11" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== log-symbols@^1.0.2: @@ -1122,7 +1130,7 @@ log-symbols@^1.0.2: log-symbols@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== dependencies: chalk "^2.0.1" @@ -1138,12 +1146,12 @@ log-update@^2.3.0: map-cache@^0.2.2: version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-visit@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" @@ -1157,7 +1165,7 @@ matcher@^1.0.0: micromatch@^3.1.8: version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" @@ -1176,19 +1184,19 @@ micromatch@^3.1.8: mimic-fn@^1.0.0: version "1.2.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== minimatch@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" mixin-deep@^1.2.0: version "1.3.1" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" @@ -1196,22 +1204,22 @@ mixin-deep@^1.2.0: mri@1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1" integrity sha1-haom09ru7t+A3FmEr5XMXKXK2fE= ms@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== nanomatch@^1.2.9: version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" @@ -1228,16 +1236,16 @@ nanomatch@^1.2.9: nice-try@^1.0.4: version "1.0.5" - resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== normalize-package-data@^2.3.2: - version "2.4.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: 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" @@ -1250,7 +1258,7 @@ npm-path@^2.0.2: npm-run-path@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" @@ -1271,12 +1279,12 @@ number-is-nan@^1.0.0: object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" @@ -1285,35 +1293,35 @@ object-copy@^0.1.0: object-visit@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.pick@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-limit@^2.0.0: @@ -1332,7 +1340,7 @@ p-locate@^3.0.0: p-map@^1.1.1: version "1.2.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== p-map@^2.0.0: @@ -1347,7 +1355,7 @@ p-try@^2.0.0: parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= dependencies: error-ex "^1.3.1" @@ -1355,27 +1363,27 @@ parse-json@^4.0.0: pascalcase@^0.1.1: version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-is-absolute@^1.0.0: version "1.0.1" - resolved "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.6: @@ -1385,24 +1393,24 @@ path-parse@^1.0.6: pify@^2.0.0: version "2.3.0" - resolved "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" - resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pkg-dir@^3.0.0: @@ -1421,7 +1429,7 @@ please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: posix-character-classes@^0.1.0: version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= prettier@1.15.3: @@ -1461,7 +1469,7 @@ reflect-metadata@^0.1.12: regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" @@ -1469,34 +1477,34 @@ regex-not@^1.0.0, regex-not@^1.0.2: repeat-element@^1.1.2: version "1.1.3" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.6.1: version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= resolve-from@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha1-six699nWiBvItuZTM17rywoYh0g= resolve-url@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.3.2: - version "1.9.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" - integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== +resolve@^1.10.0, resolve@^1.3.2: + version "1.10.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" + integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== dependencies: path-parse "^1.0.6" restore-cursor@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" @@ -1504,15 +1512,15 @@ restore-cursor@^2.0.0: ret@~0.1.10: version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== rimraf@^2.2.8: - version "2.6.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: - glob "^7.0.5" + glob "^7.1.3" run-node@^1.0.0: version "1.0.0" @@ -1520,15 +1528,15 @@ run-node@^1.0.0: integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== rxjs@^6.3.3: - version "6.3.3" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" - integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== dependencies: tslib "^1.9.0" safe-regex@^1.1.0: version "1.1.0" - resolved "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" @@ -1540,12 +1548,12 @@ semver-compare@^1.0.0: "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: version "5.6.0" - resolved "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== set-value@^0.4.3: version "0.4.3" - resolved "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" @@ -1555,7 +1563,7 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" @@ -1565,19 +1573,19 @@ set-value@^2.0.0: shebang-command@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= simple-git@^1.85.0: @@ -1589,7 +1597,7 @@ simple-git@^1.85.0: slash@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== slice-ansi@0.0.4: @@ -1599,7 +1607,7 @@ slice-ansi@0.0.4: snapdragon-node@^2.0.1: version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" @@ -1608,14 +1616,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" @@ -1629,7 +1637,7 @@ snapdragon@^0.8.1: source-map-resolve@^0.5.0: version "0.5.2" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: atob "^2.1.1" @@ -1638,52 +1646,65 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@0.5.10: + version "0.5.10" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.10.tgz#2214080bc9d51832511ee2bab96e3c2f9353120c" + integrity sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.5.6: version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + spdx-correct@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" - integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: version "2.2.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== spdx-expression-parse@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" - integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= staged-git-files@1.1.2: @@ -1693,7 +1714,7 @@ staged-git-files@1.1.2: static-extend@^0.1.1: version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" @@ -1715,7 +1736,7 @@ string-width@^1.0.1: string-width@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" @@ -1739,14 +1760,14 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-eof@^1.0.0: version "1.0.0" - resolved "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= supports-color@^2.0.0: @@ -1756,7 +1777,7 @@ supports-color@^2.0.0: supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" @@ -1768,14 +1789,14 @@ symbol-observable@^1.1.0: to-object-path@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" @@ -1783,7 +1804,7 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" @@ -1798,7 +1819,7 @@ tslib@1.9.0: tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== tslint-config-prettier@1.17.0: @@ -1873,9 +1894,9 @@ tsutils@^2.27.2, tsutils@^2.29.0: tslib "^1.8.1" tsutils@^3.0.0, tsutils@^3.5.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.7.0.tgz#f97bdd2f109070bd1865467183e015b25734b477" - integrity sha512-n+e+3q7Jx2kfZw7tjfI9axEIWBY0sFMOlC+1K70X0SeXpO/UYSB+PN+E9tIJNqViB7oiXQdqD7dNchnvoneZew== + version "3.8.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.8.0.tgz#7a3dbadc88e465596440622b65c04edc8e187ae5" + integrity sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA== dependencies: tslib "^1.8.1" @@ -1886,7 +1907,7 @@ typescript@3.2.2: union-value@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" @@ -1896,7 +1917,7 @@ union-value@^1.0.0: unset-value@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" @@ -1904,17 +1925,17 @@ unset-value@^1.0.0: urix@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= use@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -1922,7 +1943,7 @@ validate-npm-package-license@^3.0.1: which@^1.2.10, which@^1.2.9: version "1.3.1" - resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" @@ -1937,5 +1958,5 @@ wrap-ansi@^3.0.1: wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= From 9cd5083279ad6a0d18ec777fbe221f114d6dbc05 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sat, 2 Mar 2019 11:35:21 -0800 Subject: [PATCH 53/62] [utils] run: add silent option --- src/utils.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index c4243e4..35deb9f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -97,11 +97,16 @@ interface IRunResolve { export async function run( str: string, - opts?: childProcess.ExecOptions + opts?: childProcess.ExecOptions & { + silent?: boolean; + } ) : Promise { const runString = str.replace(/(\s+)/gm, ' ').trim(); + const silent = opts ? opts.silent : false; - logInfo(`> ${runString}`); + if (!silent) { + logInfo(`> ${runString}`); + } return new Promise((resolve, reject) => { function callback( @@ -110,10 +115,12 @@ export async function run( stderr: string | Buffer ) { if (error) { - process.stderr.write(chalk.red(error.message)); + if (!silent) { + process.stderr.write(chalk.red(error.message)); - if (error.stack) { - process.stderr.write(chalk.white(error.stack)); + if (error.stack) { + process.stderr.write(chalk.white(error.stack)); + } } return reject(error); @@ -127,6 +134,10 @@ export async function run( const cmd = childProcess.exec(str, opts, callback); + if (silent) { + return; + } + cmd.stderr.on('data', (data: string) => { process.stdout.write(chalk.gray(data)); }); From df67b0185adae6e753aaafb7c02add025a04b2aa Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sat, 2 Mar 2019 11:39:08 -0800 Subject: [PATCH 54/62] [src] digital ocean support --- src/alias.ts | 4 + src/create.ts | 543 +++++++++++++++++++++++++++++++---------------- src/deploy.ts | 2 +- src/install.ts | 11 +- src/login.ts | 11 +- src/providers.ts | 4 +- 6 files changed, 380 insertions(+), 195 deletions(-) diff --git a/src/alias.ts b/src/alias.ts index 58b22d9..b7bff8f 100644 --- a/src/alias.ts +++ b/src/alias.ts @@ -94,6 +94,10 @@ export default async (subcommand?: string, aliasOrDeploymentPrefix?: string, hos ingressSpec.rules[ruleIndex] = rule; } + if (!ingressSpec.tls) { + ingressSpec.tls = []; + } + // See if an existing TLS entry exists. const tlsIndex = ingressSpec.tls.findIndex(hasExistingTLSFactory(hostname)); if (tlsIndex === -1) { diff --git a/src/create.ts b/src/create.ts index 7c26928..df29437 100644 --- a/src/create.ts +++ b/src/create.ts @@ -110,210 +110,377 @@ export default async () => { if (!clusterExists) { await run(createClusterCmd); } - - /* - * Install helm with TLS. - * https://medium.com/google-cloud/install-secure-helm-in-gke-254d520061f7 - */ - - const BYTES = 2048; - - // Create Certificate Authority - await run(`openssl genrsa -out $(helm home)/ca.key.pem ${BYTES}`); - const config = ` - [req]\\n - req_extensions=v3_ca\\n - distinguished_name=req_distinguished_name\\n - [req_distinguished_name]\\n - [ v3_ca ]\\n - basicConstraints=critical,CA:TRUE\\n - subjectKeyIdentifier=hash\\n - authorityKeyIdentifier=keyid:always,issuer:always`; - await run( - ` - openssl req \\ - -config <(printf '${config}') \\ - -key $(helm home)/ca.key.pem \\ - -new \\ - -x509 \\ - -days 7300 \\ - -sha256 \\ - -out $(helm home)/ca.cert.pem \\ - -extensions v3_ca \\ - -subj "/C=US"`, - { shell: '/bin/bash' } + break; + } + case 'digitalocean': { + // Authenticate. + logInfo('Obtain a Digital Ocean access token here: https://cloud.digitalocean.com/account/api/tokens'); + const token = await askForInput( + 'Enter your digital ocean access token' ); + await run(`doctl auth init -t ${token}`); - // Create credentials for tiller (server) - await run(`openssl genrsa -out $(helm home)/tiller.key.pem ${BYTES}`); - await run( - ` - openssl req \ - -new \ - -sha256 \ - -key $(helm home)/tiller.key.pem \ - -out $(helm home)/tiller.csr.pem \ - -subj "/C=US/O=Snow/CN=tiller-server"`, - { shell: '/bin/bash' } - ); - const tillerConfig = ` - [SAN]\\n - subjectAltName=IP:127.0.0.1`; - await run( - ` - openssl x509 -req -days 365 \ - -CA $(helm home)/ca.cert.pem \ - -CAkey $(helm home)/ca.key.pem \ - -CAcreateserial \ - -in $(helm home)/tiller.csr.pem \ - -out $(helm home)/tiller.cert.pem \ - -extfile <(printf '${tillerConfig}') \ - -extensions SAN`, - { shell: '/bin/bash' } - ); + // Check if we have an existing cluster. + let clusterExists = true; + try { + await run('doctl k8s cluster get snow-cluster', {silent: true}); + } catch (e) { + clusterExists = false; + } - // Create credentials for helm (client) - await run(`openssl genrsa -out $(helm home)/helm.key.pem ${BYTES}`); - await run(` - openssl req -new -sha256 \ - -key $(helm home)/helm.key.pem \ - -out $(helm home)/helm.csr.pem \ - -subj "/C=US" - `); - await run(` - openssl x509 -req -days 365 \ - -CA $(helm home)/ca.cert.pem \ - -CAkey $(helm home)/ca.key.pem \ - -CAcreateserial \ - -in $(helm home)/helm.csr.pem \ - -out $(helm home)/helm.cert.pem - `); + const region = 'nyc1'; + const name = 'snow-cluster'; - // Create service account and clusterrolebinding - await run(`kubectl create serviceaccount \ - --namespace kube-system tiller - `); - await run(`kubectl create clusterrolebinding \ - tiller-cluster-rule \ - --clusterrole=cluster-admin \ - --serviceaccount=kube-system:tiller - `); + if (!clusterExists) { + // Create the cluster. + logInfo('Creating cluster. This will take a few minutes...'); + await run(` + doctl k8s clusters create ${name} \ + --region ${region} \ + --version 1.13.1-do.2 \ + --node-pool "name=node-pool-0;size=s-1vcpu-2gb;count=2" \ + --wait + `); + } else { + logInfo('Cluster exists.'); + } - // Install Helm w/ 'tiller' service account - await run(` - helm init \ - --debug \ - --tiller-tls \ - --tiller-tls-cert $(helm home)/tiller.cert.pem \ - --tiller-tls-key $(helm home)/tiller.key.pem \ - --tiller-tls-verify \ - --tls-ca-cert $(helm home)/ca.cert.pem \ - --service-account tiller \ - --wait - `); + await run(`kubectl config use-context do-${region}-${name}`); - // Verify helm installation - await run(` - helm ls --tls \ - --tls-ca-cert $(helm home)/ca.cert.pem \ - --tls-cert $(helm home)/helm.cert.pem \ - --tls-key $(helm home)/helm.key.pem - `); + break; + } + default: { + logError('No valid cloud provider selected.'); + } + } - /** - * - * To remove helm: - * - * helm reset - * --tls - * --tls-ca-cert $(helm home)/ca.cert.pem - * --tls-cert $(helm home)/helm.cert.pem - * --tls-key $(helm home)/helm.key.pem - */ - - // Install nginx ingress - await run(` - helm install stable/nginx-ingress \ - --tls \ - --tls-ca-cert $(helm home)/ca.cert.pem \ - --tls-cert $(helm home)/helm.cert.pem \ - --tls-key $(helm home)/helm.key.pem \ - --namespace kube-system \ - --name nginx-ingress \ - --set controller.ingressClass=nginx \ - --set rbac.create=true - `); + /* + * Authentication complete + * Cluster exists + * kubeconfig has properly configured auth credentials + * Now the fun part: time to set up Kubernetes! + */ - // Install cert-manager - await run(` - helm install stable/cert-manager \ - --tls \ - --tls-ca-cert $(helm home)/ca.cert.pem \ - --tls-cert $(helm home)/helm.cert.pem \ - --tls-key $(helm home)/helm.key.pem \ - --namespace kube-system \ - --name cert-manager \ - --set ingressShim.defaultIssuerName=letsencrypt-prod \ - --set ingressShim.defaultIssuerKind=ClusterIssuer - `); + /* + * Install helm with TLS. + * https://medium.com/google-cloud/install-secure-helm-in-gke-254d520061f7 + */ + await run('helm init --client-only'); - let email = await askForInput( - 'Provide an email address for Let\'s Encrypt' - ); - while (!(await confirm(`Confirm email: "${email}"`))) { - email = await askForInput('Provide an email address for Let\'s Encrypt'); - } + const BYTES = 2048; - // Create cluster issuer - await run(` - cat < { "args": [ "--context=dir:///kaniko/build-context", "--destination=${imageName}", - "--insecure" + "--skip-tls-verify" ], "volumeMounts": [ { diff --git a/src/install.ts b/src/install.ts index 188ad13..d38d4c1 100644 --- a/src/install.ts +++ b/src/install.ts @@ -20,7 +20,7 @@ export default async () => { installCmd: 'brew cask install docker' }, { - label: 'Kubernetes', + label: 'Kubernetes (kubectl)', detectCmd: 'which kubectl', installCmd: 'brew install kubernetes-cli' }, @@ -46,7 +46,12 @@ export default async () => { detectAdvanced: output => { return output.indexOf('Not Installed | gcloud Beta Commands') > -1; } - } + }, + { + label: 'Digital Ocean CLI (doctl)', + detectCmd: 'which doctl', + installCmd: 'brew install doctl' + }, ]; async function tryInstall(label: string, installCmd: string) { @@ -57,7 +62,7 @@ export default async () => { for (const { label, detectCmd, detectAdvanced, installCmd } of dependencies) { try { - const { stdout } = await run(detectCmd); + const { stdout } = await run(detectCmd, {silent: true}); if (detectAdvanced && detectAdvanced(stdout)) { await tryInstall(label, installCmd); } diff --git a/src/login.ts b/src/login.ts index 6e3ce51..772b2bb 100644 --- a/src/login.ts +++ b/src/login.ts @@ -1,5 +1,5 @@ import cloudProviders from './providers'; -import { logError, pickOne, run } from './utils'; +import { askForInput, logError, logInfo, pickOne, run } from './utils'; export default async () => { const question = 'Which cloud provider do you want to login to'; @@ -35,6 +35,15 @@ export default async () => { ); break; } + case 'digitalocean': { + logInfo('Obtain a Digital Ocean access token here: https://cloud.digitalocean.com/account/api/tokens'); + const token = await askForInput( + 'Enter your digital ocean access token' + ); + await run(`doctl auth init -t ${token}`); + await run('doctl k8s cluster kubeconfig save snow-cluster'); + break; + } default: { logError('No valid cloud provider selected.'); } diff --git a/src/providers.ts b/src/providers.ts index 0a5214a..344296a 100644 --- a/src/providers.ts +++ b/src/providers.ts @@ -1,4 +1,4 @@ -type Provider = 'minikube' | 'gcp'; -const cloudProviders: Provider[] = ['minikube', 'gcp']; +type Provider = 'minikube' | 'gcp' | 'digitalocean'; +const cloudProviders: Provider[] = ['minikube', 'gcp', 'digitalocean']; export default cloudProviders; From 54202bc84fa5986334be9c8c234c2530d6c5b4a8 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sun, 3 Mar 2019 20:47:47 -0800 Subject: [PATCH 55/62] [create] copy docker cert to pods daily --- src/create.ts | 88 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/src/create.ts b/src/create.ts index df29437..2a7648c 100644 --- a/src/create.ts +++ b/src/create.ts @@ -429,9 +429,10 @@ export default async () => { --tls-key $(helm home)/helm.key.pem \ --namespace default \ --name docker-registry \ + --version 1.7.0 \ --set secrets.htpasswd='user:$2y$05$8nR6bYM2ZKR0tkmJ9KEVTeWVVk77sucXVwZQp2q49t6sR0Oip346C' \ --set persistence.enabled=true \ - --set persistence.existingClaim='docker-registry-pvc' + --set persistence.existingClaim='docker-registry-pvc' \ --set tlsSecretName='docker-reg-cert-secret' `); @@ -448,10 +449,8 @@ export default async () => { }, "spec": { "secretName": "docker-reg-cert-secret", - "commonName": "${dockerIP}", - "ipAddresses": [ - "${dockerIP}" - ], + "commonName": "docker-registry.default.svc.cluster.local", + "ipAddresses": ["${dockerIP}"], "isCA": true, "issuerRef": { "name": "selfsigning-issuer", @@ -461,6 +460,85 @@ export default async () => { } \nEOF`); + /* + * Copy certificate to node VMs daily (to stop the docker + * daemon from throwing TLS errors when pulling images) + * + * You can't mount to a folder to a colon in it, so we copy + * to a temp folder, rename tls.crt to tls.cert (to make the + * docker daemon happy), and then place the files in a folder + * expected by the daemon. + */ + await run(` + cat < Date: Tue, 5 Mar 2019 18:18:22 -0800 Subject: [PATCH 56/62] add demo image --- README.md | 1 + demo.png | Bin 0 -> 182999 bytes 2 files changed, 1 insertion(+) create mode 100644 demo.png diff --git a/README.md b/README.md index c9cfa00..d20b38c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@
+
> :snowflake: **S**elf-hosted **now** deployments diff --git a/demo.png b/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..d6f186b27e8226a321b5567ec9760a59e34864d5 GIT binary patch literal 182999 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 rt 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 Date: Tue, 5 Mar 2019 18:19:58 -0800 Subject: [PATCH 57/62] [README] shell syntax highlighting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d20b38c..4052870 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ No, it isn't. This CLI abstracts away the complexities of using [Kubernetes], [c ### Getting started -``` +```sh > npm i -g @snowjs/cli # Install CLI tools From 6276b26a2f3d8eb8c1a3e72d8655626328154500 Mon Sep 17 00:00:00 2001 From: 0xflotus <0xflotus@gmail.com> Date: Fri, 3 May 2019 00:27:08 +0200 Subject: [PATCH 58/62] Secrets (#20) * Update commands.md * Update comparison.md --- docs/commands.md | 4 ++-- docs/comparison.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 1e25d65..32ceac2 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -44,7 +44,7 @@ Creates a Kubernetes cluster to host your deployments. - The type of service is `LoadBalancer`. - Used for mapping hostnames to deployments. - All HTTP traffic is permanently redirected (HTTP 308) to HTTPS. - - SSL terminiation occurs prior to requests reaching deployments. + - SSL termination occurs prior to requests reaching deployments. ## snow [deploy] @@ -84,7 +84,7 @@ Verifies DNS records are configure properly for `domain`. Creates rule to redire Removes any traffic redirect rules from `domain`. Removes SSL termination with the Let's Encrypt SSL certificate for `domain` (the [default certificate] will be used instead). -The Let's Encrypt SSL certificate will remain persistented (which is helpful if the domain is added later, and it avoids an unnecessary request for a new certificate: requests are limited by Let's Encrypt [rate limits]). Traffic from `domain` will redirect to the [default backend]. +The Let's Encrypt SSL certificate will remain persisted (which is helpful if the domain is added later, and it avoids an unnecessary request for a new certificate: requests are limited by Let's Encrypt [rate limits]). Traffic from `domain` will redirect to the [default backend]. ## snow install diff --git a/docs/comparison.md b/docs/comparison.md index 937788b..3720bb7 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -34,7 +34,7 @@ Today, Serverless lambdas are out of scope for `snow`. Costs will vary depend on which cloud you choose. These are minimal costs-- in a production setting, you might want a minimum of 2 compute instances, for example, to ensure high availability. -Cost table for Google Cloud Plaform in region `us-east4`. +Cost table for Google Cloud Platform in region `us-east4`. | Resource | Count | Cost | | ----------------------------------------- | ----- | ---------- | From c15b45510e87f58d58c43bbb56fff04dd33729f3 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sun, 18 Aug 2019 20:31:41 -0700 Subject: [PATCH 59/62] chore: watch mode - don't clear console --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f6346da..487fdca 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "tsc", - "watch": "tsc --watch", + "watch": "tsc --watch --preserveWatchOutput", "lint": "tslint -p . --format stylish" }, "bin": { From f6fea99890cc4c07ace6e9268216827c470ed3ff Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sun, 18 Aug 2019 20:51:28 -0700 Subject: [PATCH 60/62] fix(deploy): use v0.7.0 kaniko image --- src/deploy.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/deploy.ts b/src/deploy.ts index e2eaabf..d89f75c 100644 --- a/src/deploy.ts +++ b/src/deploy.ts @@ -102,7 +102,7 @@ export default async () => { const {stdout: deploymentStr} = await run(`kubectl get deployments/${name} -o json`); // Deployment exists. Update it. deployment = JSON.parse(deploymentStr); - const {metadata: {generation}} = JSON.parse(deploymentStr); + const {metadata: {generation}} : IDeployment = JSON.parse(deploymentStr); revision = generation + 1; } catch (e) { // No deployment exists. @@ -179,7 +179,7 @@ export default async () => { await run(`tar cvfz buildcontext.tar.gz Dockerfile ${files.join(' ')}`); // Wait for pod to be ready. - await run(`kubectl wait pods/${podName} --timeout=60s --for condition=Ready`); + await run(`kubectl wait pods/${podName} --timeout=${2 * 60}s --for condition=Ready`); // Copy build context to container await run(`kubectl cp -c ${contName} buildcontext.tar.gz ${podName}:/tmp/buildcontext.tar.gz`); @@ -234,7 +234,7 @@ export default async () => { "containers": [ { "name": "kaniko", - "image": "gcr.io/kaniko-project/executor:latest", + "image": "gcr.io/kaniko-project/executor:v0.7.0", "args": [ "--context=dir:///kaniko/build-context", "--destination=${imageName}", @@ -259,7 +259,7 @@ export default async () => { \nEOF`); // Wait for Kaniko to complete / push to Docker registry. - await run(`kubectl wait jobs/${kanikoJobName} --timeout=120s --for=condition=complete`); + await run(`kubectl wait jobs/${kanikoJobName} --timeout=${15 * 60}s --for=condition=complete`); // Cleanup // Delete kaniko pod and PVC. From 2be0eb847bee966af734989c6483cb5e3e7d6459 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sun, 18 Aug 2019 20:52:14 -0700 Subject: [PATCH 61/62] fix(config): add port to Dockerfile --- config/build-context/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/config/build-context/Dockerfile b/config/build-context/Dockerfile index 5ef646a..ac52609 100644 --- a/config/build-context/Dockerfile +++ b/config/build-context/Dockerfile @@ -1,2 +1,3 @@ FROM nginx:alpine COPY index.html /usr/share/nginx/html/index.html +EXPOSE 80 \ No newline at end of file From 9ae140471e9861e0bedbe11c8c61e5992e189920 Mon Sep 17 00:00:00 2001 From: Peter Mikitsh Date: Sun, 18 Aug 2019 20:53:28 -0700 Subject: [PATCH 62/62] feat(create): Add azure support, --skip-provision option --- src/create.ts | 294 ++++++++++++++++++++++++++--------------------- src/index.ts | 4 +- src/providers.ts | 4 +- 3 files changed, 168 insertions(+), 134 deletions(-) diff --git a/src/create.ts b/src/create.ts index 2a7648c..cfde99e 100644 --- a/src/create.ts +++ b/src/create.ts @@ -2,155 +2,189 @@ import * as path from 'path'; import cloudProviders from './providers'; import { askForInput, confirm, logError, logInfo, pickOne, run } from './utils'; -export default async () => { +interface IOptions { + 'skip-provision'?: boolean; +} + +export default async (opts: IOptions) => { const question = 'Which cloud provider are you hosting with'; const provider = await pickOne(question, cloudProviders); - switch (provider) { - case 'minikube': { - logInfo('Note: Minikube is for development purposes only.'); + if (!opts['skip-provision']) { + switch (provider) { + case 'minikube': { + logInfo('Note: Minikube is for development purposes only.'); + + // Start minikube if it isn't running + try { + await run('minikube status'); + } catch (error) { + logInfo('Starting Minikube. This may take a minute.'); + await run('minikube start'); + } - // Start minikube if it isn't running - try { - await run('minikube status'); - } catch (error) { - logInfo('Starting Minikube. This may take a minute.'); - await run('minikube start'); - } + await run('minikube addons enable ingress'); + await run('helm init --wait'); - await run('minikube addons enable ingress'); - await run('helm init --wait'); - - const { stdout: minikubeIP } = await run('minikube ip'); - - // Install traefik - await run(` - helm install stable/traefik \ - --name traefik \ - --namespace kube-system \ - --set serviceType=NodePort \ - --set dashboard.enabled=true \ - --set dashboard.domain=traefik-ui.minikube - `); - const traefikHost = `${minikubeIP} traefik-ui.minikube`; - logInfo( - `Add "${traefikHost}" to your hosts file to access traefik's dashboard.` - ); - - // Install docker registry - await run('helm install stable/docker-registry'); - - if (await confirm('Install an example app on Minikube')) { - const deployFile = path.resolve( - __dirname, - '../config/deployment-minikube.yaml' - ); - await run(`kubectl apply -f ${deployFile}`); - const whoAmIHost = `${minikubeIP} whoami.minikube`; + const { stdout: minikubeIP } = await run('minikube ip'); + + // Install traefik + await run(` + helm install stable/traefik \ + --name traefik \ + --namespace kube-system \ + --set serviceType=NodePort \ + --set dashboard.enabled=true \ + --set dashboard.domain=traefik-ui.minikube + `); + const traefikHost = `${minikubeIP} traefik-ui.minikube`; logInfo( - `Add "${whoAmIHost}" to your hosts file to access example app.` + `Add "${traefikHost}" to your hosts file to access traefik's dashboard.` ); - } - const completeMsg = - 'Creation complete. It may take a few minutes for services to become available.'; - logInfo(completeMsg); - break; - } - case 'gcp': { - // Check if we need to authenticate. - try { - const { stdout } = await run('gcloud auth list'); - const isAuthenticated = stdout.indexOf('*') > -1; - if (!isAuthenticated) { - await run('gcloud auth login'); + // Install docker registry + await run('helm install stable/docker-registry'); + + if (await confirm('Install an example app on Minikube')) { + const deployFile = path.resolve( + __dirname, + '../config/deployment-minikube.yaml' + ); + await run(`kubectl apply -f ${deployFile}`); + const whoAmIHost = `${minikubeIP} whoami.minikube`; + logInfo( + `Add "${whoAmIHost}" to your hosts file to access example app.` + ); } - } catch (error) { - await run('gcloud auth login'); - } - const { stdout: projectId } = await run( - 'gcloud config get-value project' - ); - await run('gcloud services enable container.googleapis.com'); - - // Check if we have an existing cluster - let clusterExists = false; - const { stdout: clusterData } = await run( - 'gcloud container clusters list' - ); - if (clusterData.indexOf('snow-cluster') > -1) { - clusterExists = true; + const completeMsg = + 'Creation complete. It may take a few minutes for services to become available.'; + logInfo(completeMsg); + break; } + case 'gcp': { + // Check if we need to authenticate. + try { + const { stdout } = await run('gcloud auth list'); + const isAuthenticated = stdout.indexOf('*') > -1; + if (!isAuthenticated) { + await run('gcloud auth login'); + } + } catch (error) { + await run('gcloud auth login'); + } - const createClusterCmd = ` - gcloud beta container \ - clusters create "snow-cluster" \ - --zone "us-west1-b" \ - --no-enable-basic-auth \ - --cluster-version "1.10.9-gke.5" \ - --image-type "COS" \ - --machine-type "f1-micro" \ - --disk-type "pd-standard" \ - --disk-size "10" \ - --default-max-pods-per-node "110" \ - --num-nodes "3" \ - --enable-cloud-logging \ - --enable-cloud-monitoring \ - --enable-ip-alias \ - --network "projects/${projectId}/global/networks/default" \ - --subnetwork "projects/${projectId}/regions/us-west1/subnetworks/default" \ - --default-max-pods-per-node "110" \ - --addons HorizontalPodAutoscaling,HttpLoadBalancing \ - --enable-autoupgrade \ - --enable-autorepair \ - --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/trace.append" \ - `; - - if (!clusterExists) { - await run(createClusterCmd); - } - break; - } - case 'digitalocean': { - // Authenticate. - logInfo('Obtain a Digital Ocean access token here: https://cloud.digitalocean.com/account/api/tokens'); - const token = await askForInput( - 'Enter your digital ocean access token' - ); - await run(`doctl auth init -t ${token}`); - - // Check if we have an existing cluster. - let clusterExists = true; - try { - await run('doctl k8s cluster get snow-cluster', {silent: true}); - } catch (e) { - clusterExists = false; + const { stdout: projectId } = await run( + 'gcloud config get-value project' + ); + await run('gcloud services enable container.googleapis.com'); + + // Check if we have an existing cluster + let clusterExists = false; + const { stdout: clusterData } = await run( + 'gcloud container clusters list' + ); + if (clusterData.indexOf('snow-cluster') > -1) { + clusterExists = true; + } + + const createClusterCmd = ` + gcloud beta container \ + clusters create "snow-cluster" \ + --zone "us-west1-b" \ + --no-enable-basic-auth \ + --cluster-version "1.10.9-gke.5" \ + --image-type "COS" \ + --machine-type "f1-micro" \ + --disk-type "pd-standard" \ + --disk-size "10" \ + --default-max-pods-per-node "110" \ + --num-nodes "3" \ + --enable-cloud-logging \ + --enable-cloud-monitoring \ + --enable-ip-alias \ + --network "projects/${projectId}/global/networks/default" \ + --subnetwork "projects/${projectId}/regions/us-west1/subnetworks/default" \ + --default-max-pods-per-node "110" \ + --addons HorizontalPodAutoscaling,HttpLoadBalancing \ + --enable-autoupgrade \ + --enable-autorepair \ + --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/trace.append" \ + `; + + if (!clusterExists) { + await run(createClusterCmd); + } + break; } + case 'digitalocean': { + // Authenticate. + logInfo('Obtain a Digital Ocean access token here: https://cloud.digitalocean.com/account/api/tokens'); + const token = await askForInput( + 'Enter your digital ocean access token' + ); + await run(`doctl auth init -t ${token}`); + + // Check if we have an existing cluster. + let clusterExists = true; + try { + await run('doctl k8s cluster get snow-cluster', {silent: true}); + } catch (e) { + clusterExists = false; + } - const region = 'nyc1'; - const name = 'snow-cluster'; + const region = 'nyc1'; + const name = 'snow-cluster'; + + if (!clusterExists) { + // Create the cluster. + logInfo('Creating cluster. This will take a few minutes...'); + await run(` + doctl k8s clusters create ${name} \ + --region ${region} \ + --version 1.13.1-do.2 \ + --node-pool "name=node-pool-0;size=s-1vcpu-2gb;count=2" \ + --wait + `); + } else { + logInfo('Cluster exists.'); + } - if (!clusterExists) { - // Create the cluster. - logInfo('Creating cluster. This will take a few minutes...'); + await run(`kubectl config use-context do-${region}-${name}`); + + break; + } + case 'azure': { + const resourceGroup = 'snow'; + const clusterName = 'snow-cluster'; + // Create the resource group. await run(` - doctl k8s clusters create ${name} \ - --region ${region} \ - --version 1.13.1-do.2 \ - --node-pool "name=node-pool-0;size=s-1vcpu-2gb;count=2" \ - --wait + az group create + -n ${resourceGroup} \ + -l westus \ `); - } else { - logInfo('Cluster exists.'); - } - await run(`kubectl config use-context do-${region}-${name}`); + // Create the cluster. + await run(` + az aks create \ + -n ${clusterName} \ + -g ${resourceGroup} \ + --no-ssh-key \ + -k 1.14.5 \ + --node-count 2 + `); - break; - } - default: { - logError('No valid cloud provider selected.'); + // Get credentials. + await run(` + az aks get-credentials \ + -g ${resourceGroup} \ + -n ${clusterName} + `); + break; + } + default: { + logError('No valid cloud provider selected.'); + } } } diff --git a/src/index.ts b/src/index.ts index 2038668..0b71e4e 100755 --- a/src/index.ts +++ b/src/index.ts @@ -20,7 +20,7 @@ import secrets from './secrets'; import { logError } from './utils'; async function main() { - const { _ } = mri(process.argv.slice(2)); + const { _, ...opts } = mri(process.argv.slice(2)); const [command, ...rest] = _; switch (command) { @@ -33,7 +33,7 @@ async function main() { break; } case 'create': { - await create(); + await create(opts); break; } case undefined: diff --git a/src/providers.ts b/src/providers.ts index 344296a..e8772d6 100644 --- a/src/providers.ts +++ b/src/providers.ts @@ -1,4 +1,4 @@ -type Provider = 'minikube' | 'gcp' | 'digitalocean'; -const cloudProviders: Provider[] = ['minikube', 'gcp', 'digitalocean']; +type Provider = 'minikube' | 'gcp' | 'digitalocean' | 'azure'; +const cloudProviders: Provider[] = ['minikube', 'gcp', 'digitalocean', 'azure']; export default cloudProviders;