Skip to content

Commit 79cee66

Browse files
committed
Replace shell with nodejs repl
1 parent 7bd9496 commit 79cee66

File tree

1 file changed

+27
-44
lines changed

1 file changed

+27
-44
lines changed

src/cli/shell/shell.ts

+27-44
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
1+
import repl from 'node:repl';
2+
13
import { frodo } from '@rockcarver/frodo-lib';
2-
import fuzzy from 'fuzzy';
3-
import inquirer from 'inquirer';
4-
import inquirerPrompt from 'inquirer-autocomplete-prompt';
4+
import { Option } from 'commander';
5+
import vm from 'vm';
56

67
import * as s from '../../help/SampleData';
78
import { getTokens } from '../../ops/AuthenticateOps';
8-
import { printError, printMessage } from '../../utils/Console';
99
import { FrodoCommand } from '../FrodoCommand';
1010

11-
const exits = ['exit', 'quit', 'q'];
12-
const functions = frodo.utils.json.getPaths(frodo, 'this.');
11+
async function startRepl(allowAwait = false) {
12+
const baseConfig = {
13+
prompt: '> ',
14+
ignoreUndefined: true,
15+
useGlobal: true,
16+
};
17+
18+
const configWithoutAwait = {
19+
...baseConfig,
20+
eval: async function myEval(cmd, context, _filename, callback) {
21+
callback(null, await vm.runInNewContext(cmd, context));
22+
},
23+
};
1324

14-
function searchFunctions(_answers, input = '') {
15-
return new Promise((resolve) => {
16-
setTimeout(
17-
() => {
18-
const results = fuzzy.filter(input, functions).map((el) => el.original);
19-
// results.splice(5, 0, new inquirer.Separator());
20-
// results.push(new inquirer.Separator());
21-
resolve(results);
22-
},
23-
Math.random() * 470 + 30
24-
);
25-
});
25+
const replServer = repl.start(allowAwait ? baseConfig : configWithoutAwait);
26+
27+
replServer.context.frodoLib = frodo;
2628
}
2729

2830
export default function setup() {
@@ -41,6 +43,12 @@ export default function setup() {
4143
` Launch a frodo shell using a connection profile (identified by a unique substring of the AM base URL):\n` +
4244
` $ frodo shell ${s.connId}\n`['brightCyan']
4345
)
46+
.addOption(
47+
new Option(
48+
'--allow-await',
49+
'Allows top-level awaits to be used in the shell.'
50+
)
51+
)
4452
.action(async (host, realm, user, password, options, command) => {
4553
command.handleDefaultArgsAndOpts(
4654
host,
@@ -51,32 +59,7 @@ export default function setup() {
5159
command
5260
);
5361
if (host) await getTokens();
54-
let exit = false;
55-
do {
56-
try {
57-
inquirer.registerPrompt('autocomplete', inquirerPrompt);
58-
const response = await inquirer.prompt([
59-
{
60-
type: 'autocomplete',
61-
prefix: '',
62-
name: 'command',
63-
message: '>',
64-
source: searchFunctions,
65-
suggestOnly: true,
66-
},
67-
]);
68-
exit = exits.includes(response.command);
69-
// evaluate code with context
70-
if (!exit) {
71-
const result = await function (str: string) {
72-
return eval(str);
73-
}.call(frodo, `${response.command}`);
74-
printMessage(result, 'data');
75-
}
76-
} catch (error) {
77-
printError(error);
78-
}
79-
} while (!exit);
62+
startRepl(options.allowAwait);
8063
});
8164
return program;
8265
}

0 commit comments

Comments
 (0)