UNPKG

2.21 kBJavaScriptView Raw
1'use strict';
2/**
3 * `input` type prompt
4 */
5
6const chalk = require('chalk');
7const { map, takeUntil } = require('rxjs/operators');
8const Base = require('./base');
9const observe = require('../utils/events');
10
11class InputPrompt extends Base {
12 /**
13 * Start the Inquiry session
14 * @param {Function} cb Callback when prompt is done
15 * @return {this}
16 */
17
18 _run(cb) {
19 this.done = cb;
20
21 // Once user confirm (enter key)
22 const events = observe(this.rl);
23 const submit = events.line.pipe(map(this.filterInput.bind(this)));
24
25 const validation = this.handleSubmitEvents(submit);
26 validation.success.forEach(this.onEnd.bind(this));
27 validation.error.forEach(this.onError.bind(this));
28
29 events.keypress
30 .pipe(takeUntil(validation.success))
31 .forEach(this.onKeypress.bind(this));
32
33 // Init
34 this.render();
35
36 return this;
37 }
38
39 /**
40 * Render the prompt to screen
41 * @return {InputPrompt} self
42 */
43
44 render(error) {
45 let bottomContent = '';
46 let appendContent = '';
47 let message = this.getQuestion();
48 const { transformer } = this.opt;
49 const isFinal = this.status === 'answered';
50
51 if (isFinal) {
52 appendContent = this.answer;
53 } else {
54 appendContent = this.rl.line;
55 }
56
57 if (transformer) {
58 message += transformer(appendContent, this.answers, { isFinal });
59 } else {
60 message += isFinal ? chalk.cyan(appendContent) : appendContent;
61 }
62
63 if (error) {
64 bottomContent = chalk.red('>> ') + error;
65 }
66
67 this.screen.render(message, bottomContent);
68 }
69
70 /**
71 * When user press `enter` key
72 */
73
74 filterInput(input) {
75 if (!input) {
76 return this.opt.default == null ? '' : this.opt.default;
77 }
78
79 return input;
80 }
81
82 onEnd(state) {
83 this.answer = state.value;
84 this.status = 'answered';
85
86 // Re-render prompt
87 this.render();
88
89 this.screen.done();
90 this.done(state.value);
91 }
92
93 onError({ value = '', isValid }) {
94 this.rl.line += value;
95 this.rl.cursor += value.length;
96 this.render(isValid);
97 }
98
99 /**
100 * When user press a key
101 */
102
103 onKeypress() {
104 this.state = 'touched';
105
106 this.render();
107 }
108}
109
110module.exports = InputPrompt;