feat: fully managed, encrypted staking keys
[crowdnode.js/.git] / bin / _prompt.js
1 "use strict";
2
3 let Prompt = module.exports;
4
5 /**
6  * @param {String} query
7  * @param {Object} [options]
8  * @param {Array<String>} [options.choices]
9  * @param {Boolean} [options.mask]
10  */
11 Prompt.prompt = async function (query, options) {
12   let Readline = require("readline");
13
14   let completer;
15   if (options?.choices) {
16     /**
17      * @param {String} line
18      */
19     completer = function (line) {
20       let completions = options.choices || [];
21       let hits = completions.filter(function (c) {
22         return c.startsWith(line);
23       });
24       if (!hits.length) {
25         hits = completions;
26       }
27       return [hits, line];
28     };
29   }
30
31   let rl = Readline.createInterface({
32     input: process.stdin,
33     output: process.stdout,
34     completer,
35   });
36
37   if (options?.mask) {
38     //@ts-ignore
39     rl.input.on("keypress", function (_char, _modifiers) {
40       // _char = "e"
41       // _modifiers = { sequence: 'e', name: 'e', ctrl: false, meta: false, shift: false }
42       let len = rl.line.length;
43       // place cursor at the beginning of the prompt
44       //@ts-ignore
45       Readline.moveCursor(rl.output, -len, 0);
46       // clear right of the cursor / prompt
47       //@ts-ignore
48       Readline.clearLine(rl.output, 1);
49       // mask with "*"
50       //@ts-ignore
51       rl.output.write("*".repeat(len));
52     });
53   }
54
55   let answer = await new Promise(function (resolve) {
56     return rl.question(query ?? "", resolve);
57   });
58
59   // TODO what if we need control over closing?
60   // ex: Promise.race([getPrompt, getFsEvent, getSocketEvent]);
61   rl.close();
62   return answer;
63 };