summaryrefslogtreecommitdiff
path: root/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/base.js
blob: c7fd14fbef0092bc8e7de92b024facd9fc88ade3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
 * Base prompt implementation
 * Should be extended by prompt types.
 */

var _ = require('lodash');
var chalk = require('chalk');
var runAsync = require('run-async');
var Choices = require('../objects/choices');
var ScreenManager = require('../utils/screen-manager');

var Prompt = module.exports = function (question, rl, answers) {
  // Setup instance defaults property
  _.assign(this, {
    answers: answers,
    status: 'pending'
  });

  // Set defaults prompt options
  this.opt = _.defaults(_.clone(question), {
    validate: function () {
      return true;
    },
    filter: function (val) {
      return val;
    },
    when: function () {
      return true;
    },
    suffix: '',
    prefix: chalk.green('?')
  });

  // Check to make sure prompt requirements are there
  if (!this.opt.message) {
    this.throwParamError('message');
  }
  if (!this.opt.name) {
    this.throwParamError('name');
  }

  // Normalize choices
  if (Array.isArray(this.opt.choices)) {
    this.opt.choices = new Choices(this.opt.choices, answers);
  }

  this.rl = rl;
  this.screen = new ScreenManager(this.rl);
};

/**
 * Start the Inquiry session and manage output value filtering
 * @return {Promise}
 */

Prompt.prototype.run = function () {
  return new Promise(function (resolve) {
    this._run(function (value) {
      resolve(value);
    });
  }.bind(this));
};

// default noop (this one should be overwritten in prompts)
Prompt.prototype._run = function (cb) {
  cb();
};

/**
 * Throw an error telling a required parameter is missing
 * @param  {String} name Name of the missing param
 * @return {Throw Error}
 */

Prompt.prototype.throwParamError = function (name) {
  throw new Error('You must provide a `' + name + '` parameter');
};

/**
 * Called when the UI closes. Override to do any specific cleanup necessary
 */
Prompt.prototype.close = function () {
  this.screen.releaseCursor();
};

/**
 * Run the provided validation method each time a submit event occur.
 * @param  {Rx.Observable} submit - submit event flow
 * @return {Object}        Object containing two observables: `success` and `error`
 */
Prompt.prototype.handleSubmitEvents = function (submit) {
  var self = this;
  var validate = runAsync(this.opt.validate);
  var filter = runAsync(this.opt.filter);
  var validation = submit.flatMap(function (value) {
    return filter(value, self.answers).then(function (filteredValue) {
      return validate(filteredValue, self.answers).then(function (isValid) {
        return {isValid: isValid, value: filteredValue};
      }, function (err) {
        return {isValid: err};
      });
    }, function (err) {
      return {isValid: err};
    });
  }).share();

  var success = validation
    .filter(function (state) {
      return state.isValid === true;
    })
    .take(1);

  var error = validation
    .filter(function (state) {
      return state.isValid !== true;
    })
    .takeUntil(success);

  return {
    success: success,
    error: error
  };
};

/**
 * Generate the prompt question string
 * @return {String} prompt question string
 */

Prompt.prototype.getQuestion = function () {
  var message = this.opt.prefix + ' ' + chalk.bold(this.opt.message) + this.opt.suffix + chalk.reset(' ');

  // Append the default if available, and if question isn't answered
  if (this.opt.default != null && this.status !== 'answered') {
    message += chalk.dim('(' + this.opt.default + ') ');
  }

  return message;
};