1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
class JSConsoleModule {
constructor() {
this.commands = {};
this.commandsMeta = { 'js': { argType: 'file' }, 'js-run': { argType: 'file' } };
this.terminal = null;
}
getHelpInfo() {
return {
'js': 'js <expression> — Evaluate JavaScript in page context',
'js-run': 'js-run <path> — Load and execute a JS file from VFS'
};
}
registerCommands() {
this.commands['js'] = (args) => this.evalJS(args);
this.commands['js-run'] = (args) => this.evalJSFile(args);
}
evalJS(args) {
if (!args[0]) return this.terminal.print('Usage: js <expression>', 'warning');
const expr = args.join(' ');
try {
const result = eval(expr);
const output = result === undefined ? 'undefined' :
typeof result === 'string' ? result :
result === null ? 'null' :
typeof result === 'object' ? JSON.stringify(result, null, 2) :
String(result);
this.terminal.print(output, 'success');
} catch (e) {
this.terminal.print(`Error: ${e.message}`, 'error');
}
}
evalJSFile(args) {
if (!args[0]) return this.terminal.print('Usage: js-run <path>', 'warning');
const path = args.join(' ');
try {
const content = this.terminal.fs.readFile(path);
if (content === null || content === undefined || content === false) {
return this.terminal.print(`js-run: ${path}: No such file`, 'error');
}
// Wrap in an async IIFE so multi-line scripts with await work
const wrapped = `(async () => {\n${content}\n})()`;
const result = eval(wrapped);
// If it returns a promise, wait for it via .then
if (result && typeof result.then === 'function') {
result.then(val => {
const output = val === undefined ? '✓ Script executed' :
typeof val === 'string' ? val :
val === null ? 'null' :
typeof val === 'object' ? JSON.stringify(val, null, 2) :
String(val);
this.terminal.print(output, 'success');
}).catch(e => {
this.terminal.print(`Error: ${e.message}`, 'error');
});
return;
}
const output = result === undefined ? '✓ Script executed' :
typeof result === 'string' ? result :
result === null ? 'null' :
typeof result === 'object' ? JSON.stringify(result, null, 2) :
String(result);
this.terminal.print(output, 'success');
} catch (e) {
this.terminal.print(`Error: ${e.message}`, 'error');
}
}
seed() {}
init() {}
}
if (typeof window !== 'undefined') window.JSConsoleModule = JSConsoleModule;
|