diff --git a/lib/elements/autocompleteMultiselect.js b/lib/elements/autocompleteMultiselect.js new file mode 100644 index 00000000..2f053ac5 --- /dev/null +++ b/lib/elements/autocompleteMultiselect.js @@ -0,0 +1,189 @@ +'use strict'; + +const color = require('kleur'); +const { cursor } = require('sisteransi'); +const MultiselectPrompt = require('./multiselect'); +const { clear, style, figures } = require('../util'); +/** + * MultiselectPrompt Base Element + * @param {Object} opts Options + * @param {String} opts.message Message + * @param {Array} opts.choices Array of choice objects + * @param {String} [opts.hint] Hint to display + * @param {String} [opts.warn] Hint shown for disabled choices + * @param {Number} [opts.max] Max choices + * @param {Number} [opts.cursor=0] Cursor start position + * @param {Stream} [opts.stdin] The Readable stream to listen to + * @param {Stream} [opts.stdout] The Writable stream to write readline data to + */ +class AutocompleteMultiselectPrompt extends MultiselectPrompt { + constructor(opts={}) { + opts.overrideRender = true; + super(opts); + this.inputValue = ''; + this.clear = clear(''); + this.filteredOptions = this.value; + this.render(); + } + + last() { + this.cursor = this.filteredOptions.length - 1; + this.render(); + } + next() { + this.cursor = (this.cursor + 1) % this.filteredOptions.length; + this.render(); + } + + up() { + if (this.cursor === 0) { + this.cursor = this.filteredOptions.length - 1; + } else { + this.cursor--; + } + this.render(); + } + + down() { + if (this.cursor === this.filteredOptions.length - 1) { + this.cursor = 0; + } else { + this.cursor++; + } + this.render(); + } + + left() { + this.filteredOptions[this.cursor].selected = false; + this.render(); + } + + right() { + if (this.value.filter(e => e.selected).length >= this.maxChoices) return this.bell(); + this.filteredOptions[this.cursor].selected = true; + this.render(); + } + + delete() { + if (this.inputValue.length) { + this.inputValue = this.inputValue.substr(0, this.inputValue.length - 1); + this.updateFilteredOptions(); + } + } + + updateFilteredOptions() { + const currentHighlight = this.filteredOptions[this.cursor]; + this.filteredOptions = this.value + .filter(v => { + if (this.inputValue) { + if (typeof v.title === 'string') { + if (v.title.toLowerCase().includes(this.inputValue.toLowerCase())) { + return true; + } + } + if (typeof v.value === 'string') { + if (v.value.toLowerCase().includes(this.inputValue.toLowerCase())) { + return true; + } + } + return false; + } + return true; + }); + const newHighlightIndex = this.filteredOptions.findIndex(v => v === currentHighlight) + this.cursor = newHighlightIndex < 0 ? 0 : newHighlightIndex; + this.render(); + } + + handleSpaceToggle() { + const v = this.filteredOptions[this.cursor]; + + if (v.selected) { + v.selected = false; + this.render(); + } else if (v.disabled || this.value.filter(e => e.selected).length >= this.maxChoices) { + return this.bell(); + } else { + v.selected = true; + this.render(); + } + } + + handleInputChange(c) { + this.inputValue = this.inputValue + c; + this.updateFilteredOptions(); + } + + _(c, key) { + if (c === ' ') { + this.handleSpaceToggle(); + } else { + this.handleInputChange(c); + } + } + + renderInstructions() { + return ` +Instructions: + ${figures.arrowUp}/${figures.arrowDown}: Highlight option + ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection + [a,b,c]/delete: Filter choices + enter/return: Complete answer + ` + } + + renderCurrentInput() { + return ` +Filtered results for: ${this.inputValue ? this.inputValue : color.gray('Enter something to filter')}\n`; + } + + renderOption(cursor, v, i) { + let title; + if (v.disabled) title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + else title = cursor === i ? color.cyan().underline(v.title) : v.title; + return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + title + } + + renderDoneOrInstructions() { + if (this.done) { + const selected = this.value + .filter(e => e.selected) + .map(v => v.title) + .join(', '); + return selected; + } + + const output = [color.gray(this.hint), this.renderInstructions(), this.renderCurrentInput()]; + + if (this.filteredOptions.length && this.filteredOptions[this.cursor].disabled) { + output.push(color.yellow(this.warn)); + } + return output.join(' '); + } + + render() { + if (this.closed) return; + if (this.firstRender) this.out.write(cursor.hide); + super.render(); + + // print prompt + + let prompt = [ + style.symbol(this.done, this.aborted), + color.bold(this.msg), + style.delimiter(false), + this.renderDoneOrInstructions() + ].join(' '); + + if (this.showMinError) { + prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`); + this.showMinError = false; + } + prompt += this.renderOptions(this.filteredOptions); + + this.out.write(this.clear + prompt); + this.clear = clear(prompt); + } +} + +module.exports = AutocompleteMultiselectPrompt; diff --git a/lib/elements/index.js b/lib/elements/index.js index 68d8fc65..2556dd05 100644 --- a/lib/elements/index.js +++ b/lib/elements/index.js @@ -8,5 +8,6 @@ module.exports = { NumberPrompt: require('./number'), MultiselectPrompt: require('./multiselect'), AutocompletePrompt: require('./autocomplete'), + AutocompleteMultiselectPrompt: require('./autocompleteMultiselect'), ConfirmPrompt: require('./confirm') }; diff --git a/lib/elements/multiselect.js b/lib/elements/multiselect.js index 93ad71fd..cd3da11f 100644 --- a/lib/elements/multiselect.js +++ b/lib/elements/multiselect.js @@ -1,8 +1,8 @@ 'use strict'; const color = require('kleur'); -const Prompt = require('./prompt'); const { cursor } = require('sisteransi'); +const Prompt = require('./prompt'); const { clear, figures, style } = require('../util'); /** @@ -22,8 +22,11 @@ class MultiselectPrompt extends Prompt { super(opts); this.msg = opts.message; this.cursor = opts.cursor || 0; - this.hint = opts.hint || '- Space to select. Return to submit'; - this.warn = opts.warn || '- This option is disabled'; + this.scrollIndex = opts.cursor || 0; + this.hint = opts.hint || ''; + this.warn = opts.warn || '- This option is disabled -'; + this.minSelected = opts.min; + this.showMinError = false; this.maxChoices = opts.max; this.value = opts.choices.map((ch, idx) => { if (typeof ch === 'string') @@ -36,7 +39,9 @@ class MultiselectPrompt extends Prompt { }; }); this.clear = clear(''); - this.render(); + if (!opts.overrideRender) { + this.render(); + } } reset() { @@ -59,8 +64,11 @@ class MultiselectPrompt extends Prompt { } submit() { - if(this.value[this.cursor].disabled) { - this.bell(); + const selected = this.value + .filter(e => e.selected); + if (this.minSelected && selected.length < this.minSelected) { + this.showMinError = true; + this.render(); } else { this.done = true; this.aborted = false; @@ -86,14 +94,20 @@ class MultiselectPrompt extends Prompt { } up() { - if (this.cursor === 0) return this.bell(); - this.cursor--; + if (this.cursor === 0) { + this.cursor = this.value.length - 1; + } else { + this.cursor--; + } this.render(); } down() { - if (this.cursor === this.value.length - 1) return this.bell(); - this.cursor++; + if (this.cursor === this.value.length - 1) { + this.cursor = 0; + } else { + this.cursor++; + } this.render(); } @@ -108,8 +122,7 @@ class MultiselectPrompt extends Prompt { this.render(); } - _(c, key) { - if (c !== ' ') return this.bell(); + handleSpaceToggle() { const v = this.value[this.cursor]; if (v.selected) { @@ -123,38 +136,99 @@ class MultiselectPrompt extends Prompt { } } + _(c, key) { + if (c === ' ') { + this.handleSpaceToggle(); + } else { + return this.bell(); + } + } + + renderInstructions() { + return ` +Instructions: + ${figures.arrowUp}/${figures.arrowDown}: Highlight option + ${figures.arrowLeft}/${figures.arrowRight}/[space]: Toggle selection + enter/return: Complete answer + ` + } + + renderOption(cursor, v, i) { + let title; + if (v.disabled) title = cursor === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); + else title = cursor === i ? color.cyan().underline(v.title) : v.title; + return (v.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + title + } + + // shared with autocompleteMultiselect + paginateOptions(options) { + const c = this.cursor; + let styledOptions = options.map((v, i) => this.renderOption(c, v, i)); + const numOfOptionsToRender = 10; // if needed, can add an option to change this. + + let scopedOptions = styledOptions; + let hint = ''; + if (styledOptions.length === 0) { + return color.red('No matches for this query.'); + } else if (styledOptions.length > numOfOptionsToRender) { + let startIndex = c - (numOfOptionsToRender / 2); + let endIndex = c + (numOfOptionsToRender / 2); + if (startIndex < 0) { + startIndex = 0; + endIndex = numOfOptionsToRender; + } else if (endIndex > options.length) { + endIndex = options.length; + startIndex = endIndex - numOfOptionsToRender; + } + scopedOptions = styledOptions.slice(startIndex, endIndex); + hint = color.dim('(Move up and down to reveal more choices)'); + } + return '\n' + scopedOptions.join('\n') + '\n' + hint; + } + + // shared with autocomleteMultiselect + renderOptions(options) { + if (!this.done) { + return this.paginateOptions(options); + } + return ''; + } + + renderDoneOrInstructions() { + if (this.done) { + const selected = this.value + .filter(e => e.selected) + .map(v => v.title) + .join(', '); + return selected; + } + + const output = [color.gray(this.hint), this.renderInstructions()]; + + if (this.value[this.cursor].disabled) { + output.push(color.yellow(this.warn)); + } + return output.join(' '); + } + render() { if (this.closed) return; if (this.firstRender) this.out.write(cursor.hide); super.render(); // print prompt - const selected = this.value - .filter(e => e.selected) - .map(v => v.title) - .join(', '); + let prompt = [ style.symbol(this.done, this.aborted), color.bold(this.msg), style.delimiter(false), - this.done ? selected : this.value[this.cursor].disabled - ? color.yellow(this.warn) : color.gray(this.hint) + this.renderDoneOrInstructions() ].join(' '); - - // print choices - if (!this.done) { - const c = this.cursor; - prompt += - '\n' + - this.value - .map((v, i) => { - let title; - if (v.disabled) title = c === i ? color.gray().underline(v.title) : color.strikethrough().gray(v.title); - else title = c === i ? color.cyan().underline(v.title) : v.title; - return (v.selected ? color.green(figures.tick) : ' ') + ' ' + title - }) - .join('\n'); + if (this.showMinError) { + prompt += color.red(`You must select a minimum of ${this.minSelected} choices.`); + this.showMinError = false; } + prompt += this.renderOptions(this.value); this.out.write(this.clear + prompt); this.clear = clear(prompt); diff --git a/lib/prompts.js b/lib/prompts.js index 35b33cee..df5d66bc 100644 --- a/lib/prompts.js +++ b/lib/prompts.js @@ -149,7 +149,7 @@ $.toggle = args => toPrompt('TogglePrompt', args); $.select = args => toPrompt('SelectPrompt', args); /** - * Interactive multi-select prompt + * Interactive multi-select / autocompleteMultiselect prompt * @param {string} args.message Prompt message to display * @param {Array} args.choices Array of choices objects `[{ title, value, [selected] }, ...]` * @param {number} [args.max] Max select @@ -169,6 +169,15 @@ $.multiselect = args => { }); }; +$.autocompleteMultiselect = args => { + args.choices = [].concat(args.choices || []); + const toSelected = items => items.filter(item => item.selected).map(item => item.value); + return toPrompt('AutocompleteMultiselectPrompt', args, { + onAbort: toSelected, + onSubmit: toSelected + }); +}; + const byTitle = (input, choices) => Promise.resolve( choices.filter(item => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase()) ); diff --git a/lib/util/figures.js b/lib/util/figures.js index 7950db7a..cd31b885 100644 --- a/lib/util/figures.js +++ b/lib/util/figures.js @@ -1,21 +1,33 @@ -'use strict'; +'use strict'; -const main = { - tick: '✔', - cross: '✖', - ellipsis: '…', - pointerSmall: '›', - line: '─', - pointer: '❯' -}; + const main = { + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + radioOn: '◉', + radioOff: '◯', + tick: '✔', + cross: '✖', + ellipsis: '…', + pointerSmall: '›', + line: '─', + pointer: '❯' +}; const win = { - tick: '√', - cross: '×', - ellipsis: '...', - pointerSmall: '»', - line: '─', - pointer: '>' -}; -const figures = process.platform === 'win32' ? win : main; + arrowUp: main.arrowUp, + arrowDown: main.arrowDown, + arrowLeft: main.arrowLeft, + arrowRight: main.arrowRight, + radioOn: '(*)', + radioOff: '( )', + tick: '√', + cross: '×', + ellipsis: '...', + pointerSmall: '»', + line: '─', + pointer: '>' +}; +const figures = process.platform === 'win32' ? win : main; -module.exports = figures; + module.exports = figures; diff --git a/package-lock.json b/package-lock.json index 366db461..7de5957c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -940,36 +940,31 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true + "dev": true }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "optional": true + "dev": true }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "optional": true + "dev": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "optional": true + "dev": true }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "optional": true + "dev": true }, "async-each": { "version": "1.0.1", @@ -982,8 +977,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "optional": true + "dev": true }, "balanced-match": { "version": "1.0.0", @@ -996,7 +990,6 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, - "optional": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -1012,7 +1005,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -1022,7 +1014,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1032,7 +1023,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1042,7 +1032,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1073,7 +1062,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -1092,7 +1080,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -1121,7 +1108,6 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, - "optional": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -1179,7 +1165,6 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, - "optional": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -1192,7 +1177,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -1204,7 +1188,6 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, - "optional": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -1235,8 +1218,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", @@ -1257,8 +1239,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1271,7 +1252,6 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "optional": true, "requires": { "ms": "2.0.0" } @@ -1280,8 +1260,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "optional": true + "dev": true }, "deep-equal": { "version": "1.0.1", @@ -1303,7 +1282,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, - "optional": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -1314,7 +1292,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1324,7 +1301,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1334,7 +1310,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1403,7 +1378,6 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, - "optional": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -1419,7 +1393,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -1429,7 +1402,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -1441,7 +1413,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, - "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -1452,7 +1423,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, - "optional": true, "requires": { "is-plain-object": "^2.0.4" } @@ -1464,7 +1434,6 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, - "optional": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -1481,7 +1450,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -1491,7 +1459,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -1501,7 +1468,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1511,7 +1477,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1521,7 +1486,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1530,22 +1494,11 @@ } } }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, - "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -1558,7 +1511,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -1578,15 +1530,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true + "dev": true }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, - "optional": true, "requires": { "map-cache": "^0.2.2" } @@ -1623,8 +1573,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -1645,14 +1594,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1667,20 +1614,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1797,8 +1741,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1810,7 +1753,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1825,7 +1767,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1833,14 +1774,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1859,7 +1798,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -1940,8 +1878,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -1953,7 +1890,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -2039,8 +1975,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -2076,7 +2011,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2096,7 +2030,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2140,14 +2073,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -2161,8 +2092,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "optional": true + "dev": true }, "glob": { "version": "7.1.3", @@ -2248,7 +2178,6 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, - "optional": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -2260,7 +2189,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, - "optional": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -2271,7 +2199,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -2308,7 +2235,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -2318,7 +2244,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -2339,8 +2264,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "optional": true + "dev": true }, "is-callable": { "version": "1.1.4", @@ -2353,7 +2277,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -2363,7 +2286,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -2381,7 +2303,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, - "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -2392,8 +2313,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true + "dev": true } } }, @@ -2401,15 +2321,13 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true + "dev": true }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "optional": true + "dev": true }, "is-finite": { "version": "1.0.2", @@ -2435,7 +2353,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -2445,7 +2362,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -2463,7 +2379,6 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, - "optional": true, "requires": { "isobject": "^3.0.1" } @@ -2490,8 +2405,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "optional": true + "dev": true }, "isarray": { "version": "1.0.0", @@ -2503,8 +2417,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true + "dev": true }, "js-levenshtein": { "version": "1.1.6", @@ -2545,8 +2458,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true, - "optional": true + "dev": true }, "kleur": { "version": "3.0.2", @@ -2572,15 +2484,13 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "optional": true + "dev": true }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, - "optional": true, "requires": { "object-visit": "^1.0.0" } @@ -2590,7 +2500,6 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, - "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -2627,7 +2536,6 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, - "optional": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -2638,7 +2546,6 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, - "optional": true, "requires": { "is-plain-object": "^2.0.4" } @@ -2658,8 +2565,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "optional": true + "dev": true }, "nan": { "version": "2.12.1", @@ -2673,7 +2579,6 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, - "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -2721,7 +2626,6 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, - "optional": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -2733,7 +2637,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -2743,7 +2646,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -2767,7 +2669,6 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, - "optional": true, "requires": { "isobject": "^3.0.0" } @@ -2777,7 +2678,6 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, - "optional": true, "requires": { "isobject": "^3.0.1" } @@ -2812,8 +2712,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "optional": true + "dev": true }, "path-dirname": { "version": "1.0.2", @@ -2844,8 +2743,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "optional": true + "dev": true }, "pretty-ms": { "version": "2.1.0", @@ -2932,7 +2830,6 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, - "optional": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -2992,8 +2889,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true, - "optional": true + "dev": true }, "repeat-string": { "version": "1.6.1", @@ -3014,8 +2910,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true, - "optional": true + "dev": true }, "resumer": { "version": "0.0.0", @@ -3030,8 +2925,7 @@ "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "optional": true + "dev": true }, "safe-buffer": { "version": "5.1.2", @@ -3044,7 +2938,6 @@ "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, - "optional": true, "requires": { "ret": "~0.1.10" } @@ -3060,7 +2953,6 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, - "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -3073,7 +2965,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -3096,7 +2987,6 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, - "optional": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -3113,7 +3003,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -3123,7 +3012,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -3135,7 +3023,6 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, - "optional": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -3147,7 +3034,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -3157,7 +3043,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -3167,7 +3052,6 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -3177,7 +3061,6 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -3191,7 +3074,6 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, - "optional": true, "requires": { "kind-of": "^3.2.0" }, @@ -3201,7 +3083,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -3219,7 +3100,6 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, - "optional": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -3232,8 +3112,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true, - "optional": true + "dev": true }, "split": { "version": "1.0.0", @@ -3249,7 +3128,6 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, - "optional": true, "requires": { "extend-shallow": "^3.0.0" } @@ -3259,7 +3137,6 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, - "optional": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -3270,7 +3147,6 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -3370,6 +3246,18 @@ "repeat-string": "^1.5.2", "tap-out": "^2.1.0", "through2": "^2.0.0" + }, + "dependencies": { + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + } } }, "tape": { @@ -3428,7 +3316,6 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -3438,7 +3325,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -3450,7 +3336,6 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, - "optional": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -3463,7 +3348,6 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -3514,7 +3398,6 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, - "optional": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -3527,7 +3410,6 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -3537,7 +3419,6 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, - "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -3552,7 +3433,6 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, - "optional": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -3563,7 +3443,6 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, - "optional": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -3575,7 +3454,6 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, - "optional": true, "requires": { "isarray": "1.0.0" } @@ -3586,8 +3464,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "optional": true + "dev": true } } }, @@ -3602,15 +3479,13 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true, - "optional": true + "dev": true }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "optional": true + "dev": true }, "util-deprecate": { "version": "1.0.2", diff --git a/readme.md b/readme.md index accf148d..ac51b543 100755 --- a/readme.md +++ b/readme.md @@ -663,7 +663,9 @@ Use up/down to navigate. Use tab to cycle the l | onState | `function` | On state change callback. Function signature is an `object` with two properties: `value` and `aborted` | ### multiselect(message, choices, [initial], [max], [hint], [warn]) -> Interactive multi-select prompt. +### autocompleteMultiselect(same) +> Interactive multi-select prompt. +> Autocomplete is a searchable multiselect prompt with the same options. Useful for long lists. Use space to toggle select/unselect and up/down to navigate. Use tab to cycle the list. You can also use right to select and left to deselect. By default this prompt returns an `array` containing the **values** of the selected items - not their display title. @@ -692,6 +694,7 @@ By default this prompt returns an `array` containing the **values** of the selec | message | `string` | Prompt message to display | | format | `function` | Receive user input. The returned value will be added to the response object | | choices | `Array` | Array of strings or choices objects `[{ title, value, disabled }, ...]`. The choice's index in the array will be used as its value if it is not specified. | +| min | `number` | Min select - will display error | | max | `number` | Max select | | hint | `string` | Hint to display to the user | | warn | `string` | Message to display when selecting a disabled option | diff --git a/test/prompts.js b/test/prompts.js index fc4addd0..f15b0cc8 100644 --- a/test/prompts.js +++ b/test/prompts.js @@ -13,7 +13,7 @@ test('basics', t => { }); test('prompts', t => { - t.plan(23); + t.plan(25); const types = [ 'text', @@ -25,6 +25,7 @@ test('prompts', t => { 'toggle', 'select', 'multiselect', + 'autocompleteMultiselect', 'autocomplete', 'date' ];