UNPKG

snyk

Version:

snyk library and cli utility

2,189 lines (1,725 loc) • 769 kB
exports.id = 139; exports.ids = [139]; exports.modules = { /***/ 32139: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * Inquirer.js * A collection of common interactive command line user interfaces. */ var inquirer = module.exports; /** * Client interfaces */ inquirer.prompts = {}; inquirer.Separator = __webpack_require__(61622); inquirer.ui = { BottomBar: __webpack_require__(9785), Prompt: __webpack_require__(3313), }; /** * Create a new self-contained prompt module. */ inquirer.createPromptModule = function (opt) { var promptModule = function (questions, answers) { var ui; try { ui = new inquirer.ui.Prompt(promptModule.prompts, opt); } catch (error) { return Promise.reject(error); } var promise = ui.run(questions, answers); // Monkey patch the UI on the promise object so // that it remains publicly accessible. promise.ui = ui; return promise; }; promptModule.prompts = {}; /** * Register a prompt type * @param {String} name Prompt type name * @param {Function} prompt Prompt constructor * @return {inquirer} */ promptModule.registerPrompt = function (name, prompt) { promptModule.prompts[name] = prompt; return this; }; /** * Register the defaults provider prompts */ promptModule.restoreDefaultPrompts = function () { this.registerPrompt('list', __webpack_require__(94258)); this.registerPrompt('input', __webpack_require__(92802)); this.registerPrompt('number', __webpack_require__(2303)); this.registerPrompt('confirm', __webpack_require__(54533)); this.registerPrompt('rawlist', __webpack_require__(30230)); this.registerPrompt('expand', __webpack_require__(58788)); this.registerPrompt('checkbox', __webpack_require__(75355)); this.registerPrompt('password', __webpack_require__(18405)); this.registerPrompt('editor', __webpack_require__(13998)); }; promptModule.restoreDefaultPrompts(); return promptModule; }; /** * Public CLI helper interface * @param {Array|Object|Rx.Observable} questions - Questions settings array * @param {Function} cb - Callback being passed the user answers * @return {inquirer.ui.Prompt} */ inquirer.prompt = inquirer.createPromptModule(); // Expose helper functions on the top level for easiest usage by common users inquirer.registerPrompt = function (name, prompt) { inquirer.prompt.registerPrompt(name, prompt); }; inquirer.restoreDefaultPrompts = function () { inquirer.prompt.restoreDefaultPrompts(); }; /***/ }), /***/ 9068: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; var _ = { isString: __webpack_require__(25751), isNumber: __webpack_require__(23126), extend: __webpack_require__(5089), isFunction: __webpack_require__(98423), }; /** * Choice object * Normalize input as choice object * @constructor * @param {Number|String|Object} val Choice value. If an object is passed, it should contains * at least one of `value` or `name` property */ module.exports = class Choice { constructor(val, answers) { // Don't process Choice and Separator object if (val instanceof Choice || val.type === 'separator') { // eslint-disable-next-line no-constructor-return return val; } if (_.isString(val) || _.isNumber(val)) { this.name = String(val); this.value = val; this.short = String(val); } else { _.extend(this, val, { name: val.name || val.value, value: 'value' in val ? val.value : val.name, short: val.short || val.name || val.value, }); } if (_.isFunction(val.disabled)) { this.disabled = val.disabled(answers); } else { this.disabled = val.disabled; } } }; /***/ }), /***/ 32898: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; var assert = __webpack_require__(42357); var _ = { isNumber: __webpack_require__(23126), filter: __webpack_require__(4474), map: __webpack_require__(80820), find: __webpack_require__(84872), }; var Separator = __webpack_require__(61622); var Choice = __webpack_require__(9068); /** * Choices collection * Collection of multiple `choice` object * @constructor * @param {Array} choices All `choice` to keep in the collection */ module.exports = class Choices { constructor(choices, answers) { this.choices = choices.map((val) => { if (val.type === 'separator') { if (!(val instanceof Separator)) { val = new Separator(val.line); } return val; } return new Choice(val, answers); }); this.realChoices = this.choices .filter(Separator.exclude) .filter((item) => !item.disabled); Object.defineProperty(this, 'length', { get() { return this.choices.length; }, set(val) { this.choices.length = val; }, }); Object.defineProperty(this, 'realLength', { get() { return this.realChoices.length; }, set() { throw new Error('Cannot set `realLength` of a Choices collection'); }, }); } /** * Get a valid choice from the collection * @param {Number} selector The selected choice index * @return {Choice|Undefined} Return the matched choice or undefined */ getChoice(selector) { assert(_.isNumber(selector)); return this.realChoices[selector]; } /** * Get a raw element from the collection * @param {Number} selector The selected index value * @return {Choice|Undefined} Return the matched choice or undefined */ get(selector) { assert(_.isNumber(selector)); return this.choices[selector]; } /** * Match the valid choices against a where clause * @param {Object} whereClause Lodash `where` clause * @return {Array} Matching choices or empty array */ where(whereClause) { return _.filter(this.realChoices, whereClause); } /** * Pluck a particular key from the choices * @param {String} propertyName Property name to select * @return {Array} Selected properties */ pluck(propertyName) { return _.map(this.realChoices, propertyName); } // Expose usual Array methods indexOf() { return this.choices.indexOf.apply(this.choices, arguments); } forEach() { return this.choices.forEach.apply(this.choices, arguments); } filter() { return this.choices.filter.apply(this.choices, arguments); } reduce() { return this.choices.reduce.apply(this.choices, arguments); } find(func) { return _.find(this.choices, func); } push() { var objs = _.map(arguments, (val) => new Choice(val)); this.choices.push.apply(this.choices, objs); this.realChoices = this.choices .filter(Separator.exclude) .filter((item) => !item.disabled); return this.choices; } }; /***/ }), /***/ 61622: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; var chalk = __webpack_require__(58270); var figures = __webpack_require__(91254); /** * Separator object * Used to space/separate choices group * @constructor * @param {String} line Separation line content (facultative) */ class Separator { constructor(line) { this.type = 'separator'; this.line = chalk.dim(line || new Array(15).join(figures.line)); } /** * Stringify separator * @return {String} the separator display string */ toString() { return this.line; } } /** * Helper function returning false if object is a separator * @param {Object} obj object to test against * @return {Boolean} `false` if object is a separator */ Separator.exclude = function (obj) { return obj.type !== 'separator'; }; module.exports = Separator; /***/ }), /***/ 19280: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * Base prompt implementation * Should be extended by prompt types. */ var _ = { assign: __webpack_require__(31730), defaults: __webpack_require__(55402), clone: __webpack_require__(33543), }; var chalk = __webpack_require__(58270); var runAsync = __webpack_require__(14709); var { filter, flatMap, share, take, takeUntil } = __webpack_require__(11717); var Choices = __webpack_require__(32898); var ScreenManager = __webpack_require__(1627); class Prompt { constructor(question, rl, answers) { // Setup instance defaults property _.assign(this, { answers: answers, status: 'pending', }); // Set defaults prompt options this.opt = _.defaults(_.clone(question), { validate: () => true, filter: (val) => val, when: () => true, suffix: '', prefix: chalk.green('?'), }); // Make sure name is present if (!this.opt.name) { this.throwParamError('name'); } // Set default message if no message defined if (!this.opt.message) { this.opt.message = this.opt.name + ':'; } // Normalize choices if (Array.isArray(this.opt.choices)) { this.opt.choices = new Choices(this.opt.choices, answers); } this.rl = rl; this.screen = new ScreenManager(this.rl); } /** * Start the Inquiry session and manage output value filtering * @return {Promise} */ run() { return new Promise((resolve, reject) => { this._run( (value) => resolve(value), (error) => reject(error) ); }); } // Default noop (this one should be overwritten in prompts) _run(cb) { cb(); } /** * Throw an error telling a required parameter is missing * @param {String} name Name of the missing param * @return {Throw Error} */ throwParamError(name) { throw new Error('You must provide a `' + name + '` parameter'); } /** * Called when the UI closes. Override to do any specific cleanup necessary */ close() { this.screen.releaseCursor(); } /** * Run the provided validation method each time a submit event occur. * @param {Rx.Observable} submit - submit event flow * @return {Object} Object containing two observables: `success` and `error` */ handleSubmitEvents(submit) { var self = this; var validate = runAsync(this.opt.validate); var asyncFilter = runAsync(this.opt.filter); var validation = submit.pipe( flatMap((value) => asyncFilter(value, self.answers).then( (filteredValue) => validate(filteredValue, self.answers).then( (isValid) => ({ isValid: isValid, value: filteredValue }), (err) => ({ isValid: err, value: filteredValue }) ), (err) => ({ isValid: err }) ) ), share() ); var success = validation.pipe( filter((state) => state.isValid === true), take(1) ); var error = validation.pipe( filter((state) => state.isValid !== true), takeUntil(success) ); return { success: success, error: error, }; } /** * Generate the prompt question string * @return {String} prompt question string */ getQuestion() { var message = this.opt.prefix + ' ' + chalk.bold(this.opt.message) + this.opt.suffix + chalk.reset(' '); // Append the default if available, and if question isn't answered if (this.opt.default != null && this.status !== 'answered') { // If default password is supplied, hide it if (this.opt.type === 'password') { message += chalk.italic.dim('[hidden] '); } else { message += chalk.dim('(' + this.opt.default + ') '); } } return message; } } module.exports = Prompt; /***/ }), /***/ 75355: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `list` type prompt */ var _ = { isArray: Array.isArray, map: __webpack_require__(80820), isString: __webpack_require__(25751), }; var chalk = __webpack_require__(58270); var cliCursor = __webpack_require__(23909); var figures = __webpack_require__(91254); var { map, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var observe = __webpack_require__(27382); var Paginator = __webpack_require__(59028); var incrementListIndex = __webpack_require__(81464); class CheckboxPrompt extends Base { constructor(questions, rl, answers) { super(questions, rl, answers); if (!this.opt.choices) { this.throwParamError('choices'); } if (_.isArray(this.opt.default)) { this.opt.choices.forEach(function (choice) { if (this.opt.default.indexOf(choice.value) >= 0) { choice.checked = true; } }, this); } this.pointer = 0; // Make sure no default is set (so it won't be printed) this.opt.default = null; const shouldLoop = this.opt.loop === undefined ? true : this.opt.loop; this.paginator = new Paginator(this.screen, { isInfinite: shouldLoop }); } /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; var events = observe(this.rl); var validation = this.handleSubmitEvents( events.line.pipe(map(this.getCurrentValue.bind(this))) ); validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); events.normalizedUpKey .pipe(takeUntil(validation.success)) .forEach(this.onUpKey.bind(this)); events.normalizedDownKey .pipe(takeUntil(validation.success)) .forEach(this.onDownKey.bind(this)); events.numberKey .pipe(takeUntil(validation.success)) .forEach(this.onNumberKey.bind(this)); events.spaceKey .pipe(takeUntil(validation.success)) .forEach(this.onSpaceKey.bind(this)); events.aKey.pipe(takeUntil(validation.success)).forEach(this.onAllKey.bind(this)); events.iKey.pipe(takeUntil(validation.success)).forEach(this.onInverseKey.bind(this)); // Init the prompt cliCursor.hide(); this.render(); this.firstRender = false; return this; } /** * Render the prompt to screen * @return {CheckboxPrompt} self */ render(error) { // Render question var message = this.getQuestion(); var bottomContent = ''; if (!this.spaceKeyPressed) { message += '(Press ' + chalk.cyan.bold('<space>') + ' to select, ' + chalk.cyan.bold('<a>') + ' to toggle all, ' + chalk.cyan.bold('<i>') + ' to invert selection)'; } // Render choices or answer depending on the state if (this.status === 'answered') { message += chalk.cyan(this.selection.join(', ')); } else { var choicesStr = renderChoices(this.opt.choices, this.pointer); var indexPosition = this.opt.choices.indexOf( this.opt.choices.getChoice(this.pointer) ); var realIndexPosition = this.opt.choices.reduce(function (acc, value, i) { // Dont count lines past the choice we are looking at if (i > indexPosition) { return acc; } // Add line if it's a separator if (value.type === 'separator') { return acc + 1; } var l = value.name; // Non-strings take up one line if (typeof l !== 'string') { return acc + 1; } // Calculate lines taken up by string l = l.split('\n'); return acc + l.length; }, 0) - 1; message += '\n' + this.paginator.paginate(choicesStr, realIndexPosition, this.opt.pageSize); } if (error) { bottomContent = chalk.red('>> ') + error; } this.screen.render(message, bottomContent); } /** * When user press `enter` key */ onEnd(state) { this.status = 'answered'; this.spaceKeyPressed = true; // Rerender prompt (and clean subline error) this.render(); this.screen.done(); cliCursor.show(); this.done(state.value); } onError(state) { this.render(state.isValid); } getCurrentValue() { var choices = this.opt.choices.filter(function (choice) { return Boolean(choice.checked) && !choice.disabled; }); this.selection = _.map(choices, 'short'); return _.map(choices, 'value'); } onUpKey() { this.pointer = incrementListIndex(this.pointer, 'up', this.opt); this.render(); } onDownKey() { this.pointer = incrementListIndex(this.pointer, 'down', this.opt); this.render(); } onNumberKey(input) { if (input <= this.opt.choices.realLength) { this.pointer = input - 1; this.toggleChoice(this.pointer); } this.render(); } onSpaceKey() { this.spaceKeyPressed = true; this.toggleChoice(this.pointer); this.render(); } onAllKey() { var shouldBeChecked = Boolean( this.opt.choices.find(function (choice) { return choice.type !== 'separator' && !choice.checked; }) ); this.opt.choices.forEach(function (choice) { if (choice.type !== 'separator') { choice.checked = shouldBeChecked; } }); this.render(); } onInverseKey() { this.opt.choices.forEach(function (choice) { if (choice.type !== 'separator') { choice.checked = !choice.checked; } }); this.render(); } toggleChoice(index) { var item = this.opt.choices.getChoice(index); if (item !== undefined) { this.opt.choices.getChoice(index).checked = !item.checked; } } } /** * Function for rendering checkbox choices * @param {Number} pointer Position of the pointer * @return {String} Rendered content */ function renderChoices(choices, pointer) { var output = ''; var separatorOffset = 0; choices.forEach(function (choice, i) { if (choice.type === 'separator') { separatorOffset++; output += ' ' + choice + '\n'; return; } if (choice.disabled) { separatorOffset++; output += ' - ' + choice.name; output += ' (' + (_.isString(choice.disabled) ? choice.disabled : 'Disabled') + ')'; } else { var line = getCheckbox(choice.checked) + ' ' + choice.name; if (i - separatorOffset === pointer) { output += chalk.cyan(figures.pointer + line); } else { output += ' ' + line; } } output += '\n'; }); return output.replace(/\n$/, ''); } /** * Get the checkbox * @param {Boolean} checked - add a X or not to the checkbox * @return {String} Composited checkbox string */ function getCheckbox(checked) { return checked ? chalk.green(figures.radioOn) : figures.radioOff; } module.exports = CheckboxPrompt; /***/ }), /***/ 54533: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `confirm` type prompt */ var _ = { extend: __webpack_require__(5089), isBoolean: __webpack_require__(48094), }; var chalk = __webpack_require__(58270); var { take, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var observe = __webpack_require__(27382); class ConfirmPrompt extends Base { constructor(questions, rl, answers) { super(questions, rl, answers); var rawDefault = true; _.extend(this.opt, { filter: function (input) { var value = rawDefault; if (input != null && input !== '') { value = /^y(es)?/i.test(input); } return value; }, }); if (_.isBoolean(this.opt.default)) { rawDefault = this.opt.default; } this.opt.default = rawDefault ? 'Y/n' : 'y/N'; } /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; // Once user confirm (enter key) var events = observe(this.rl); events.keypress.pipe(takeUntil(events.line)).forEach(this.onKeypress.bind(this)); events.line.pipe(take(1)).forEach(this.onEnd.bind(this)); // Init this.render(); return this; } /** * Render the prompt to screen * @return {ConfirmPrompt} self */ render(answer) { var message = this.getQuestion(); if (typeof answer === 'boolean') { message += chalk.cyan(answer ? 'Yes' : 'No'); } else { message += this.rl.line; } this.screen.render(message); return this; } /** * When user press `enter` key */ onEnd(input) { this.status = 'answered'; var output = this.opt.filter(input); this.render(output); this.screen.done(); this.done(output); } /** * When user press a key */ onKeypress() { this.render(); } } module.exports = ConfirmPrompt; /***/ }), /***/ 13998: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `editor` type prompt */ var chalk = __webpack_require__(58270); var editAsync = __webpack_require__(72134)/* .editAsync */ .Wl; var Base = __webpack_require__(19280); var observe = __webpack_require__(27382); var { Subject } = __webpack_require__(34143); class EditorPrompt extends Base { /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; this.editorResult = new Subject(); // Open Editor on "line" (Enter Key) var events = observe(this.rl); this.lineSubscription = events.line.subscribe(this.startExternalEditor.bind(this)); // Trigger Validation when editor closes var validation = this.handleSubmitEvents(this.editorResult); validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); // Prevents default from being printed on screen (can look weird with multiple lines) this.currentText = this.opt.default; this.opt.default = null; // Init this.render(); return this; } /** * Render the prompt to screen * @return {EditorPrompt} self */ render(error) { var bottomContent = ''; var message = this.getQuestion(); if (this.status === 'answered') { message += chalk.dim('Received'); } else { message += chalk.dim('Press <enter> to launch your preferred editor.'); } if (error) { bottomContent = chalk.red('>> ') + error; } this.screen.render(message, bottomContent); } /** * Launch $EDITOR on user press enter */ startExternalEditor() { // Pause Readline to prevent stdin and stdout from being modified while the editor is showing this.rl.pause(); editAsync(this.currentText, this.endExternalEditor.bind(this)); } endExternalEditor(error, result) { this.rl.resume(); if (error) { this.editorResult.error(error); } else { this.editorResult.next(result); } } onEnd(state) { this.editorResult.unsubscribe(); this.lineSubscription.unsubscribe(); this.answer = state.value; this.status = 'answered'; // Re-render prompt this.render(); this.screen.done(); this.done(this.answer); } onError(state) { this.render(state.isValid); } } module.exports = EditorPrompt; /***/ }), /***/ 58788: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `rawlist` type prompt */ var _ = { uniq: __webpack_require__(97644), isString: __webpack_require__(25751), isNumber: __webpack_require__(23126), findIndex: __webpack_require__(66945), }; var chalk = __webpack_require__(58270); var { map, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var Separator = __webpack_require__(61622); var observe = __webpack_require__(27382); var Paginator = __webpack_require__(59028); class ExpandPrompt extends Base { constructor(questions, rl, answers) { super(questions, rl, answers); if (!this.opt.choices) { this.throwParamError('choices'); } this.validateChoices(this.opt.choices); // Add the default `help` (/expand) option this.opt.choices.push({ key: 'h', name: 'Help, list all options', value: 'help', }); this.opt.validate = (choice) => { if (choice == null) { return 'Please enter a valid command'; } return choice !== 'help'; }; // Setup the default string (capitalize the default key) this.opt.default = this.generateChoicesString(this.opt.choices, this.opt.default); this.paginator = new Paginator(this.screen); } /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; // Save user answer and update prompt to show selected option. var events = observe(this.rl); var validation = this.handleSubmitEvents( events.line.pipe(map(this.getCurrentValue.bind(this))) ); validation.success.forEach(this.onSubmit.bind(this)); validation.error.forEach(this.onError.bind(this)); this.keypressObs = events.keypress .pipe(takeUntil(validation.success)) .forEach(this.onKeypress.bind(this)); // Init the prompt this.render(); return this; } /** * Render the prompt to screen * @return {ExpandPrompt} self */ render(error, hint) { var message = this.getQuestion(); var bottomContent = ''; if (this.status === 'answered') { message += chalk.cyan(this.answer); } else if (this.status === 'expanded') { var choicesStr = renderChoices(this.opt.choices, this.selectedKey); message += this.paginator.paginate(choicesStr, this.selectedKey, this.opt.pageSize); message += '\n Answer: '; } message += this.rl.line; if (error) { bottomContent = chalk.red('>> ') + error; } if (hint) { bottomContent = chalk.cyan('>> ') + hint; } this.screen.render(message, bottomContent); } getCurrentValue(input) { if (!input) { input = this.rawDefault; } var selected = this.opt.choices.where({ key: input.toLowerCase().trim() })[0]; if (!selected) { return null; } return selected.value; } /** * Generate the prompt choices string * @return {String} Choices string */ getChoices() { var output = ''; this.opt.choices.forEach((choice) => { output += '\n '; if (choice.type === 'separator') { output += ' ' + choice; return; } var choiceStr = choice.key + ') ' + choice.name; if (this.selectedKey === choice.key) { choiceStr = chalk.cyan(choiceStr); } output += choiceStr; }); return output; } onError(state) { if (state.value === 'help') { this.selectedKey = ''; this.status = 'expanded'; this.render(); return; } this.render(state.isValid); } /** * When user press `enter` key */ onSubmit(state) { this.status = 'answered'; var choice = this.opt.choices.where({ value: state.value })[0]; this.answer = choice.short || choice.name; // Re-render prompt this.render(); this.screen.done(); this.done(state.value); } /** * When user press a key */ onKeypress() { this.selectedKey = this.rl.line.toLowerCase(); var selected = this.opt.choices.where({ key: this.selectedKey })[0]; if (this.status === 'expanded') { this.render(); } else { this.render(null, selected ? selected.name : null); } } /** * Validate the choices * @param {Array} choices */ validateChoices(choices) { var formatError; var errors = []; var keymap = {}; choices.filter(Separator.exclude).forEach((choice) => { if (!choice.key || choice.key.length !== 1) { formatError = true; } if (keymap[choice.key]) { errors.push(choice.key); } keymap[choice.key] = true; choice.key = String(choice.key).toLowerCase(); }); if (formatError) { throw new Error( 'Format error: `key` param must be a single letter and is required.' ); } if (keymap.h) { throw new Error( 'Reserved key error: `key` param cannot be `h` - this value is reserved.' ); } if (errors.length) { throw new Error( 'Duplicate key error: `key` param must be unique. Duplicates: ' + _.uniq(errors).join(', ') ); } } /** * Generate a string out of the choices keys * @param {Array} choices * @param {Number|String} default - the choice index or name to capitalize * @return {String} The rendered choices key string */ generateChoicesString(choices, defaultChoice) { var defIndex = choices.realLength - 1; if (_.isNumber(defaultChoice) && this.opt.choices.getChoice(defaultChoice)) { defIndex = defaultChoice; } else if (_.isString(defaultChoice)) { let index = _.findIndex( choices.realChoices, ({ value }) => value === defaultChoice ); defIndex = index === -1 ? defIndex : index; } var defStr = this.opt.choices.pluck('key'); this.rawDefault = defStr[defIndex]; defStr[defIndex] = String(defStr[defIndex]).toUpperCase(); return defStr.join(''); } } /** * Function for rendering checkbox choices * @param {String} pointer Selected key * @return {String} Rendered content */ function renderChoices(choices, pointer) { var output = ''; choices.forEach((choice) => { output += '\n '; if (choice.type === 'separator') { output += ' ' + choice; return; } var choiceStr = choice.key + ') ' + choice.name; if (pointer === choice.key) { choiceStr = chalk.cyan(choiceStr); } output += choiceStr; }); return output; } module.exports = ExpandPrompt; /***/ }), /***/ 92802: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `input` type prompt */ var chalk = __webpack_require__(58270); var { map, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var observe = __webpack_require__(27382); class InputPrompt extends Base { /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; // Once user confirm (enter key) var events = observe(this.rl); var submit = events.line.pipe(map(this.filterInput.bind(this))); var validation = this.handleSubmitEvents(submit); validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); events.keypress .pipe(takeUntil(validation.success)) .forEach(this.onKeypress.bind(this)); // Init this.render(); return this; } /** * Render the prompt to screen * @return {InputPrompt} self */ render(error) { var bottomContent = ''; var appendContent = ''; var message = this.getQuestion(); var transformer = this.opt.transformer; var isFinal = this.status === 'answered'; if (isFinal) { appendContent = this.answer; } else { appendContent = this.rl.line; } if (transformer) { message += transformer(appendContent, this.answers, { isFinal }); } else { message += isFinal ? chalk.cyan(appendContent) : appendContent; } if (error) { bottomContent = chalk.red('>> ') + error; } this.screen.render(message, bottomContent); } /** * When user press `enter` key */ filterInput(input) { if (!input) { return this.opt.default == null ? '' : this.opt.default; } return input; } onEnd(state) { this.answer = state.value; this.status = 'answered'; // Re-render prompt this.render(); this.screen.done(); this.done(state.value); } onError({ value = '', isValid }) { this.rl.line += value; this.rl.cursor += value.length; this.render(isValid); } /** * When user press a key */ onKeypress() { // If user press a key, just clear the default value if (this.opt.default) { this.opt.default = undefined; } this.render(); } } module.exports = InputPrompt; /***/ }), /***/ 94258: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `list` type prompt */ var _ = { isNumber: __webpack_require__(23126), findIndex: __webpack_require__(66945), isString: __webpack_require__(25751), }; var chalk = __webpack_require__(58270); var figures = __webpack_require__(91254); var cliCursor = __webpack_require__(23909); var runAsync = __webpack_require__(14709); var { flatMap, map, take, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var observe = __webpack_require__(27382); var Paginator = __webpack_require__(59028); var incrementListIndex = __webpack_require__(81464); class ListPrompt extends Base { constructor(questions, rl, answers) { super(questions, rl, answers); if (!this.opt.choices) { this.throwParamError('choices'); } this.firstRender = true; this.selected = 0; var def = this.opt.default; // If def is a Number, then use as index. Otherwise, check for value. if (_.isNumber(def) && def >= 0 && def < this.opt.choices.realLength) { this.selected = def; } else if (!_.isNumber(def) && def != null) { let index = _.findIndex(this.opt.choices.realChoices, ({ value }) => value === def); this.selected = Math.max(index, 0); } // Make sure no default is set (so it won't be printed) this.opt.default = null; const shouldLoop = this.opt.loop === undefined ? true : this.opt.loop; this.paginator = new Paginator(this.screen, { isInfinite: shouldLoop }); } /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; var self = this; var events = observe(this.rl); events.normalizedUpKey.pipe(takeUntil(events.line)).forEach(this.onUpKey.bind(this)); events.normalizedDownKey .pipe(takeUntil(events.line)) .forEach(this.onDownKey.bind(this)); events.numberKey.pipe(takeUntil(events.line)).forEach(this.onNumberKey.bind(this)); events.line .pipe( take(1), map(this.getCurrentValue.bind(this)), flatMap((value) => runAsync(self.opt.filter)(value).catch((err) => err)) ) .forEach(this.onSubmit.bind(this)); // Init the prompt cliCursor.hide(); this.render(); return this; } /** * Render the prompt to screen * @return {ListPrompt} self */ render() { // Render question var message = this.getQuestion(); if (this.firstRender) { message += chalk.dim('(Use arrow keys)'); } // Render choices or answer depending on the state if (this.status === 'answered') { message += chalk.cyan(this.opt.choices.getChoice(this.selected).short); } else { var choicesStr = listRender(this.opt.choices, this.selected); var indexPosition = this.opt.choices.indexOf( this.opt.choices.getChoice(this.selected) ); var realIndexPosition = this.opt.choices.reduce(function (acc, value, i) { // Dont count lines past the choice we are looking at if (i > indexPosition) { return acc; } // Add line if it's a separator if (value.type === 'separator') { return acc + 1; } var l = value.name; // Non-strings take up one line if (typeof l !== 'string') { return acc + 1; } // Calculate lines taken up by string l = l.split('\n'); return acc + l.length; }, 0) - 1; message += '\n' + this.paginator.paginate(choicesStr, realIndexPosition, this.opt.pageSize); } this.firstRender = false; this.screen.render(message); } /** * When user press `enter` key */ onSubmit(value) { this.status = 'answered'; // Rerender prompt this.render(); this.screen.done(); cliCursor.show(); this.done(value); } getCurrentValue() { return this.opt.choices.getChoice(this.selected).value; } /** * When user press a key */ onUpKey() { this.selected = incrementListIndex(this.selected, 'up', this.opt); this.render(); } onDownKey() { this.selected = incrementListIndex(this.selected, 'down', this.opt); this.render(); } onNumberKey(input) { if (input <= this.opt.choices.realLength) { this.selected = input - 1; } this.render(); } } /** * Function for rendering list choices * @param {Number} pointer Position of the pointer * @return {String} Rendered content */ function listRender(choices, pointer) { var output = ''; var separatorOffset = 0; choices.forEach((choice, i) => { if (choice.type === 'separator') { separatorOffset++; output += ' ' + choice + '\n'; return; } if (choice.disabled) { separatorOffset++; output += ' - ' + choice.name; output += ' (' + (_.isString(choice.disabled) ? choice.disabled : 'Disabled') + ')'; output += '\n'; return; } var isSelected = i - separatorOffset === pointer; var line = (isSelected ? figures.pointer + ' ' : ' ') + choice.name; if (isSelected) { line = chalk.cyan(line); } output += line + ' \n'; }); return output.replace(/\n$/, ''); } module.exports = ListPrompt; /***/ }), /***/ 2303: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `input` type prompt */ var Input = __webpack_require__(92802); /** * Extention of the Input prompt specifically for use with number inputs. */ class NumberPrompt extends Input { filterInput(input) { if (input && typeof input === 'string') { input = input.trim(); // Match a number in the input let numberMatch = input.match(/(^-?\d+|^\d+\.\d*|^\d*\.\d+)(e\d+)?$/); // If a number is found, return that input. if (numberMatch) { return Number(numberMatch[0]); } } // If the input was invalid return the default value. return this.opt.default == null ? NaN : this.opt.default; } } module.exports = NumberPrompt; /***/ }), /***/ 18405: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `password` type prompt */ var chalk = __webpack_require__(58270); var { map, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var observe = __webpack_require__(27382); function mask(input, maskChar) { input = String(input); maskChar = typeof maskChar === 'string' ? maskChar : '*'; if (input.length === 0) { return ''; } return new Array(input.length + 1).join(maskChar); } class PasswordPrompt extends Base { /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; var events = observe(this.rl); // Once user confirm (enter key) var submit = events.line.pipe(map(this.filterInput.bind(this))); var validation = this.handleSubmitEvents(submit); validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); events.keypress .pipe(takeUntil(validation.success)) .forEach(this.onKeypress.bind(this)); // Init this.render(); return this; } /** * Render the prompt to screen * @return {PasswordPrompt} self */ render(error) { var message = this.getQuestion(); var bottomContent = ''; if (this.status === 'answered') { message += this.opt.mask ? chalk.cyan(mask(this.answer, this.opt.mask)) : chalk.italic.dim('[hidden]'); } else if (this.opt.mask) { message += mask(this.rl.line || '', this.opt.mask); } else { message += chalk.italic.dim('[input is hidden] '); } if (error) { bottomContent = '\n' + chalk.red('>> ') + error; } this.screen.render(message, bottomContent); } /** * When user press `enter` key */ filterInput(input) { if (!input) { return this.opt.default == null ? '' : this.opt.default; } return input; } onEnd(state) { this.status = 'answered'; this.answer = state.value; // Re-render prompt this.render(); this.screen.done(); this.done(state.value); } onError(state) { this.render(state.isValid); } onKeypress() { // If user press a key, just clear the default value if (this.opt.default) { this.opt.default = undefined; } this.render(); } } module.exports = PasswordPrompt; /***/ }), /***/ 30230: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * `rawlist` type prompt */ var _ = { extend: __webpack_require__(5089), isNumber: __webpack_require__(23126), findIndex: __webpack_require__(66945), }; var chalk = __webpack_require__(58270); var { map, takeUntil } = __webpack_require__(11717); var Base = __webpack_require__(19280); var Separator = __webpack_require__(61622); var observe = __webpack_require__(27382); var Paginator = __webpack_require__(59028); var incrementListIndex = __webpack_require__(81464); class RawListPrompt extends Base { constructor(questions, rl, answers) { super(questions, rl, answers); if (!this.opt.choices) { this.throwParamError('choices'); } this.opt.validChoices = this.opt.choices.filter(Separator.exclude); this.selected = 0; this.rawDefault = 0; _.extend(this.opt, { validate: function (val) { return val != null; }, }); var def = this.opt.default; if (_.isNumber(def) && def >= 0 && def < this.opt.choices.realLength) { this.selected = def; this.rawDefault = def; } else if (!_.isNumber(def) && def != null) { let index = _.findIndex(this.opt.choices.realChoices, ({ value }) => value === def); let safeIndex = Math.max(index, 0); this.selected = safeIndex; this.rawDefault = safeIndex; } // Make sure no default is set (so it won't be printed) this.opt.default = null; const shouldLoop = this.opt.loop === undefined ? true : this.opt.loop; this.paginator = new Paginator(undefined, { isInfinite: shouldLoop }); } /** * Start the Inquiry session * @param {Function} cb Callback when prompt is done * @return {this} */ _run(cb) { this.done = cb; // Once user confirm (enter key) var events = observe(this.rl); var submit = events.line.pipe(map(this.getCurrentValue.bind(this))); var validation = this.handleSubmitEvents(submit); validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); events.normalizedUpKey.pipe(takeUntil(events.line)).forEach(this.onUpKey.bind(this)); events.normalizedDownKey .pipe(takeUntil(events.line)) .forEach(this.onDownKey.bind(this)); events.keypress .pipe(takeUntil(validation.success)) .forEach(this.onKeypress.bind(this)); // Init the prompt this.render(); return this; } /** * Render the prompt to screen * @return {RawListPrompt} self */ render(error) { // Render question var message = this.getQuestion(); var bottomContent = ''; if (this.status === 'answered') { message += chalk.cyan(this.answer); } else { var choicesStr = renderChoices(this.opt.choices, this.selected); message += '\n' + this.paginator.paginate(choicesStr, this.selected, this.opt.pageSize); message += '\n Answer: '; } message += this.rl.line; if (error) { bottomContent = '\n' + chalk.red('>> ') + error; } this.screen.render(message, bottomContent); } /** * When user press `enter` key */ getCurrentValue(index) { if (index == null) { index = this.rawDefault; } else if (index === '') { index = this.selected; } else { index -= 1; } var choice = this.opt.choices.getChoice(index); return choice ? choice.value : null; } onEnd(state) { this.status = 'answered'; this.answer = state.value; // Re-render prompt this.render(); this.screen.done(); this.done(state.value); } onError() { this.render('Please enter a valid index'); } /** * When user press a key */ onKeypress() { var index = this.rl.line.length ? Number(this.rl.line) - 1 : 0; if (this.opt.choices.getChoice(index)) { this.selected = index; } else { this.selected = undefined; } this.render(); } /** * When user press up key */ onUpKey() { this.onArrowKey('up'); } /** * When user press down key */ onDownKey() { this.onArrowKey('down'); } /** * When user press up or down key * @param {String} type Arrow type: up or down */ onArrowKey(type) { this.selected = incrementListIndex(this.selected, type, this.opt); this.rl.line = String(this.selected + 1); } } /** * Function for rendering list choices * @param {Number} pointer Position of the pointer * @return {String} Rendered content */ function renderChoices(choices, pointer) { var output = ''; var separatorOffset = 0; choices.forEach(function (choice, i) { output += '\n '; if (choice.type === 'separator') { separatorOffset++; output += ' ' + choice; return; } var index = i - separatorOffset; var display = index + 1 + ') ' + choice.name; if (index === pointer) { display = chalk.cyan(display); } output += display; }); return output; } module.exports = RawListPrompt; /***/ }), /***/ 96781: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; var _ = { extend: __webpack_require__(5089), omit: __webpack_require__(76427), }; var MuteStream = __webpack_require__(42954); var readline = __webpack_require__(51058); /** * Base interface class other can inherits from */ class UI { constructor(opt) { // Instantiate the Readline interface // @Note: Don't reassign if already present (allow test to override the Stream) if (!this.rl) { this.rl = readline.createInterface(setupReadlineOptions(opt)); } this.rl.resume(); this.onForceClose = this.onForceClose.bind(this); // Make sure new prompt start on a newline when closing process.on('exit', this.onForceClose); // Terminate process on SIGINT (which will call process.on('exit') in return) this.rl.on('SIGINT', this.onForceClose); } /** * Handle the ^C exit * @return {null} */ onForceClose() { this.close(); process.kill(process.pid, 'SIGINT'); console.log(''); } /** * Close the interface and cleanup listeners */ close() { // Remove events listeners this.rl.removeListener('SIGINT', this.onForceClose); process.removeListener('exit', this.onForceClose); this.rl.output.unmute(); if (this.activePrompt && typeof this.activePrompt.close === 'function') { this.activePrompt.close(); } // Close the readline this.rl.output.end(); this.rl.pause(); this.rl.close(); } } function setupReadlineOptions(opt) { opt = opt || {}; // Inquirer 8.x: // opt.skipTTYChecks = opt.skipTTYChecks === undefined ? opt.input !== undefined : opt.skipTTYChecks; opt.skipTTYChecks = opt.skipTTYChecks === undefined ? true : opt.skipTTYChecks; // Default `input` to stdin var input = opt.input || process.stdin; // Check if prompt is being called in TTY environment // If it isn't return a failed promise if (!opt.skipTTYChecks && !input.isTTY) { const nonTtyError = new Error( 'Prompts can not be meaningfully rendered in non-TTY environments' ); nonTtyError.isTtyError = true; throw nonTtyError; } // Add mute capabilities to the output var ms = new MuteStream(); ms.pipe(opt.output || process.stdout); var output = ms; return _.extend( { terminal: true, input: input, output: output, }, _.omit(opt, ['input', 'output']) ); } module.exports = UI; /***/ }), /***/ 9785: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; /** * Sticky bottom bar user interface */ var through = __webpack_require__(26547); var Base = __webpack_require__(96781); var rlUtils = __webpack_require__(59152); var _ = { last: __webpack_require__(17833), }; class BottomBar extends Base { constructor(opt) { opt = opt || {}; super(opt); this.log = through(this.writeLog.bind(this)); this.bottomBar = opt.bottomBar || ''; this.render(); } /** * Render the prompt to screen * @return {BottomBar} self */ render() { this.write(this.bottomBar); return this; } clean() { rlUtils.clearLine(this.rl, this.bottomBar.split('\n').length); return this; } /** * Update the bottom bar content and rerender * @param {String} bottomBar Bottom bar content * @return {BottomBar} self */ updateBottomBar(bottomBar) { rlUtils.clearLine(this.rl, 1); this.rl.output.unmute(); this.clean(); this.bottomBar = bottomBar; this.render(); this.rl.output.mute(); return this; } /** * Write out log data * @param {String} data - The log data to be output * @return {BottomBar} self */ writeLog(data) { this.rl.output.unmute(); this.clean(); this.rl.output.write(this.enforceL