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); | 
						|
};
 | 
						|
 |