From c2e2c7d3058ef3903debe832cd3cd5aa1773dd5f Mon Sep 17 00:00:00 2001 From: EGOIST <0x142857@gmail.com> Date: Wed, 9 Jan 2019 23:31:27 +0800 Subject: [PATCH] feat: use enquirer --- README.md | 8 +-- __test__/index.test.js | 4 +- docs/README.md | 9 +-- docs/creating-generators.md | 2 +- docs/generator.md | 22 +++++--- docs/prompts.md | 4 +- docs/testing-generators.md | 9 +-- example/index.js | 2 +- example/saofile.js | 2 +- lib/Generator.js | 18 ++++-- lib/runPrompts.js | 106 ++++++++++------------------------- package.json | 3 +- yarn.lock | 108 ++++++++++++++++++++---------------- 13 files changed, 131 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index b68b02b..fb60cd5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ const config = { prompts() { return [ { - type: 'text', + type: 'input', name: 'name', message: 'what is your name' } @@ -68,10 +68,8 @@ const kopy = require('kopy') test('it works', async () => { const generator = kopy(config) - const result = await generator.test({ - name: 'kevin' - }) - expect(result.fileList).toContain('index.js') + await generator.emulate() + expect(generator.answers).toEqual({ name: '' }) }) ``` diff --git a/__test__/index.test.js b/__test__/index.test.js index 7d467ca..2f3047a 100644 --- a/__test__/index.test.js +++ b/__test__/index.test.js @@ -5,13 +5,13 @@ test('simple', async () => { prompts: [ { name: 'name', - type: 'text', + type: 'input', message: 'what is your name', initial: 'kevin' } ] }) - await generator.test() + await generator.emulate() expect(generator.answers).toEqual({ name: 'kevin' }) diff --git a/docs/README.md b/docs/README.md index 6cc25bc..15d08ce 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,7 +18,7 @@ const config = { prompts() { return [ { - type: 'text', + type: 'input', name: 'name', message: 'what is your name' } @@ -62,10 +62,7 @@ const kopy = require('kopy') test('it works', async () => { const generator = kopy(config) - await generator.test({ - // Prompt answers - name: 'kevin' - }) - expect(generator.fileList).toContain('index.js') + await generator.emulate() + expect(generator.answers).toEqual({ name: '' }) }) ``` diff --git a/docs/creating-generators.md b/docs/creating-generators.md index 00fd4ec..71dc824 100644 --- a/docs/creating-generators.md +++ b/docs/creating-generators.md @@ -7,7 +7,7 @@ const config = { prompts() { return [ { - type: 'text', + type: 'input', name: 'name', message: 'what is your name' } diff --git a/docs/generator.md b/docs/generator.md index 7f5908e..c3558df 100644 --- a/docs/generator.md +++ b/docs/generator.md @@ -126,18 +126,22 @@ interface Opts { Check out [validateSchema.js](https://github.com/saojs/kopy/blob/master/lib/validateConfig.js) for the underlying schema we use to validate the config. -## generator.test +## generator.emulate -- Type: `(answers: Answers) => Promise` +- Type: `(emulator?: Emulator) => Promise` -Run the generator in test mode. +Emulate running the generator. -### answers +### emulator -- Type: `any[]` `{[name: string]: any}` `boolean` +- Type: `(prompt: enquirer.prompt) => void` -Set it to `true` to use inject initial value to prompts. +By default, running `generator.emulate()` will emulate using the initial values for prompts, the `emulator` it uses looks like: -Or an array with values to inject. - -Or an object whose entry is prompt name. +```js +const defaultEmulator = prompt => { + prompt.on('prompt', prompt => { + prompt.submit() + }) +} +``` diff --git a/docs/prompts.md b/docs/prompts.md index bf13ccf..ad91d36 100644 --- a/docs/prompts.md +++ b/docs/prompts.md @@ -1,6 +1,8 @@ # Prompts -Kopy prompts are a superset of [prompts](https://github.com/terkelg/prompts), we have following addtional properties. +Check out the documentation for [prompts](https://github.com/enquirer/enquirer#prompt-options) in Enquirer. + +We also have a few addtional prompt options listed below. ## cache diff --git a/docs/testing-generators.md b/docs/testing-generators.md index 1e298a9..f55ec8b 100644 --- a/docs/testing-generators.md +++ b/docs/testing-generators.md @@ -7,7 +7,7 @@ const config = { prompts: [ { name: 'name', - type: 'text', + type: 'input', message: 'what is your name' } ] @@ -15,11 +15,8 @@ const config = { test('it works', async () => { const generator = kopy(config) - const answers = { - name: 'kevin' - } - await generator.test(answers) - expect(generator.fileList).toContain('index.js') + await generator.emulate() + expect(generator.answers).toEqual({ name: '' }) }) ``` diff --git a/example/index.js b/example/index.js index 4b10f32..f9f15af 100644 --- a/example/index.js +++ b/example/index.js @@ -4,5 +4,5 @@ const kopy = require('../lib') const generator = kopy(require('./saofile')) generator - .run({ outDir: path.join(__dirname, 'dist'), injectAnswers: true }) + .run({ outDir: path.join(__dirname, 'dist') }) .catch(generator.handleError) diff --git a/example/saofile.js b/example/saofile.js index cfcce4e..632ccfd 100644 --- a/example/saofile.js +++ b/example/saofile.js @@ -4,7 +4,7 @@ module.exports = { prompts() { return [ { - type: 'text', + type: 'input', name: 'name', message: 'what is your name', cache: true diff --git a/lib/Generator.js b/lib/Generator.js index 6178196..0cf9319 100644 --- a/lib/Generator.js +++ b/lib/Generator.js @@ -177,13 +177,19 @@ module.exports = class Generator { } } - test(answers = true, opts) { + emulate( + emulator = prompt => prompt.on('prompt', prompt => prompt.submit()), + opts + ) { return this.run( - Object.assign({}, opts, { - injectAnswers: answers, - test: true, - logLevel: 1 - }) + Object.assign( + { + emulator, + test: true, + logLevel: 1 + }, + opts + ) ) } diff --git a/lib/runPrompts.js b/lib/runPrompts.js index 316e78f..7ea3b4b 100644 --- a/lib/runPrompts.js +++ b/lib/runPrompts.js @@ -1,45 +1,46 @@ -const prompts = require('prompts') +const { prompt } = require('enquirer') const { fs } = require('majo') -const logger = require('./logger') -const KopyError = require('./KopyError') module.exports = async (questions, generator) => { const cacheData = await readCacheFile(generator) const cacheAnswers = generator.cacheIdentifier && cacheData[generator.cacheIdentifier] - if (cacheAnswers) { - questions = questions.map(q => { + questions = questions.map(q => { + if (cacheAnswers) { const answer = cacheAnswers[q.name] if (q.cache && answer !== undefined) { q.initial = answer } - return q - }) - } + } + + if (generator.opts.test) { + q.show = false + } - const { injectAnswers } = generator.opts + // Compability with older version + if (q.type === 'text') { + q.type = 'input' + } + + return q + }) - if (injectAnswers === true) { - // Use initial values as answers - logger.warn( - "We're automatically answering default value to all questions, which may have security implications." - ) - prompts.inject(await getInitialValues(questions)) - } else if (Array.isArray(injectAnswers)) { - prompts.inject(await getInitialValues(questions, injectAnswers)) - } else if (typeof injectAnswers === 'object') { - prompts.inject( - await getInitialValues( - questions, - Object.keys(questions).map(q => { - return injectAnswers[q.name] - }) - ) - ) + if (typeof generator.opts.emulator === 'function') { + generator.opts.emulator(prompt) } - const answers = await prompts(questions) + const answers = await prompt(questions) + + // Restore cursor + // When using prompt.show enquirer will hide prompts + // But seems it doesn't restore cursor when finished + if (generator.opts.test) { + const stream = process.stdout + if (stream.isTTY) { + stream.write('\u001B[?25h') + } + } for (const q of questions) { // In case some questions are skipped @@ -69,54 +70,3 @@ async function setCacheAnswers(generator, cacheData, answers) { await fs.writeFile(generator.cacheFile, JSON.stringify(newData), 'utf8') } - -async function getInitialValues(questions, initialValues) { - const values = [].concat(initialValues || []) - for (const [i, q] of questions.entries()) { - let initial = values[i] - if (initial === undefined) { - if (typeof q.initial === 'function') { - initial = await q.initial(values[i - 1], values, q) - } else { - initial = q.initial - } - } - values[i] = inferInitialValue(q, initial) - } - return values -} - -function inferInitialValue(question, initial) { - switch (question.type) { - case 'text': - case 'password': - case 'invisible': - case 'autocomplete': { - return typeof initial === 'string' ? initial : '' - } - case 'list': { - initial = typeof initial === 'string' ? initial : '' - return initial.split(question.separator || ',').map(v => v.trim()) - } - case 'number': { - return typeof initial === 'number' ? initial : 0 - } - case 'confirm': - case 'toggle': { - return typeof initial === 'boolean' ? initial : true - } - case 'select': { - initial = typeof initial === 'number' ? initial : 0 - const choice = question.choices.find((_, i) => { - return i === initial - }) - return choice && choice.value - } - case 'multiselect': { - return question.choices.filter(c => c.selected).map(c => c.value) - } - default: { - throw new KopyError(`Unknown prompt type: ${question.type}`) - } - } -} diff --git a/package.json b/package.json index 652fab3..e69b794 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,12 @@ "devDependencies": { "@types/fs-extra": "^5.0.4", "@types/micromatch": "^3.1.0", - "@types/prompts": "^1.2.0", "builtin-modules": "^3.0.0", "colorette": "1.0.7", "commitizen": "^3.0.5", "cross-spawn": "6.0.5", "cz-conventional-changelog": "^2.1.0", + "enquirer": "^2.3.0", "env-paths": "2.0.0", "eslint-config-prettier": "^3.3.0", "eslint-config-rem": "^4.0.0", @@ -44,7 +44,6 @@ "micromatch": "3.1.10", "ora": "3.0.0", "prettier": "1.15.3", - "prompts": "2.0.1", "rollup": "^1.0.2", "rollup-plugin-alias": "^1.5.1", "rollup-plugin-commonjs": "^9.2.0", diff --git a/yarn.lock b/yarn.lock index 857c706..c7442b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,6 +280,11 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-colors@^3.2.1: + version "3.2.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + ansi-escapes@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" @@ -1206,7 +1211,7 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -colorette@^1.0.7: +colorette@1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/colorette/-/colorette-1.0.7.tgz#7adf43c445ee63a541b4a4aef7d13f03df1e0cc0" integrity sha512-KeK4klsvAgdODAjFPm6QLzvStizJqlxMBtVo4KQMCgk5tt/tf9rAzxmxLHNRynJg3tJjkKGKbHx3j4HLox27Lw== @@ -1437,16 +1442,7 @@ create-error-class@^3.0.0: 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.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== @@ -1457,6 +1453,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +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" + 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" @@ -1811,6 +1816,13 @@ enhance-visitors@^1.0.0: dependencies: lodash "^4.13.1" +enquirer@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.0.tgz#c362c9d84984ebe854def63caaf12983a16af552" + integrity sha512-RNGUbRVlfnjmpxV+Ed+7CGu0rg3MK7MmlW+DW0v7V2zdAUBC1s4BxCRiIAozbYB2UJ+q4D+8tW9UFb11kF72/g== + dependencies: + ansi-colors "^3.2.1" + env-ci@^3.0.0: version "3.1.3" resolved "https://registry.npmjs.org/env-ci/-/env-ci-3.1.3.tgz#17626015676d35bfb64d6f2945a178d559c0d23d" @@ -1824,7 +1836,7 @@ env-editor@^0.3.1: resolved "https://registry.npmjs.org/env-editor/-/env-editor-0.3.1.tgz#30d0540c2101414f258a94d4c0a524c06c13e3c6" integrity sha1-MNBUDCEBQU8lipTUwKUkwGwT48Y= -env-paths@^2.0.0: +env-paths@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.0.0.tgz#5a71723f3df7ca98113541f6fa972184f2c9611d" integrity sha512-13VpSqOO91W3MskXxWJ8x+Y33RKaPT53/HviPp8QcMmEbAJaPFEm8BmMpxCHroJ5rGADqr34Zl6zosBt3F+xAA== @@ -3153,7 +3165,7 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: +ini@1.3.5, ini@^1.3.4, ini@^1.3.5, 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== @@ -3287,7 +3299,7 @@ is-arrayish@^0.2.1: resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-binary-path@^2.0.0: +is-binary-path@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.0.0.tgz#0e61cea6974b24dda8bcc8366ce58a69265d1a36" integrity sha1-DmHOppdLJN2ovMg2bOWKaSZdGjY= @@ -4221,14 +4233,14 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jstransformer-ejs@^0.2.0: +jstransformer-ejs@0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/jstransformer-ejs/-/jstransformer-ejs-0.2.0.tgz#e45c9ff6b9c53dd20e646ce8a84456c76f5afa61" integrity sha1-5Fyf9rnFPdIOZGzoqERWx29a+mE= dependencies: ejs "^2.5.7" -jstransformer@^1.0.0: +jstransformer@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM= @@ -4647,7 +4659,7 @@ log-symbols@^2.0.0, log-symbols@^2.2.0: dependencies: chalk "^2.0.1" -log-update@^2.3.0: +log-update@2.3.0, log-update@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= @@ -4708,7 +4720,7 @@ magic-string@^0.25.1: dependencies: sourcemap-codec "^1.4.1" -majo@^0.6.3: +majo@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/majo/-/majo-0.6.3.tgz#ac8f35a64c644c87eaccddf940891f157a183846" integrity sha512-MFbnH7HSBstk/8Mic0M0cQ9cjpj+o+cZxyCKSHsqKd6OHB1DGDyIsV1UyVOXoyNQpsIYDjZOw9NQaoNdxSQprA== @@ -4887,6 +4899,25 @@ merge@^1.2.0: resolved "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== +micromatch@3.1.10, micromatch@^3.1.10, micromatch@^3.1.4, 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== + 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" + micromatch@^2.3.11, micromatch@^2.3.7: version "2.3.11" resolved "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -4906,25 +4937,6 @@ micromatch@^2.3.11, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.10, micromatch@^3.1.4, 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== - 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" - mime-db@~1.37.0: version "1.37.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" @@ -5659,7 +5671,7 @@ optionator@^0.8.1, optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -ora@^3.0.0: +ora@3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/ora/-/ora-3.0.0.tgz#8179e3525b9aafd99242d63cc206fd64732741d0" integrity sha512-LBS97LFe2RV6GJmXBi6OKcETKyklHNMV0xw7BtsVn2MlsgsydyZetSCbCANr+PFLmDyv4KV88nn0eCKza665Mg== @@ -6090,7 +6102,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^1.12.1, prettier@^1.15.3: +prettier@1.15.3, prettier@^1.12.1: version "1.15.3" resolved "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg== @@ -6138,6 +6150,14 @@ promise@^7.0.1: dependencies: asap "~2.0.3" +prompts@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.0.1.tgz#201b3718b4276fb407f037db48c0029d6465245c" + integrity sha512-8lnEOSIGQbgbnO47+13S+H204L8ISogGulyi0/NNEFAQ9D1VMNTrJ9SBX2Ra03V4iPn/zt36HQMndRYkaPoWiQ== + dependencies: + kleur "^3.0.0" + sisteransi "^1.0.0" + prompts@^0.1.9: version "0.1.14" resolved "https://registry.npmjs.org/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" @@ -6146,14 +6166,6 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prompts@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/prompts/-/prompts-2.0.1.tgz#201b3718b4276fb407f037db48c0029d6465245c" - integrity sha512-8lnEOSIGQbgbnO47+13S+H204L8ISogGulyi0/NNEFAQ9D1VMNTrJ9SBX2Ra03V4iPn/zt36HQMndRYkaPoWiQ== - dependencies: - kleur "^3.0.0" - sisteransi "^1.0.0" - promzard@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" @@ -7381,7 +7393,7 @@ strip-json-comments@2.0.1, strip-json-comments@^2.0.1, strip-json-comments@~2.0. resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -superstruct@^0.6.0: +superstruct@0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.6.0.tgz#20d2073526cf683a57f258695e009c4a19134ad0" integrity sha512-6Y+bh5oFXCMUmGGzcdwd8M2qXMWn9aH3Qu2wV8Cg/Lxu+3fTxJ0dTx54nKd/Sm3lSz3i901xVatzev7c/xN8Lg==