3 const assert = require('assert');
4 const Events = require('events');
5 const utils = require('./lib/utils');
8 * Create an instance of `Enquirer`.
11 * const Enquirer = require('enquirer');
12 * const enquirer = new Enquirer();
15 * @param {Object} `options` (optional) Options to use with all prompts.
16 * @param {Object} `answers` (optional) Answers object to initialize with.
20 class Enquirer extends Events {
21 constructor(options, answers) {
23 this.options = utils.merge({}, options);
24 this.answers = { ...answers };
28 * Register a custom prompt type.
31 * const Enquirer = require('enquirer');
32 * const enquirer = new Enquirer();
33 * enquirer.register('customType', require('./custom-prompt'));
36 * @param {String} `type`
37 * @param {Function|Prompt} `fn` `Prompt` class, or a function that returns a `Prompt` class.
38 * @return {Object} Returns the Enquirer instance
43 if (utils.isObject(type)) {
44 for (let key of Object.keys(type)) this.register(key, type[key]);
47 assert.equal(typeof fn, 'function', 'expected a function');
48 let name = type.toLowerCase();
49 if (fn.prototype instanceof this.Prompt) {
50 this.prompts[name] = fn;
52 this.prompts[name] = fn(this.Prompt, this);
58 * Prompt function that takes a "question" object or array of question objects,
59 * and returns an object with responses from the user.
62 * const Enquirer = require('enquirer');
63 * const enquirer = new Enquirer();
65 * const response = await enquirer.prompt({
68 * message: 'What is your username?'
70 * console.log(response);
73 * @param {Array|Object} `questions` Options objects for one or more prompts to run.
74 * @return {Promise} Promise that returns an "answers" object with the user's responses.
78 async prompt(questions = []) {
79 for (let question of [].concat(questions)) {
81 if (typeof question === 'function') question = await question.call(this);
82 await this.ask(utils.merge({}, this.options, question));
84 return Promise.reject(err);
91 if (typeof question === 'function') {
92 question = await question.call(this);
95 let opts = utils.merge({}, this.options, question);
96 let { type, name } = question;
97 let { set, get } = utils;
99 if (typeof type === 'function') {
100 type = await type.call(this, question, this.answers);
103 if (!type) return this.answers[name];
105 assert(this.prompts[type], `Prompt "${type}" is not registered`);
107 let prompt = new this.prompts[type](opts);
108 let value = get(this.answers, name);
110 prompt.state.answers = this.answers;
111 prompt.enquirer = this;
114 prompt.on('submit', value => {
115 this.emit('answer', name, value, prompt);
116 set(this.answers, name, value);
121 let emit = prompt.emit.bind(prompt);
122 prompt.emit = (...args) => {
123 this.emit.call(this, ...args);
124 return emit(...args);
127 this.emit('prompt', prompt, this);
129 if (opts.autofill && value != null) {
130 prompt.value = prompt.input = value;
132 // if "autofill=show" render the prompt, otherwise stay "silent"
133 if (opts.autofill === 'show') {
134 await prompt.submit();
137 value = prompt.value = await prompt.run();
144 * Use an enquirer plugin.
147 * const Enquirer = require('enquirer');
148 * const enquirer = new Enquirer();
149 * const plugin = enquirer => {
150 * // do stuff to enquire instance
152 * enquirer.use(plugin);
155 * @param {Function} `plugin` Plugin function that takes an instance of Enquirer.
156 * @return {Object} Returns the Enquirer instance.
161 plugin.call(this, this);
166 this._Prompt = value;
169 return this._Prompt || this.constructor.Prompt;
173 return this.constructor.prompts;
176 static set Prompt(value) {
177 this._Prompt = value;
179 static get Prompt() {
180 return this._Prompt || require('./lib/prompt');
183 static get prompts() {
184 return require('./lib/prompts');
188 return require('./lib/types');
192 * Prompt function that takes a "question" object or array of question objects,
193 * and returns an object with responses from the user.
196 * const { prompt } = require('enquirer');
197 * const response = await prompt({
200 * message: 'What is your username?'
202 * console.log(response);
204 * @name Enquirer#prompt
205 * @param {Array|Object} `questions` Options objects for one or more prompts to run.
206 * @return {Promise} Promise that returns an "answers" object with the user's responses.
210 static get prompt() {
211 const fn = (questions, ...rest) => {
212 let enquirer = new this(...rest);
213 let emit = enquirer.emit.bind(enquirer);
214 enquirer.emit = (...args) => {
216 return emit(...args);
218 return enquirer.prompt(questions);
220 utils.mixinEmitter(fn, new Events());
225 utils.mixinEmitter(Enquirer, new Events());
226 const prompts = Enquirer.prompts;
228 for (let name of Object.keys(prompts)) {
229 let key = name.toLowerCase();
231 let run = options => new prompts[name](options).run();
232 Enquirer.prompt[key] = run;
235 if (!Enquirer[name]) {
236 Reflect.defineProperty(Enquirer, name, { get: () => prompts[name] });
240 const exp = name => {
241 utils.defineExport(Enquirer, name, () => Enquirer.types[name]);
246 exp('BooleanPrompt');
250 module.exports = Enquirer;