From f05da1acb0be5af50211ff4a0646fbbea0e3f199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Wenzel?= Date: Thu, 7 Feb 2019 03:14:27 +0100 Subject: [PATCH] feat(ui): add Enquirer as UI lib --- lib/commands/new/new-application.json | 2 +- lib/ui-enquirer.js | 61 ++++++++ lib/ui.js | 154 +++++-------------- lib/workflow/activities/input-multiselect.js | 15 +- lib/workflow/activities/input-select.js | 10 +- lib/workflow/activities/input-text.js | 9 +- lib/workflow/activities/project-create.js | 45 +++--- lib/workflow/activities/project-install.js | 56 +++++-- package-lock.json | 98 ++++++------ package.json | 1 + 10 files changed, 225 insertions(+), 226 deletions(-) create mode 100644 lib/ui-enquirer.js diff --git a/lib/commands/new/new-application.json b/lib/commands/new/new-application.json index 41b908806..340c54f3b 100644 --- a/lib/commands/new/new-application.json +++ b/lib/commands/new/new-application.json @@ -79,7 +79,7 @@ "type": "input-text", "id": 200, "nextActivity": 300, - "question": "Please enter a name for your new project below.", + "question": "Please enter a name for your new project:", "stateProperty": "name", "defaultValue": "aurelia-app" }, diff --git a/lib/ui-enquirer.js b/lib/ui-enquirer.js new file mode 100644 index 000000000..40af5ed17 --- /dev/null +++ b/lib/ui-enquirer.js @@ -0,0 +1,61 @@ +'use strict'; +const os = require('os'); +const { prompt } = require('enquirer'); +const Enquirer = require('enquirer'); +const colors = require("ansi-colors"); +const transform = require('./colors/transform'); +const createLines = require('./string').createLines; + +module.exports = class { + constructor(ui) { + this.ui = ui; + } + + async prompt(type, name, question, initial, options, autoSubmit) { + const choices = options && options[0].displayName ? this.convertOptions(options) : options; + const enquirer = new Enquirer(); + if (autoSubmit) { + enquirer.answers[name] = initial; + } + const answers = await enquirer.prompt({ + type: type, + name: name, + message: question, + initial: initial, + choices: choices, + styles: { + em: colors.cyan, + }, + separator: ' ' + (autoSubmit ? transform(` ${initial}`) : ''), + header: ' ', + footer: ' ', + choicesHeader: ' ', + onSubmit() { + if (type === 'multiselect' && this.selected.length === 0) { + this.enable(this.focused); + } + }, + autofill: autoSubmit ? 'show' : false, + }); + if (type === 'multiselect') { + return (options && options[0].displayName ? answers[name].map((option) => this.findValue(options, option)) : answers[name]) || []; + } + else { + return (options && options[0].displayName) || autoSubmit ? this.findValue(options, answers[name]) : answers[name]; + } + } + + convertOptions(options) { + return options.map((option, index, options) => { + return { + // name: option.value, + value: option.displayName, + message: `${index}. ${option.displayName}`, + hint: os.EOL + transform(`${createLines(option.description, ' ', this.ui.getWidth())}`), + } + }); + } + findValue(options, displayName) { + return options.find((option) => option.displayName === displayName).value; + } +}; diff --git a/lib/ui.js b/lib/ui.js index a18012492..e2f3fc288 100644 --- a/lib/ui.js +++ b/lib/ui.js @@ -5,12 +5,14 @@ const fs = require('./file-system'); const transform = require('./colors/transform'); const createLines = require('./string').createLines; const tty = require('tty'); +const UIEnquirer = require('./ui-enquirer'); -exports.UI = class {}; +exports.UI = class { }; exports.ConsoleUI = class { constructor(cliOptions) { this.cliOptions = cliOptions; + this.uiEnquirer = new UIEnquirer(this); } open() { @@ -46,62 +48,47 @@ exports.ConsoleUI = class { return this.question(question, suggestion); } - question(text, optionsOrSuggestion) { - return new Promise((resolve, reject) => { - if (!optionsOrSuggestion || typeof optionsOrSuggestion === 'string') { - this.open(); - - let fullText = os.EOL + text + os.EOL + os.EOL; - - if (optionsOrSuggestion) { - fullText += '[' + optionsOrSuggestion + ']'; - } - - this.rl.question(fullText + '> ', answer => { - this.close(); - - answer = answer || optionsOrSuggestion; - - if (answer) { - resolve(answer); - } else { - return this.question(text, optionsOrSuggestion).then(theAnswer => resolve(theAnswer)); - } - }); + async question(question, optionsOrSuggestion, defaultValue) { + if (!optionsOrSuggestion || typeof optionsOrSuggestion === 'string') { + const answer = await this.uiEnquirer.prompt( + 'input', + 'noNameNeeded', + question, + optionsOrSuggestion, + ); + if (answer && answer.length) { + return answer; } else { - optionsOrSuggestion = optionsOrSuggestion.filter(x => includeOption(this.cliOptions, x)); - - if (optionsOrSuggestion.length === 1) { - return resolve(optionsOrSuggestion[0]); - } - - let defaultOption = optionsOrSuggestion[0]; - let fullText = os.EOL + text + os.EOL - + createOptionsText(this, optionsOrSuggestion) + os.EOL + '[' + defaultOption.displayName + ']' + '> '; - - this.open(); - this.rl.question(fullText, answer => { - this.close(); - resolve(interpretAnswer(answer, optionsOrSuggestion)); - }); + return this.question(question, optionsOrSuggestion); } - }); + } else { + optionsOrSuggestion = optionsOrSuggestion.filter(x => includeOption(this.cliOptions, x)); + let autoSubmit = false; + if (optionsOrSuggestion.length === 1) { + defaultValue = optionsOrSuggestion[0].displayName; + optionsOrSuggestion[0].name = optionsOrSuggestion[0].value.id; + autoSubmit = true; + } + + return this.uiEnquirer.prompt( + 'select', + 'noNameNeeded', + question, + defaultValue, + optionsOrSuggestion, + autoSubmit, + ); + } } - multiselect(question, options) { - return new Promise(resolve => { - let info = 'Select one or more options separated by spaces'; - let fullText = os.EOL + question + os.EOL - + createOptionsText(this, options, true) + os.EOL + info + os.EOL + '> '; - - this.open(); - this.rl.question(fullText, answer => { - this.close(); - let answers = answer.split(' '); - answers = answers.filter(x => x.length > 0); - resolve(interpretAnswers(answers, options)); - }); - }); + multiselect(question, options, defaultValue) { + return this.uiEnquirer.prompt( + 'multiselect', + 'noNameNeeded', + question, + defaultValue, + options + ); } getWidth() { @@ -137,65 +124,6 @@ function includeOption(cliOptions, option) { return true; } -function createOptionsText(ui, options, multi) { - let text = os.EOL; - - for (let i = 0; i < options.length; ++i) { - text += `${i + 1}. ${options[i].displayName}`; - - if (!multi && i === 0) { - text += ' (Default)'; - } - - text += os.EOL; - - if (options[i].description) { - text += createLines(`${options[i].description}`, ' ', ui.getWidth()); - text += os.EOL; - } - } - - return transform(text); -} - -function interpretAnswer(answer, options) { - if (!answer) { - return options[0]; - } - - let lowerCasedAnswer = answer.toLowerCase(); - let found = options.find(x => x.displayName.toLowerCase().startsWith(lowerCasedAnswer)); - - if (found) { - return found; - } - - let num = parseInt(answer, 10); - return options[num - 1] || options[0]; -} - -function interpretAnswers(answers, options) { - let foundAnswers = []; - - for (let i = 0; i < answers.length; i++) { - let lowerCasedAnswer = answers[i].toLowerCase(); - let found = options.find(x => x.displayName.toLowerCase().startsWith(lowerCasedAnswer)); - - if (found) { - foundAnswers.push(found); - continue; - } - - let num = parseInt(answers[i], 10); - - if (options[num - 1]) { - foundAnswers.push(options[num - 1]); - } - } - - return foundAnswers; -} - function getWindowSize() { let width; let height; @@ -216,5 +144,5 @@ function getWindowSize() { height = 100; } - return {height: height, width: width}; + return { height: height, width: width }; } diff --git a/lib/workflow/activities/input-multiselect.js b/lib/workflow/activities/input-multiselect.js index c85f96b02..8abba0b29 100644 --- a/lib/workflow/activities/input-multiselect.js +++ b/lib/workflow/activities/input-multiselect.js @@ -8,16 +8,9 @@ module.exports = class { this.ui = ui; } - execute(context) { - return this.ui.multiselect(this.question, this.options).then(answers => { - context.state[this.stateProperty] = []; - - for (let i = 0; i < answers.length; i++) { - let answer = answers[i]; - - context.state[this.stateProperty].push(answer.value); - } - context.next(this.nextActivity); - }); + async execute(context) { + const answers = await this.ui.multiselect(this.question, this.options); + context.state[this.stateProperty] = answers.slice(); + context.next(this.nextActivity); } }; diff --git a/lib/workflow/activities/input-select.js b/lib/workflow/activities/input-select.js index 0097b19b6..68eeb9324 100644 --- a/lib/workflow/activities/input-select.js +++ b/lib/workflow/activities/input-select.js @@ -8,17 +8,15 @@ module.exports = class { this.ui = ui; } - execute(context) { + async execute(context) { let overrideProperty = this.stateProperty + 'Override'; if (overrideProperty in context.state) { context.state[this.stateProperty] = context.state[overrideProperty]; - context.next(this.nextActivity); } else { - return this.ui.question(this.question, this.options).then(answer => { - context.state[this.stateProperty] = answer.value; - context.next(this.nextActivity); - }); + const answer = await this.ui.question(this.question, this.options, this.defaultValue); + context.state[this.stateProperty] = answer; } + context.next(this.nextActivity); } }; diff --git a/lib/workflow/activities/input-text.js b/lib/workflow/activities/input-text.js index 9e9ac5195..d7969b2b4 100644 --- a/lib/workflow/activities/input-text.js +++ b/lib/workflow/activities/input-text.js @@ -8,10 +8,9 @@ module.exports = class { this.ui = ui; } - execute(context) { - return this.ui.ensureAnswer(context.state[this.stateProperty], this.question, this.defaultValue).then(answer => { - context.state[this.stateProperty] = answer; - context.next(this.nextActivity); - }); + async execute(context) { + const answer = await this.ui.ensureAnswer(context.state[this.stateProperty], this.question, this.defaultValue); + context.state[this.stateProperty] = answer; + context.next(this.nextActivity); } }; diff --git a/lib/workflow/activities/project-create.js b/lib/workflow/activities/project-create.js index 50bb0324a..8b9ec5312 100644 --- a/lib/workflow/activities/project-create.js +++ b/lib/workflow/activities/project-create.js @@ -15,7 +15,7 @@ module.exports = class { this.options = options; } - execute(context) { + async execute(context) { let model = { name: context.state.name, type: context.state.type, @@ -59,28 +59,27 @@ module.exports = class { this.ui.log(JSON.stringify(model, null, 2)); } - return this.ui.log(this.createProjectDescription(model)) - .then(() => this.projectConfirmation(project)) - .then(answer => { - if (answer.value === 'yes') { - let configurator = require(`../../commands/new/buildsystems/${model.bundler.id}`); - configurator(project, this.options); - - return project.create(this.ui, this.options.hasFlag('here') ? undefined : process.cwd()) - .then(() => this.ui.log('Project structure created and configured.' + os.EOL)) - .then(() => project.renderManualInstructions()) - .then(() => context.next(this.nextActivity)); - } else if (answer.value === 'restart') { - return context.next(this.restartActivity); - } - - return this.ui.log(os.EOL + 'Project creation aborted.') - .then(() => context.next()); - }) - .catch(e => { - logger.error(`Failed to create the project due to an error: ${e.message}`); - logger.info(e.stack); - }); + if (context.state.defaultOrCustom !== 'custom') { + await this.ui.log(this.createProjectDescription(model)); + } + const answer = await this.projectConfirmation(project); + if (answer === 'yes') { + const configurator = require(`../../commands/new/buildsystems/${model.bundler.id}`); + configurator(project, this.options); + + return project.create(this.ui, this.options.hasFlag('here') ? undefined : process.cwd()) + .then(() => this.ui.log('Project structure created and configured.' + os.EOL)) + .then(() => project.renderManualInstructions()) + .then(() => context.next(this.nextActivity)).catch(e => { + logger.error(`Failed to create the project due to an error: ${e.message}`); + logger.info(e.stack); + }); + } else if (answer === 'restart') { + return context.next(this.restartActivity); + } + + return this.ui.log(os.EOL + 'Project creation aborted.') + .then(() => context.next()); } createProjectDescription(model) { diff --git a/lib/workflow/activities/project-install.js b/lib/workflow/activities/project-install.js index d04a74bc7..8a7027d97 100644 --- a/lib/workflow/activities/project-install.js +++ b/lib/workflow/activities/project-install.js @@ -5,6 +5,7 @@ const transform = require('../../colors/transform'); const createLines = require('../../string').createLines; const Yarn = require('../../package-managers/yarn').Yarn; const CLIOptions = require('../../cli-options').CLIOptions; +const fs = require('../../file-system'); module.exports = class { static inject() { return [UI, CLIOptions]; } @@ -14,14 +15,33 @@ module.exports = class { this.options = options; } - execute(context) { + async execute(context) { let project = context.state.project; let options = []; + const workingDirectory = project.getWorkingDirectory(); + const npmLockExists = fs.existsSync(fs.join(workingDirectory, 'package-lock.json')); + const yarnLockExists = fs.existsSync(fs.join(workingDirectory, 'yarn.lock')); + + if (npmLockExists && yarnLockExists) { + this.ui.log(transform("WARNING: Found lock files for both npm and yarn! Lock files are not cross compatible between package managers. It's recommended to remove either package-lock.json (NPM) or yarn.lock (Yarn) from the project directory before installing new packages.\n")); + } + else if (npmLockExists) { + this.ui.log(transform('Note: Found NPM lock file. Recommend continued use of npm as package manager.\n')); + } + else if (yarnLockExists) { + this.ui.log(transform('Note: Found Yarn lock file. Recommend continued use of yarn as package manager.\n')); + } + let defaultIndex = 0; let yarn = new Yarn(); - if (yarn.isAvailable(project.getWorkingDirectory())) { - this.ui.log('Note: lock files are not cross compatible between package managers. Choose Yarn here only if you intend to use Yarn for future package installs. Alternatively, remove either yarn.lock or package-lock.json from the project directory before installing new packages.'); - options = [ + if (yarn.isAvailable(workingDirectory)) { + if (!yarnLockExists) { + this.ui.log('Note: Lock files are not cross compatible between package managers. Choose Yarn here only if you intend to use Yarn for future package installs. Alternatively, remove either yarn.lock or package-lock.json from the project directory before installing new packages.'); + } + if (npmLockExists && !yarnLockExists) { + defaultIndex = 1; + } + options = [ { displayName: 'Yes, use Yarn', description: 'Installs all server, client and tooling dependencies needed to build the project using Yarn.', @@ -53,20 +73,24 @@ module.exports = class { ]; } - return this.ui.question('Would you like to install the project dependencies?', options).then(answer => { - if (answer.value === 'yes' || answer.value === 'npm' || answer.value === 'yarn') { - const packageManager = answer.value === 'yes' ? 'npm' : answer.value; + const name = 'install-dependencies'; + const answer = await this.ui.question( + 'Would you like to install the project dependencies?', + options, + defaultIndex, + ); + if (answer === 'yes' || answer === 'npm' || answer === 'yarn') { + const packageManager = answer === 'yes' ? 'npm' : answer; - return project.savePackageManager(packageManager) - .then(() => this.ui.log(os.EOL + 'Installing project dependencies.')) - .then(() => project.install(this.ui, packageManager)) - .then(() => this.displayCompletionMessage(project)) - .then(() => context.next(this.nextActivity)); - } + return project.savePackageManager(packageManager) + .then(() => this.ui.log(os.EOL + 'Installing project dependencies.')) + .then(() => project.install(this.ui, packageManager)) + .then(() => this.displayCompletionMessage(project)) + .then(() => context.next(this.nextActivity)); + } - return this.ui.log(os.EOL + 'Dependencies not installed.') - .then(() => context.next()); - }); + return this.ui.log(os.EOL + 'Dependencies not installed.') + .then(() => context.next()); } displayCompletionMessage(project) { diff --git a/package-lock.json b/package-lock.json index 263cc17d2..595671fc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "aurelia-cli", - "version": "1.0.0-beta.12", + "version": "1.0.0-beta.13", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -294,7 +294,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", "dev": true }, "acorn": { @@ -374,7 +374,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -687,7 +687,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", "dev": true }, "async-settle": { @@ -1177,7 +1177,7 @@ "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "integrity": "sha1-VcbDmouljZxhrSLNh3Uy3rZlogs=", "dev": true, "requires": { "ansi-align": "^2.0.0", @@ -1210,7 +1210,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -1566,7 +1566,7 @@ "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", "dev": true }, "class-utils": { @@ -1794,7 +1794,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -2643,7 +2643,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", "dev": true, "requires": { "esutils": "^2.0.2" @@ -2758,6 +2758,21 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.0.tgz", + "integrity": "sha512-RNGUbRVlfnjmpxV+Ed+7CGu0rg3MK7MmlW+DW0v7V2zdAUBC1s4BxCRiIAozbYB2UJ+q4D+8tW9UFb11kF72/g==", + "requires": { + "ansi-colors": "^3.2.1" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + } + } + }, "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", @@ -3481,8 +3496,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "optional": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { "version": "1.2.0", @@ -3503,14 +3517,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "optional": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3525,20 +3537,17 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "optional": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "optional": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", @@ -3655,8 +3664,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "optional": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -3668,7 +3676,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3683,7 +3690,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3691,14 +3697,12 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "optional": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3717,7 +3721,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3798,8 +3801,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "optional": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { "version": "4.1.1", @@ -3811,7 +3813,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "optional": true, "requires": { "wrappy": "1" } @@ -3897,8 +3898,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safer-buffer": { "version": "2.1.2", @@ -3934,7 +3934,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3954,7 +3953,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3998,14 +3996,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "optional": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "optional": true + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" } } }, @@ -4949,7 +4945,7 @@ "https-proxy-agent": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -5465,7 +5461,7 @@ "jasmine-spec-reporter": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", - "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", + "integrity": "sha1-HWMq7ANBZwrTJPkrqEtLMrNeniI=", "dev": true, "requires": { "colors": "1.1.2" @@ -6573,7 +6569,7 @@ }, "p-cancelable": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "resolved": "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", "dev": true }, @@ -6591,7 +6587,7 @@ }, "p-is-promise": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", "dev": true }, @@ -6860,7 +6856,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -7030,7 +7026,7 @@ }, "query-string": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", "dev": true, "requires": { @@ -7777,7 +7773,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", "dev": true, "requires": { "through": "2" @@ -7794,7 +7790,7 @@ "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", "dev": true, "requires": { "through2": "^2.0.2" @@ -8036,7 +8032,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -8217,7 +8213,7 @@ "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "integrity": "sha1-/jZfX3XsntTlaCXgu3bSSrdK+Ds=", "dev": true, "requires": { "nopt": "~1.0.10" @@ -8543,7 +8539,7 @@ "dependencies": { "got": { "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { @@ -8798,7 +8794,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", diff --git a/package.json b/package.json index d9ed5d804..5f76ae8cf 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "concat-with-sourcemaps": "^1.1.0", "convert-source-map": "^1.6.0", "del": "^3.0.0", + "enquirer": "^2.3.0", "esprima": "^4.0.1", "glob": "^7.1.3", "gulp": "^4.0.0",