SBoudrias / Inquirer.js

A collection of common interactive command line user interfaces.
MIT License
20.28k stars 1.3k forks source link

Can't reuse `rl` #967

Closed RobinKnipe closed 3 months ago

RobinKnipe commented 4 years ago

https://github.com/SBoudrias/Inquirer.js/blob/f14ecd77386edfcb7340c667d804867295cbcfda/packages/inquirer/lib/ui/baseUI.js#L17 I am I missing something fundamental, or is it completely impossible for this.rl to have any value at the start of the constructor? It's a shame because I think I need to pass an existing rl to a descendant class of the baseUI, but it seems there's no way to do this.

SBoudrias commented 4 years ago

Could you do with passing the stdin/stdout? This is possible, but not a full readline instance.

Can you also explain a little bit more what you're trying to achieve?

RobinKnipe commented 4 years ago

:wave: hi! I'm trying to resurrect an old prompt type called recursive. I'm using plop and so don't want / can't guarantee access to the underlying inquirer process - instead preferring to defining nested prompt flows as a single object, e.g.

const questions = [{
    type: 'input',
    name: 'collection-name',
    message: 'What is this collection called?'
  }, {
    type: 'recursive',
    name: 'collection-items',
    message: 'Add an item?',
    prompts: [{
        type: 'input',
        name: 'item-name',
        message: 'Enter the item name'
      }, {
        type: 'input',
        name: 'item-description',
        message: 'Enter the item description'
      }]
    },
  // other config
];
RobinKnipe commented 4 years ago

My RecursivePrompt implementation looks like this so far:


const inquirer = require('inquirer');
const ConfirmPrompt = require('inquirer/lib/prompts/confirm');

class RecursivePrompt extends ConfirmPrompt {
  constructor({ firstMessage, nextMessage, prompts, ...questions }, rl, answers) {
    super({
      ...questions,
      message: firstMessage || questions.message
    }, rl, answers);

    this.recusiveConfig = {
      questions: [...prompts, {
        type: 'confirm',
        name: 'askAgain',
        message: nextMessage || questions.message
      }]
    };
  }

  _run(cb) {
    const { questions } = this.recusiveConfig;
    const responses = [];
    const ask = begin => begin ?
      inquirer.prompt(questions).then(({askAgain, ...answers}) => {
        responses.push(answers);
        return ask(askAgain);
      }) :
      cb(responses);

    super._run(ask);
  }
}

module.exports = RecursivePrompt;