Giant blob of minor changes
[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, reject) => {
60       this._run(
61         (value) => resolve(value),
62         (error) => reject(error)
63       );
64     });
65   }
66
67   // Default noop (this one should be overwritten in prompts)
68   _run(cb) {
69     cb();
70   }
71
72   /**
73    * Throw an error telling a required parameter is missing
74    * @param  {String} name Name of the missing param
75    * @return {Throw Error}
76    */
77
78   throwParamError(name) {
79     throw new Error('You must provide a `' + name + '` parameter');
80   }
81
82   /**
83    * Called when the UI closes. Override to do any specific cleanup necessary
84    */
85   close() {
86     this.screen.releaseCursor();
87   }
88
89   /**
90    * Run the provided validation method each time a submit event occur.
91    * @param  {Rx.Observable} submit - submit event flow
92    * @return {Object}        Object containing two observables: `success` and `error`
93    */
94   handleSubmitEvents(submit) {
95     var self = this;
96     var validate = runAsync(this.opt.validate);
97     var asyncFilter = runAsync(this.opt.filter);
98     var validation = submit.pipe(
99       flatMap((value) =>
100         asyncFilter(value, self.answers).then(
101           (filteredValue) =>
102             validate(filteredValue, self.answers).then(
103               (isValid) => ({ isValid: isValid, value: filteredValue }),
104               (err) => ({ isValid: err, value: filteredValue })
105             ),
106           (err) => ({ isValid: err })
107         )
108       ),
109       share()
110     );
111
112     var success = validation.pipe(
113       filter((state) => state.isValid === true),
114       take(1)
115     );
116     var error = validation.pipe(
117       filter((state) => state.isValid !== true),
118       takeUntil(success)
119     );
120
121     return {
122       success: success,
123       error: error,
124     };
125   }
126
127   /**
128    * Generate the prompt question string
129    * @return {String} prompt question string
130    */
131
132   getQuestion() {
133     var message =
134       this.opt.prefix +
135       ' ' +
136       chalk.bold(this.opt.message) +
137       this.opt.suffix +
138       chalk.reset(' ');
139
140     // Append the default if available, and if question isn't answered
141     if (this.opt.default != null && this.status !== 'answered') {
142       // If default password is supplied, hide it
143       if (this.opt.type === 'password') {
144         message += chalk.italic.dim('[hidden] ');
145       } else {
146         message += chalk.dim('(' + this.opt.default + ') ');
147       }
148     }
149
150     return message;
151   }
152 }
153
154 module.exports = Prompt;