1 | const repl = require('repl');
|
2 | const SpinnerView = require('@src/view/spinner-view');
|
3 | const Messenger = require('@src/view/messenger');
|
4 | const stringUtils = require('@src/utils/string-utils');
|
5 |
|
6 | module.exports = class CliReplView {
|
7 | |
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | constructor(configuration) {
|
14 | if (!configuration) {
|
15 | throw 'Cannot have an undefined configuration.';
|
16 | }
|
17 | const { prompt, evalFunc, header, footer, prettifyHeaderFooter, inputStream } = configuration;
|
18 | this.prompt = prompt || '> ';
|
19 | this.eval = evalFunc;
|
20 | this.header = header;
|
21 | this.footer = footer;
|
22 | this.prettifyHeaderFooter = prettifyHeaderFooter || (arg => arg);
|
23 | this.inputStream = inputStream || process.stdin;
|
24 | this.progressSpinner = new SpinnerView();
|
25 | if (!stringUtils.isNonEmptyString(this.prompt)) {
|
26 | throw 'Prompt must be a non-empty string.';
|
27 | }
|
28 | this.printHeaderFooter(this.header);
|
29 |
|
30 | const replConfig = {
|
31 | prompt: this.prompt,
|
32 | eval: (cmd, context, filename, callback) => {
|
33 | this.eval(cmd, callback);
|
34 | },
|
35 | ignoreUndefined: true,
|
36 | input: this.inputStream,
|
37 | output: process.stdout
|
38 | };
|
39 | this.replServer = repl.start(replConfig);
|
40 | this.replServer.removeAllListeners('SIGINT');
|
41 | this.clearSpecialCommands();
|
42 | this.registerQuitCommand(() => {});
|
43 | }
|
44 |
|
45 | |
46 |
|
47 |
|
48 |
|
49 | printHeaderFooter(data) {
|
50 | if (stringUtils.isNonEmptyString(data)) {
|
51 | Messenger.getInstance().info(this.prettifyHeaderFooter(data));
|
52 | }
|
53 | }
|
54 |
|
55 | |
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | registerSpecialCommand(name, helpMessage, func, displayPrompt) {
|
64 | const shouldDisplayPrompt = displayPrompt === undefined ? true : displayPrompt;
|
65 | this.replServer.defineCommand(name, {
|
66 | help: helpMessage || this.replServer.commands[name].help,
|
67 | action: (args) => {
|
68 | func(args);
|
69 | if (shouldDisplayPrompt) this.replServer.displayPrompt();
|
70 | }
|
71 | });
|
72 | }
|
73 |
|
74 | |
75 |
|
76 |
|
77 |
|
78 | registerQuitCommand(func) {
|
79 | this.replServer.removeAllListeners('close');
|
80 | this.registerSpecialCommand(
|
81 | 'quit',
|
82 | 'Quit repl session.',
|
83 | () => {
|
84 | this.close();
|
85 | },
|
86 | false
|
87 | );
|
88 | this.replServer.on('close', () => {
|
89 | func();
|
90 | this.progressSpinner.terminate();
|
91 | this.printHeaderFooter(this.footer);
|
92 | });
|
93 | }
|
94 |
|
95 | |
96 |
|
97 |
|
98 |
|
99 | clearSpecialCommands() {
|
100 | this.replServer.commands = { help: this.replServer.commands.help };
|
101 | this.replServer.removeAllListeners('close');
|
102 | }
|
103 |
|
104 | |
105 |
|
106 |
|
107 | close() {
|
108 | this.replServer.close();
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 | |
114 |
|
115 |
|
116 |
|
117 | startProgressSpinner(text) {
|
118 | this.progressSpinner.start(text);
|
119 | }
|
120 |
|
121 | |
122 |
|
123 |
|
124 |
|
125 | updateProgressSpinner(text) {
|
126 | this.progressSpinner.update(text);
|
127 | }
|
128 |
|
129 | |
130 |
|
131 |
|
132 | terminateProgressSpinner() {
|
133 | this.progressSpinner.terminate();
|
134 | }
|
135 | };
|