lib/index.js
async function prompt(questions=[], { onSubmit=noop, onCancel=noop }={}) {
  const answers = {};
  const override = prompt._override || {};
  questions = [].concat(questions);
  let answer, question, quit, name, type;

  const getFormattedAnswer = async (question, answer, skipValidation = false) => {
    if (!skipValidation && question.validate && question.validate(answer) !== true) {
      return;
    }
    return question.format ? await question.format(answer, answers) : answer
  };

  for (question of questions) {
    ({ name, type } = question);

    // if property is a function, invoke it unless it's a special function
    for (let key in question) {
      if (passOn.includes(key)) continue;
      let value = question[key];
      question[key] = typeof value === 'function' ? await value(answer, { ...answers }, question) : value;
    }

    if (typeof question.message !== 'string') {
      throw new Error('prompt message is required');
    }

    // update vars in case they changed
    ({ name, type } = question);

    // skip if type is a falsy value
    if (!type) continue;

    if (prompts[type] === void 0) {
      throw new Error(`prompt type (${type}) is not defined`);
    }

    if (override[question.name] !== undefined) {
      answer = await getFormattedAnswer(question, override[question.name]);
      if (answer !== undefined) {
        answers[name] = answer;
        continue;
      }
    }

    try {
      // Get the injected answer if there is one or prompt the user
      answer = prompt._injected ? getInjectedAnswer(prompt._injected) : await prompts[type](question);
      answers[name] = answer = await getFormattedAnswer(question, answer, true);
      quit = await onSubmit(question, answer, answers);
    } catch (err) {
      quit = !(await onCancel(question, answers));
    }

    if (quit) return answers;
  }

  return answers;
}
async function prompt(questions=[], { onSubmit=noop, onCancel=noop }={}) {
  const answers = {};
  const override = prompt._override || {};
  questions = [].concat(questions);
  let answer, question, quit, name, type;

  const getFormattedAnswer = async (question, answer, skipValidation = false) => {
    if (!skipValidation && question.validate && question.validate(answer) !== true) {
      return;
    }
    return question.format ? await question.format(answer, answers) : answer
  };

  for (question of questions) {
    ({ name, type } = question);

    // if property is a function, invoke it unless it's a special function
    for (let key in question) {
      if (passOn.includes(key)) continue;
      let value = question[key];
      question[key] = typeof value === 'function' ? await value(answer, { ...answers }, question) : value;
    }

    if (typeof question.message !== 'string') {
      throw new Error('prompt message is required');
    }

    // update vars in case they changed
    ({ name, type } = question);

    // skip if type is a falsy value
    if (!type) continue;

    if (prompts[type] === void 0) {
      throw new Error(`prompt type (${type}) is not defined`);
    }

    if (override[question.name] !== undefined) {
      answer = await getFormattedAnswer(question, override[question.name]);
      if (answer !== undefined) {
        answers[name] = answer;
        continue;
      }
    }

    try {
      // Get the injected answer if there is one or prompt the user
      answer = prompt._injected ? getInjectedAnswer(prompt._injected) : await prompts[type](question);
      answers[name] = answer = await getFormattedAnswer(question, answer, true);
      quit = await onSubmit(question, answer, answers);
    } catch (err) {
      quit = !(await onCancel(question, answers));
    }

    if (quit) return answers;
  }

  return answers;
}
async function prompt ( questions = [ ] , { onSubmit = noop , onCancel = noop } = { } ) { const answers = { } ; const override = prompt . _override || { } ; questions = [ ] . concat ( questions ) ; let answer , question , quit , name , type ; const getFormattedAnswer = async ( question , answer , skipValidation = false ) => { if ( ! skipValidation && question . validate && question . validate ( answer ) !== true ) { return ; } return question . format ? await question . format ( answer , answers ) : answer } ; for ( question of questions ) { ( { name , type } = question ) ; // if property is a function, invoke it unless it's a special function for ( let key in question ) { if ( passOn . includes ( key ) ) continue ; let value = question [ key ] ; question [ key ] = typeof value === 'function' ? await value ( answer , { ... answers } , question ) : value ; } if ( typeof question . message !== 'string' ) { throw new Error ( 'prompt message is required' ) ; } // update vars in case they changed ( { name , type } = question ) ; // skip if type is a falsy value if ( ! type ) continue ; if ( prompts [ type ] === void 0 ) { throw new Error ( ` ${ type } ` ) ; } if ( override [ question . name ] !== undefined ) { answer = await getFormattedAnswer ( question , override [ question . name ] ) ; if ( answer !== undefined ) { answers [ name ] = answer ; continue ; } } try { // Get the injected answer if there is one or prompt the user answer = prompt . _injected ? getInjectedAnswer ( prompt . _injected ) : await prompts [ type ] ( question ) ; answers [ name ] = answer = await getFormattedAnswer ( question , answer , true ) ; quit = await onSubmit ( question , answer , answers ) ; } catch ( err ) { quit = ! ( await onCancel ( question , answers ) ) ; } if ( quit ) return answers ; } return answers ; }
Prompt for a series of questions
@param {Array|Object} questions Single question object or Array of question objects
@param {Function} [onSubmit] Callback function called on prompt submit
@param {Function} [onCancel] Callback function called on cancel/abort
@returns {Object} Object with values from user input
Prompt for a series of questions