You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
8.6 KiB
206 lines
8.6 KiB
'use strict'; |
|
const $ = exports; |
|
const el = require('./elements'); |
|
const noop = v => v; |
|
|
|
function toPrompt(type, args, opts={}) { |
|
return new Promise((res, rej) => { |
|
const p = new el[type](args); |
|
const onAbort = opts.onAbort || noop; |
|
const onSubmit = opts.onSubmit || noop; |
|
const onExit = opts.onExit || noop; |
|
p.on('state', args.onState || noop); |
|
p.on('submit', x => res(onSubmit(x))); |
|
p.on('exit', x => res(onExit(x))); |
|
p.on('abort', x => rej(onAbort(x))); |
|
}); |
|
} |
|
|
|
/** |
|
* Text prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {string} [args.initial] Default string value |
|
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') |
|
* @param {function} [args.onState] On state change callback |
|
* @param {function} [args.validate] Function to validate user input |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.text = args => toPrompt('TextPrompt', args); |
|
|
|
/** |
|
* Password prompt with masked input |
|
* @param {string} args.message Prompt message to display |
|
* @param {string} [args.initial] Default string value |
|
* @param {function} [args.onState] On state change callback |
|
* @param {function} [args.validate] Function to validate user input |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.password = args => { |
|
args.style = 'password'; |
|
return $.text(args); |
|
}; |
|
|
|
/** |
|
* Prompt where input is invisible, like sudo |
|
* @param {string} args.message Prompt message to display |
|
* @param {string} [args.initial] Default string value |
|
* @param {function} [args.onState] On state change callback |
|
* @param {function} [args.validate] Function to validate user input |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.invisible = args => { |
|
args.style = 'invisible'; |
|
return $.text(args); |
|
}; |
|
|
|
/** |
|
* Number prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {number} args.initial Default number value |
|
* @param {function} [args.onState] On state change callback |
|
* @param {number} [args.max] Max value |
|
* @param {number} [args.min] Min value |
|
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') |
|
* @param {Boolean} [opts.float=false] Parse input as floats |
|
* @param {Number} [opts.round=2] Round floats to x decimals |
|
* @param {Number} [opts.increment=1] Number to increment by when using arrow-keys |
|
* @param {function} [args.validate] Function to validate user input |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.number = args => toPrompt('NumberPrompt', args); |
|
|
|
/** |
|
* Date prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {number} args.initial Default number value |
|
* @param {function} [args.onState] On state change callback |
|
* @param {number} [args.max] Max value |
|
* @param {number} [args.min] Min value |
|
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') |
|
* @param {Boolean} [opts.float=false] Parse input as floats |
|
* @param {Number} [opts.round=2] Round floats to x decimals |
|
* @param {Number} [opts.increment=1] Number to increment by when using arrow-keys |
|
* @param {function} [args.validate] Function to validate user input |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.date = args => toPrompt('DatePrompt', args); |
|
|
|
/** |
|
* Classic yes/no prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {boolean} [args.initial=false] Default value |
|
* @param {function} [args.onState] On state change callback |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.confirm = args => toPrompt('ConfirmPrompt', args); |
|
|
|
/** |
|
* List prompt, split intput string by `seperator` |
|
* @param {string} args.message Prompt message to display |
|
* @param {string} [args.initial] Default string value |
|
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') |
|
* @param {string} [args.separator] String separator |
|
* @param {function} [args.onState] On state change callback |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input, in form of an `Array` |
|
*/ |
|
$.list = args => { |
|
const sep = args.separator || ','; |
|
return toPrompt('TextPrompt', args, { |
|
onSubmit: str => str.split(sep).map(s => s.trim()) |
|
}); |
|
}; |
|
|
|
/** |
|
* Toggle/switch prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {boolean} [args.initial=false] Default value |
|
* @param {string} [args.active="on"] Text for `active` state |
|
* @param {string} [args.inactive="off"] Text for `inactive` state |
|
* @param {function} [args.onState] On state change callback |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.toggle = args => toPrompt('TogglePrompt', args); |
|
|
|
/** |
|
* Interactive select prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {Array} args.choices Array of choices objects `[{ title, value }, ...]` |
|
* @param {number} [args.initial] Index of default value |
|
* @param {String} [args.hint] Hint to display |
|
* @param {function} [args.onState] On state change callback |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.select = args => toPrompt('SelectPrompt', args); |
|
|
|
/** |
|
* 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 |
|
* @param {string} [args.hint] Hint to display user |
|
* @param {Number} [args.cursor=0] Cursor start position |
|
* @param {function} [args.onState] On state change callback |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.multiselect = args => { |
|
args.choices = [].concat(args.choices || []); |
|
const toSelected = items => items.filter(item => item.selected).map(item => item.value); |
|
return toPrompt('MultiselectPrompt', args, { |
|
onAbort: toSelected, |
|
onSubmit: toSelected |
|
}); |
|
}; |
|
|
|
$.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()) |
|
); |
|
|
|
/** |
|
* Interactive auto-complete prompt |
|
* @param {string} args.message Prompt message to display |
|
* @param {Array} args.choices Array of auto-complete choices objects `[{ title, value }, ...]` |
|
* @param {Function} [args.suggest] Function to filter results based on user input. Defaults to sort by `title` |
|
* @param {number} [args.limit=10] Max number of results to show |
|
* @param {string} [args.style="default"] Render style ('default', 'password', 'invisible') |
|
* @param {String} [args.initial] Index of the default value |
|
* @param {boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input |
|
* @param {String} [args.fallback] Fallback message - defaults to initial value |
|
* @param {function} [args.onState] On state change callback |
|
* @param {Stream} [args.stdin] The Readable stream to listen to |
|
* @param {Stream} [args.stdout] The Writable stream to write readline data to |
|
* @returns {Promise} Promise with user input |
|
*/ |
|
$.autocomplete = args => { |
|
args.suggest = args.suggest || byTitle; |
|
args.choices = [].concat(args.choices || []); |
|
return toPrompt('AutocompletePrompt', args); |
|
};
|
|
|