1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | const chalk = require('chalk');
|
7 | const { map, takeUntil } = require('rxjs/operators');
|
8 | const Base = require('./base');
|
9 | const observe = require('../utils/events');
|
10 |
|
11 | class InputPrompt extends Base {
|
12 | |
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | _run(cb) {
|
19 | this.done = cb;
|
20 |
|
21 |
|
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 |
|
34 | this.render();
|
35 |
|
36 | return this;
|
37 | }
|
38 |
|
39 | |
40 |
|
41 |
|
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 |
|
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 |
|
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 |
|
101 |
|
102 |
|
103 | onKeypress() {
|
104 | this.state = 'touched';
|
105 |
|
106 | this.render();
|
107 | }
|
108 | }
|
109 |
|
110 | module.exports = InputPrompt;
|