299b65826f8041b33ac0cc68e9d7bce37ff93ffb
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / inquirer / lib / prompts / base.js
1 'use strict';
2 /**
3  * Base prompt implementation
4  * Should be extended by prompt types.
5  */
6 var _ = {
7   assign: require('lodash/assign'),
8   defaults: require('lodash/defaults'),
9   clone: require('lodash/clone'),
10 };
11 var chalk = require('chalk');
12 var runAsync = require('run-async');
13 var { filter, flatMap, share, take, takeUntil } = require('rxjs/operators');
14 var Choices = require('../objects/choices');
15 var ScreenManager = require('../utils/screen-manager');
16
17 class Prompt {
18   constructor(question, rl, answers) {
19     // Setup instance defaults property
20     _.assign(this, {
21       answers: answers,
22       status: 'pending',
23     });
24
25     // Set defaults prompt options
26     this.opt = _.defaults(_.clone(question), {
27       validate: () => true,
28       filter: (val) => val,
29       when: () => true,
30       suffix: '',
31       prefix: chalk.green('?'),
32     });
33
34     // Make sure name is present
35     if (!this.opt.name) {
36       this.throwParamError('name');
37     }
38
39     // Set default message if no message defined
40     if (!this.opt.message) {
41       this.opt.message = this.opt.name + ':';
42     }
43
44     // Normalize choices
45     if (Array.isArray(this.opt.choices)) {
46       this.opt.choices = new Choices(this.opt.choices, answers);
47     }
48
49     this.rl = rl;
50     this.screen = new ScreenManager(this.rl);
51   }
52
53   /**
54    * Start the Inquiry session and manage output value filtering
55    * @return {Promise}
56    */
57
58   run() {
59     return new Promise((resolve) => {
60       this._run((value) => resolve(value));
61     });
62   }
63
64   // Default noop (this one should be overwritten in prompts)
65   _run(cb) {
66     cb();
67   }
68
69   /**
70    * Throw an error telling a required parameter is missing
71    * @param  {String} name Name of the missing param
72    * @return {Throw Error}
73    */
74
75   throwParamError(name) {
76     throw new Error('You must provide a `' + name + '` parameter');
77   }
78
79   /**
80    * Called when the UI closes. Override to do any specific cleanup necessary
81    */
82   close() {
83     this.screen.releaseCursor();
84   }
85
86   /**
87    * Run the provided validation method each time a submit event occur.
88    * @param  {Rx.Observable} submit - submit event flow
89    * @return {Object}        Object containing two observables: `success` and `error`
90    */
91   handleSubmitEvents(submit) {
92     var self = this;
93     var validate = runAsync(this.opt.validate);
94     var asyncFilter = runAsync(this.opt.filter);
95     var validation = submit.pipe(
96       flatMap((value) =>
97         asyncFilter(value, self.answers).then(
98           (filteredValue) =>
99             validate(filteredValue, self.answers).then(
100               (isValid) => ({ isValid: isValid, value: filteredValue }),
101               (err) => ({ isValid: err, value: filteredValue })
102             ),
103           (err) => ({ isValid: err })
104         )
105       ),
106       share()
107     );
108
109     var success = validation.pipe(
110       filter((state) => state.isValid === true),
111       take(1)
112     );
113     var error = validation.pipe(
114       filter((state) => state.isValid !== true),
115       takeUntil(success)
116     );
117
118     return {
119       success: success,
120       error: error,
121     };
122   }
123
124   /**
125    * Generate the prompt question string
126    * @return {String} prompt question string
127    */
128
129   getQuestion() {
130     var message =
131       this.opt.prefix +
132       ' ' +
133       chalk.bold(this.opt.message) +
134       this.opt.suffix +
135       chalk.reset(' ');
136
137     // Append the default if available, and if question isn't answered
138     if (this.opt.default != null && this.status !== 'answered') {
139       // If default password is supplied, hide it
140       if (this.opt.type === 'password') {
141         message += chalk.italic.dim('[hidden] ');
142       } else {
143         message += chalk.dim('(' + this.opt.default + ') ');
144       }
145     }
146
147     return message;
148   }
149 }
150
151 module.exports = Prompt;