diff options
Diffstat (limited to 'sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui')
3 files changed, 351 insertions, 0 deletions
diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/baseUI.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/baseUI.js new file mode 100644 index 00000000..547e5658 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/baseUI.js @@ -0,0 +1,99 @@ +'use strict'; +const _ = { + extend: require('lodash/extend'), + omit: require('lodash/omit'), +}; +const MuteStream = require('mute-stream'); +const readline = require('readline'); + +/** + * 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 + const 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 + const ms = new MuteStream(); + ms.pipe(opt.output || process.stdout); + const output = ms; + + return _.extend( + { + terminal: true, + input, + output, + }, + _.omit(opt, ['input', 'output']) + ); +} + +module.exports = UI; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/bottom-bar.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/bottom-bar.js new file mode 100644 index 00000000..9235273e --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/bottom-bar.js @@ -0,0 +1,102 @@ +'use strict'; +/** + * Sticky bottom bar user interface + */ + +const through = require('through'); +const Base = require('./baseUI'); +const rlUtils = require('../utils/readline'); +const _ = { + last: require('lodash/last'), +}; + +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.enforceLF(data.toString())); + this.render(); + this.rl.output.mute(); + return this; + } + + /** + * Make sure line end on a line feed + * @param {String} str Input string + * @return {String} The input string with a final line feed + */ + + enforceLF(str) { + return str.match(/[\r\n]$/) ? str : str + '\n'; + } + + /** + * Helper for writing message in Prompt + * @param {BottomBar} prompt - The Prompt object that extends tty + * @param {String} message - The message to be output + */ + write(message) { + const msgLines = message.split(/\n/); + this.height = msgLines.length; + + // Write message to screen and setPrompt to control backspace + this.rl.setPrompt(_.last(msgLines)); + + if (this.rl.output.rows === 0 && this.rl.output.columns === 0) { + /* When it's a tty through serial port there's no terminal info and the render will malfunction, + so we need enforce the cursor to locate to the leftmost position for rendering. */ + rlUtils.left(this.rl, message.length + this.rl.line.length); + } + + this.rl.output.write(message); + } +} + +module.exports = BottomBar; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/prompt.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/prompt.js new file mode 100644 index 00000000..d9383879 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/ui/prompt.js @@ -0,0 +1,150 @@ +'use strict'; +const _ = { + isPlainObject: require('lodash/isPlainObject'), + clone: require('lodash/clone'), + isArray: require('lodash/isArray'), + get: require('lodash/get'), + set: require('lodash/set'), + isFunction: require('lodash/isFunction'), +}; +const { defer, empty, from, of } = require('rxjs'); +const { concatMap, filter, publish, reduce } = require('rxjs/operators'); +const runAsync = require('run-async'); +const utils = require('../utils/utils'); +const Base = require('./baseUI'); + +/** + * Base interface class other can inherits from + */ + +class PromptUI extends Base { + constructor(prompts, opt) { + super(opt); + this.prompts = prompts; + } + + run(questions, answers) { + // Keep global reference to the answers + if (_.isPlainObject(answers)) { + this.answers = _.clone(answers); + } else { + this.answers = {}; + } + + // Make sure questions is an array. + if (_.isPlainObject(questions)) { + // It's either an object of questions or a single question + questions = Object.values(questions).every( + (v) => _.isPlainObject(v) && v.name === undefined + ) + ? Object.entries(questions).map(([name, question]) => ({ name, ...question })) + : [questions]; + } + + // Create an observable, unless we received one as parameter. + // Note: As this is a public interface, we cannot do an instanceof check as we won't + // be using the exact same object in memory. + const obs = _.isArray(questions) ? from(questions) : questions; + + this.process = obs.pipe( + concatMap(this.processQuestion.bind(this)), + publish() // Creates a hot Observable. It prevents duplicating prompts. + ); + + this.process.connect(); + + return this.process + .pipe( + reduce((answers, answer) => { + _.set(answers, answer.name, answer.answer); + return answers; + }, this.answers) + ) + .toPromise(Promise) + .then(this.onCompletion.bind(this), this.onError.bind(this)); + } + + /** + * Once all prompt are over + */ + + onCompletion() { + this.close(); + + return this.answers; + } + + onError(error) { + this.close(); + return Promise.reject(error); + } + + processQuestion(question) { + question = _.clone(question); + return defer(() => { + const obs = of(question); + + return obs.pipe( + concatMap(this.setDefaultType.bind(this)), + concatMap(this.filterIfRunnable.bind(this)), + concatMap(() => + utils.fetchAsyncQuestionProperty(question, 'message', this.answers) + ), + concatMap(() => + utils.fetchAsyncQuestionProperty(question, 'default', this.answers) + ), + concatMap(() => + utils.fetchAsyncQuestionProperty(question, 'choices', this.answers) + ), + concatMap(this.fetchAnswer.bind(this)) + ); + }); + } + + fetchAnswer(question) { + const Prompt = this.prompts[question.type]; + this.activePrompt = new Prompt(question, this.rl, this.answers); + return defer(() => + from(this.activePrompt.run().then((answer) => ({ name: question.name, answer }))) + ); + } + + setDefaultType(question) { + // Default type to input + if (!this.prompts[question.type]) { + question.type = 'input'; + } + + return defer(() => of(question)); + } + + filterIfRunnable(question) { + if ( + question.askAnswered !== true && + _.get(this.answers, question.name) !== undefined + ) { + return empty(); + } + + if (question.when === false) { + return empty(); + } + + if (!_.isFunction(question.when)) { + return of(question); + } + + const { answers } = this; + return defer(() => + from( + runAsync(question.when)(answers).then((shouldRun) => { + if (shouldRun) { + return question; + } + }) + ).pipe(filter((val) => val != null)) + ); + } +} + +module.exports = PromptUI; |