index.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use strict';
  2. const prompts = require('./prompts');
  3. const ignore = ['suggest', 'format', 'onState'];
  4. const noop = () => {};
  5. /**
  6. * Prompt for a series of questions
  7. * @param {Array|Object} questions Single question object or Array of question objects
  8. * @returns {Object} Object with values from user input
  9. */
  10. async function prompt(questions=[], { onSubmit=noop, onCancel=noop }={}) {
  11. const answers = {};
  12. questions = [].concat(questions);
  13. let answer, question, quit, name, type;
  14. let MAP = prompt._map || {};
  15. for (question of questions) {
  16. ({ name, type } = question);
  17. if (MAP[name] !== void 0) {
  18. answers[name] = MAP[name];
  19. delete MAP[name];
  20. continue; // take val & run
  21. }
  22. // if property is a function, invoke it unless it's ignored
  23. for (let key in question) {
  24. if (ignore.includes(key)) continue;
  25. let value = question[key];
  26. question[key] = typeof value === 'function' ? await value(answer, { ...answers }, question) : value;
  27. }
  28. if (typeof question.message !== 'string') {
  29. throw new Error('prompt message is required');
  30. }
  31. // update vars in case they changed
  32. ({ name, type } = question);
  33. // skip if type is a falsy value
  34. if (!type) continue;
  35. if (prompts[type] === void 0) {
  36. throw new Error(`prompt type (${type}) is not defined`);
  37. }
  38. try {
  39. answer = await prompts[type](question);
  40. answers[name] = answer = question.format ? await question.format(answer, answers) : answer;
  41. quit = onSubmit(question, answer);
  42. } catch (err) {
  43. quit = !onCancel(question);
  44. }
  45. if (quit) return answers;
  46. }
  47. return answers;
  48. }
  49. function inject(obj) {
  50. prompt._map = prompt._map || {};
  51. for (let k in obj) {
  52. prompt._map[k] = obj[k];
  53. }
  54. }
  55. module.exports = Object.assign(prompt, { prompt, prompts, inject });