diff options
| author | Danijel Andjelkovic <adanijel99@gmail.com> | 2022-03-01 20:21:29 +0000 | 
|---|---|---|
| committer | Danijel Andjelkovic <adanijel99@gmail.com> | 2022-03-01 20:21:29 +0000 | 
| commit | 61cb1570a3410c85a4489b97c172e3a50715f36c (patch) | |
| tree | 8fe4a5b77ea54bba80abc817ce2c9ef0e79e7e66 /sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts | |
| parent | 21a53d349788c99d2007cba91a923db982353b31 (diff) | |
| parent | a9ee9e0a500a4a15bd0b5dcaf041f827228ed309 (diff) | |
Merge branch 'researchML' into 'dev'
Research ml
See merge request igrannonica/neuronstellar!6
Diffstat (limited to 'sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts')
10 files changed, 1647 insertions, 0 deletions
| diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/base.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/base.js new file mode 100644 index 00000000..ec503eec --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/base.js @@ -0,0 +1,181 @@ +'use strict'; +/** + * Base prompt implementation + * Should be extended by prompt types. + */ +const _ = { +  assign: require('lodash/assign'), +  defaults: require('lodash/defaults'), +  clone: require('lodash/clone'), +}; +const chalk = require('chalk'); +const runAsync = require('run-async'); +const { filter, flatMap, share, take, takeUntil } = require('rxjs/operators'); +const Choices = require('../objects/choices'); +const ScreenManager = require('../utils/screen-manager'); + +class Prompt { +  constructor(question, rl, answers) { +    // Setup instance defaults property +    _.assign(this, { +      answers, +      status: 'pending', +    }); + +    // Set defaults prompt options +    this.opt = _.defaults(_.clone(question), { +      validate: () => true, +      validatingText: '', +      filter: (val) => val, +      filteringText: '', +      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) { +    const self = this; +    const validate = runAsync(this.opt.validate); +    const asyncFilter = runAsync(this.opt.filter); +    const validation = submit.pipe( +      flatMap((value) => { +        this.startSpinner(value, this.opt.filteringText); +        return asyncFilter(value, self.answers).then( +          (filteredValue) => { +            this.startSpinner(filteredValue, this.opt.validatingText); +            return validate(filteredValue, self.answers).then( +              (isValid) => ({ isValid, value: filteredValue }), +              (err) => ({ isValid: err, value: filteredValue }) +            ); +          }, +          (err) => ({ isValid: err }) +        ); +      }), +      share() +    ); + +    const success = validation.pipe( +      filter((state) => state.isValid === true), +      take(1) +    ); +    const error = validation.pipe( +      filter((state) => state.isValid !== true), +      takeUntil(success) +    ); + +    return { +      success, +      error, +    }; +  } + +  startSpinner(value, bottomContent) { +    value = this.getSpinningValue(value); +    // If the question will spin, cut off the prefix (for layout purposes) +    const content = bottomContent +      ? this.getQuestion() + value +      : this.getQuestion().slice(this.opt.prefix.length + 1) + value; + +    this.screen.renderWithSpinner(content, bottomContent); +  } + +  /** +   * Allow override, e.g. for password prompts +   * See: https://github.com/SBoudrias/Inquirer.js/issues/1022 +   * +   * @return {String} value to display while spinning +   */ +  getSpinningValue(value) { +    return value; +  } + +  /** +   * Generate the prompt question string +   * @return {String} prompt question string +   */ +  getQuestion() { +    let message = +      (this.opt.prefix ? this.opt.prefix + ' ' : '') + +      chalk.bold(this.opt.message) + +      this.opt.suffix + +      chalk.reset(' '); + +    // Append the default if available, and if question isn't touched/answered +    if ( +      this.opt.default != null && +      this.status !== 'touched' && +      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; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/checkbox.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/checkbox.js new file mode 100644 index 00000000..4f60b77e --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/checkbox.js @@ -0,0 +1,278 @@ +'use strict'; +/** + * `list` type prompt + */ + +const _ = { +  isArray: require('lodash/isArray'), +  map: require('lodash/map'), +  isString: require('lodash/isString'), +}; +const chalk = require('chalk'); +const cliCursor = require('cli-cursor'); +const figures = require('figures'); +const { map, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const observe = require('../utils/events'); +const Paginator = require('../utils/paginator'); +const incrementListIndex = require('../utils/incrementListIndex'); + +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; + +    const events = observe(this.rl); + +    const 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 +    let message = this.getQuestion(); +    let bottomContent = ''; + +    if (!this.dontShowHints) { +      message += +        '(Press ' + +        chalk.cyan.bold('<space>') + +        ' to select, ' + +        chalk.cyan.bold('<a>') + +        ' to toggle all, ' + +        chalk.cyan.bold('<i>') + +        ' to invert selection, and ' + +        chalk.cyan.bold('<enter>') + +        ' to proceed)'; +    } + +    // Render choices or answer depending on the state +    if (this.status === 'answered') { +      message += chalk.cyan(this.selection.join(', ')); +    } else { +      const choicesStr = renderChoices(this.opt.choices, this.pointer); +      const indexPosition = this.opt.choices.indexOf( +        this.opt.choices.getChoice(this.pointer) +      ); +      const realIndexPosition = +        this.opt.choices.reduce((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; +          } + +          let 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.dontShowHints = 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() { +    const choices = this.opt.choices.filter( +      (choice) => 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.toggleChoice(this.pointer); +    this.render(); +  } + +  onAllKey() { +    const shouldBeChecked = Boolean( +      this.opt.choices.find((choice) => choice.type !== 'separator' && !choice.checked) +    ); + +    this.opt.choices.forEach((choice) => { +      if (choice.type !== 'separator') { +        choice.checked = shouldBeChecked; +      } +    }); + +    this.render(); +  } + +  onInverseKey() { +    this.opt.choices.forEach((choice) => { +      if (choice.type !== 'separator') { +        choice.checked = !choice.checked; +      } +    }); + +    this.render(); +  } + +  toggleChoice(index) { +    const 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) { +  let output = ''; +  let 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') + ')'; +    } else { +      const 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; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/confirm.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/confirm.js new file mode 100644 index 00000000..8171aab5 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/confirm.js @@ -0,0 +1,102 @@ +'use strict'; +/** + * `confirm` type prompt + */ + +const _ = { +  extend: require('lodash/extend'), +  isBoolean: require('lodash/isBoolean'), +}; +const chalk = require('chalk'); +const { take, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const observe = require('../utils/events'); + +class ConfirmPrompt extends Base { +  constructor(questions, rl, answers) { +    super(questions, rl, answers); + +    let rawDefault = true; + +    _.extend(this.opt, { +      filter(input) { +        let 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) +    const 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) { +    let 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'; + +    const 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; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/editor.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/editor.js new file mode 100644 index 00000000..600e0745 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/editor.js @@ -0,0 +1,100 @@ +'use strict'; +/** + * `editor` type prompt + */ + +const chalk = require('chalk'); +const { editAsync } = require('external-editor'); +const Base = require('./base'); +const observe = require('../utils/events'); +const { Subject } = require('rxjs'); + +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) +    const events = observe(this.rl); +    this.lineSubscription = events.line.subscribe(this.startExternalEditor.bind(this)); + +    // Trigger Validation when editor closes +    const 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) { +    let bottomContent = ''; +    let 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; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/expand.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/expand.js new file mode 100644 index 00000000..af1ad810 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/expand.js @@ -0,0 +1,282 @@ +'use strict'; +/** + * `rawlist` type prompt + */ + +const _ = { +  uniq: require('lodash/uniq'), +  isString: require('lodash/isString'), +  isNumber: require('lodash/isNumber'), +  findIndex: require('lodash/findIndex'), +}; +const chalk = require('chalk'); +const { map, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const Separator = require('../objects/separator'); +const observe = require('../utils/events'); +const Paginator = require('../utils/paginator'); + +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. +    const events = observe(this.rl); +    const 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) { +    let message = this.getQuestion(); +    let bottomContent = ''; + +    if (this.status === 'answered') { +      message += chalk.cyan(this.answer); +    } else if (this.status === 'expanded') { +      const 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; +    } + +    const 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() { +    let output = ''; + +    this.opt.choices.forEach((choice) => { +      output += '\n  '; + +      if (choice.type === 'separator') { +        output += ' ' + choice; +        return; +      } + +      let 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'; +    const 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(); +    const 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) { +    let formatError; +    const errors = []; +    const keymap = {}; +    choices.filter(Separator.exclude).forEach((choice) => { +      if (!choice.key || choice.key.length !== 1) { +        formatError = true; +      } + +      choice.key = String(choice.key).toLowerCase(); + +      if (keymap[choice.key]) { +        errors.push(choice.key); +      } + +      keymap[choice.key] = true; +    }); + +    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) { +    let defIndex = choices.realLength - 1; +    if (_.isNumber(defaultChoice) && this.opt.choices.getChoice(defaultChoice)) { +      defIndex = defaultChoice; +    } else if (_.isString(defaultChoice)) { +      const index = _.findIndex( +        choices.realChoices, +        ({ value }) => value === defaultChoice +      ); +      defIndex = index === -1 ? defIndex : index; +    } + +    const 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) { +  let output = ''; + +  choices.forEach((choice) => { +    output += '\n  '; + +    if (choice.type === 'separator') { +      output += ' ' + choice; +      return; +    } + +    let choiceStr = choice.key + ') ' + choice.name; +    if (pointer === choice.key) { +      choiceStr = chalk.cyan(choiceStr); +    } + +    output += choiceStr; +  }); + +  return output; +} + +module.exports = ExpandPrompt; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/input.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/input.js new file mode 100644 index 00000000..87f68b92 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/input.js @@ -0,0 +1,110 @@ +'use strict'; +/** + * `input` type prompt + */ + +const chalk = require('chalk'); +const { map, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const observe = require('../utils/events'); + +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) +    const events = observe(this.rl); +    const submit = events.line.pipe(map(this.filterInput.bind(this))); + +    const 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) { +    let bottomContent = ''; +    let appendContent = ''; +    let message = this.getQuestion(); +    const { transformer } = this.opt; +    const 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() { +    this.state = 'touched'; + +    this.render(); +  } +} + +module.exports = InputPrompt; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/list.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/list.js new file mode 100644 index 00000000..486c030e --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/list.js @@ -0,0 +1,214 @@ +'use strict'; +/** + * `list` type prompt + */ + +const _ = { +  isNumber: require('lodash/isNumber'), +  findIndex: require('lodash/findIndex'), +  isString: require('lodash/isString'), +}; +const chalk = require('chalk'); +const figures = require('figures'); +const cliCursor = require('cli-cursor'); +const runAsync = require('run-async'); +const { flatMap, map, take, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const observe = require('../utils/events'); +const Paginator = require('../utils/paginator'); +const incrementListIndex = require('../utils/incrementListIndex'); + +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; + +    const 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) { +      const 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; + +    const self = this; + +    const 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, self.answers).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 +    let 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 { +      const choicesStr = listRender(this.opt.choices, this.selected); +      const indexPosition = this.opt.choices.indexOf( +        this.opt.choices.getChoice(this.selected) +      ); +      const realIndexPosition = +        this.opt.choices.reduce((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; +          } + +          let 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) { +  let output = ''; +  let 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; +    } + +    const isSelected = i - separatorOffset === pointer; +    let line = (isSelected ? figures.pointer + ' ' : '  ') + choice.name; +    if (isSelected) { +      line = chalk.cyan(line); +    } + +    output += line + ' \n'; +  }); + +  return output.replace(/\n$/, ''); +} + +module.exports = ListPrompt; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/number.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/number.js new file mode 100644 index 00000000..ccabc018 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/number.js @@ -0,0 +1,29 @@ +'use strict'; +/** + * `input` type prompt + */ + +const Input = require('./input'); + +/** + * 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 +      const 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; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/password.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/password.js new file mode 100644 index 00000000..840249d3 --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/password.js @@ -0,0 +1,127 @@ +'use strict'; +/** + * `password` type prompt + */ + +const chalk = require('chalk'); +const { map, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const observe = require('../utils/events'); + +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; + +    const events = observe(this.rl); + +    // Once user confirm (enter key) +    const submit = events.line.pipe(map(this.filterInput.bind(this))); + +    const 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) { +    let message = this.getQuestion(); +    let bottomContent = ''; + +    if (this.status === 'answered') { +      message += this.getMaskedValue(this.answer); +    } else { +      message += this.getMaskedValue(this.rl.line || ''); +    } + +    if (error) { +      bottomContent = '\n' + chalk.red('>> ') + error; +    } + +    this.screen.render(message, bottomContent); +  } + +  getMaskedValue(value) { +    if (this.status === 'answered') { +      return this.opt.mask +        ? chalk.cyan(mask(value, this.opt.mask)) +        : chalk.italic.dim('[hidden]'); +    } +    return this.opt.mask +      ? mask(value, this.opt.mask) +      : chalk.italic.dim('[input is hidden] '); +  } + +  /** +   * Mask value during async filter/validation. +   */ +  getSpinningValue(value) { +    return this.getMaskedValue(value); +  } + +  /** +   * 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; diff --git a/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/rawlist.js b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/rawlist.js new file mode 100644 index 00000000..06036eaf --- /dev/null +++ b/sandbox/testAppNevena/Front/node_modules/inquirer/lib/prompts/rawlist.js @@ -0,0 +1,224 @@ +'use strict'; +/** + * `rawlist` type prompt + */ + +const _ = { +  extend: require('lodash/extend'), +  isNumber: require('lodash/isNumber'), +  findIndex: require('lodash/findIndex'), +}; +const chalk = require('chalk'); +const { map, takeUntil } = require('rxjs/operators'); +const Base = require('./base'); +const Separator = require('../objects/separator'); +const observe = require('../utils/events'); +const Paginator = require('../utils/paginator'); +const incrementListIndex = require('../utils/incrementListIndex'); + +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(val) { +        return val != null; +      }, +    }); + +    const 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) { +      const index = _.findIndex( +        this.opt.choices.realChoices, +        ({ value }) => value === def +      ); +      const 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) +    const events = observe(this.rl); +    const submit = events.line.pipe(map(this.getCurrentValue.bind(this))); + +    const validation = this.handleSubmitEvents(submit); +    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.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 +    let message = this.getQuestion(); +    let bottomContent = ''; + +    if (this.status === 'answered') { +      message += chalk.cyan(this.opt.choices.getChoice(this.selected).short); +    } else { +      const 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 === '') { +      this.selected = this.selected === undefined ? -1 : this.selected; +      index = this.selected; +    } else { +      index -= 1; +    } + +    const 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() { +    const 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) { +  let output = ''; +  let separatorOffset = 0; + +  choices.forEach((choice, i) => { +    output += '\n  '; + +    if (choice.type === 'separator') { +      separatorOffset++; +      output += ' ' + choice; +      return; +    } + +    const index = i - separatorOffset; +    let display = index + 1 + ') ' + choice.name; +    if (index === pointer) { +      display = chalk.cyan(display); +    } + +    output += display; +  }); + +  return output; +} + +module.exports = RawListPrompt; | 
