aimyapi 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +195 -195
- package/dist/index.cjs +36 -4
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +36 -4
- package/dist/index.mjs +36 -4
- package/example/example1.ts +30 -30
- package/example/example2.ts +58 -58
- package/example/example3.ts +69 -69
- package/example/ordering_api.md +94 -94
- package/example/ordering_api.ts +191 -191
- package/example/ordering_api_impl.ts +207 -207
- package/example/sales_api.md +4 -4
- package/example/sales_api.ts +29 -29
- package/example/sales_api_impl.ts +60 -60
- package/package.json +1 -1
- package/prompts/create-task-prompt.md +37 -30
- package/src/index.ts +495 -456
- package/src/sandbox-wrappers.ts +249 -249
- package/src/sandbox.ts +277 -277
- package/src/utils.ts +2 -2
- package/tsconfig.json +12 -12
package/src/sandbox.ts
CHANGED
|
@@ -1,277 +1,277 @@
|
|
|
1
|
-
import "quickjs-emscripten";
|
|
2
|
-
|
|
3
|
-
import { QuickJSWASMModule } from "quickjs-emscripten";
|
|
4
|
-
import * as ts from "typescript";
|
|
5
|
-
import {
|
|
6
|
-
injectTimingFunctions,
|
|
7
|
-
wrap,
|
|
8
|
-
wrapObject,
|
|
9
|
-
wrapObjectWhitelist,
|
|
10
|
-
} from "./sandbox-wrappers";
|
|
11
|
-
|
|
12
|
-
// Should we use "noEmitOnError": true ?
|
|
13
|
-
function tsCompile(
|
|
14
|
-
source: string,
|
|
15
|
-
options?: ts.TranspileOptions
|
|
16
|
-
): string {
|
|
17
|
-
// Default options -- you could also perform a merge, or use the project tsconfig.json
|
|
18
|
-
if (!options) {
|
|
19
|
-
options = {
|
|
20
|
-
compilerOptions: {
|
|
21
|
-
target: ts.ScriptTarget.ES2022,
|
|
22
|
-
module: ts.ModuleKind.None,
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
return ts.transpileModule(source, options).outputText;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface GlobalOption {
|
|
30
|
-
value: any;
|
|
31
|
-
whitelist?: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface Globals {
|
|
35
|
-
[key: string]: GlobalOption;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type SandboxLog = {
|
|
39
|
-
type: "log" | "error";
|
|
40
|
-
args: any[];
|
|
41
|
-
source: string
|
|
42
|
-
};
|
|
43
|
-
export type CodeRunResult = {
|
|
44
|
-
success: boolean;
|
|
45
|
-
logs: SandboxLog[];
|
|
46
|
-
}
|
|
47
|
-
type LogSource = "sandbox" | "compiler" | "runner";
|
|
48
|
-
class Logger {
|
|
49
|
-
logs: SandboxLog[] = [];
|
|
50
|
-
debug: boolean = false;
|
|
51
|
-
|
|
52
|
-
constructor(debug: boolean = false) {
|
|
53
|
-
this.debug = debug;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
log(args: any, source: LogSource) {
|
|
57
|
-
if(Array.isArray(args)) {
|
|
58
|
-
this.logs.push({ type: "log", args, source });
|
|
59
|
-
} else {
|
|
60
|
-
this.logs.push({ type: "log", args: [args], source });
|
|
61
|
-
}
|
|
62
|
-
if (this.debug) {
|
|
63
|
-
console.log(`[${source}]:`, ...args);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
error(args: any, source: LogSource) {
|
|
68
|
-
if(Array.isArray(args)) {
|
|
69
|
-
this.logs.push({ type: "error", args, source });
|
|
70
|
-
} else {
|
|
71
|
-
this.logs.push({ type: "error", args: [args], source });
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
console.error(`[${source}]:`, ...args);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
clear() {
|
|
78
|
-
this.logs = [];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// function whitelist can be produced using something like:
|
|
85
|
-
// const assistantFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(apiObject))
|
|
86
|
-
// .filter((f) => f !== "constructor" && !f.startsWith("_"));
|
|
87
|
-
|
|
88
|
-
// Is there some way we can treat the API and globals the same?
|
|
89
|
-
// We could just provide an object for all globals (including the API) and also have the whitelist as a parameter..
|
|
90
|
-
export default async function createSandbox(QuickJS: QuickJSWASMModule, requireLookup:any = {}, globals: Globals = {}, debug:boolean = false) {
|
|
91
|
-
const vm = QuickJS.newContext();
|
|
92
|
-
|
|
93
|
-
let errorState = false;
|
|
94
|
-
let lastError = "";
|
|
95
|
-
|
|
96
|
-
let asyncProcessesRunning = 0;
|
|
97
|
-
|
|
98
|
-
let beginAsyncProcess = () => {
|
|
99
|
-
asyncProcessesRunning++;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
let endAsyncProcess = () => {
|
|
103
|
-
if (asyncProcessesRunning > 0) {
|
|
104
|
-
asyncProcessesRunning--;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
let isAsyncProcessRunning = () => {
|
|
109
|
-
//console.log("asyncProcessesRunning:", asyncProcessesRunning);
|
|
110
|
-
return asyncProcessesRunning > 0;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const logger = new Logger(debug);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// const assistantHandle = wrapObjectWhitelist(vm, apiObject, functionWhitelist, beginAsyncProcess, endAsyncProcess);
|
|
118
|
-
// vm.setProp(vm.global, apiGlobalName, assistantHandle)
|
|
119
|
-
|
|
120
|
-
// assistantHandle.dispose();
|
|
121
|
-
|
|
122
|
-
const logHandle = vm.newFunction("log", (...args:any) => {
|
|
123
|
-
const nativeArgs = args.map(vm.dump);
|
|
124
|
-
logger.log(nativeArgs, "sandbox");
|
|
125
|
-
});
|
|
126
|
-
const consoleHandle = vm.newObject();
|
|
127
|
-
const exportsHandle = vm.newObject();
|
|
128
|
-
|
|
129
|
-
const errorHandle = vm.newFunction("error", (...args:any) => {
|
|
130
|
-
try {
|
|
131
|
-
const nativeArgs = args.map(vm.dump);
|
|
132
|
-
|
|
133
|
-
logger.error(nativeArgs, "sandbox");
|
|
134
|
-
lastError = JSON.stringify(nativeArgs);
|
|
135
|
-
errorState = true;
|
|
136
|
-
} catch (e) {
|
|
137
|
-
logger.error(["? Error in error:", e], "sandbox");
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
const globalNames = Object.getOwnPropertyNames(globals);
|
|
142
|
-
for (let i = 0; i < globalNames.length; i++) {
|
|
143
|
-
const globalOption: GlobalOption = globals[globalNames[i]];
|
|
144
|
-
const globalObj = globalOption.whitelist
|
|
145
|
-
? wrapObjectWhitelist(
|
|
146
|
-
vm,
|
|
147
|
-
globalOption.value,
|
|
148
|
-
globalOption.whitelist,
|
|
149
|
-
beginAsyncProcess,
|
|
150
|
-
endAsyncProcess
|
|
151
|
-
)
|
|
152
|
-
: wrap(vm, globalOption.value, globalOption, beginAsyncProcess, endAsyncProcess);
|
|
153
|
-
|
|
154
|
-
vm.setProp(vm.global, globalNames[i], globalObj);
|
|
155
|
-
globalObj.dispose();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
injectTimingFunctions(vm, beginAsyncProcess, endAsyncProcess);
|
|
159
|
-
|
|
160
|
-
const requireHandle = vm.newFunction("require", (...args) => {
|
|
161
|
-
const nativeArgs = args.map(vm.dump);
|
|
162
|
-
if(requireLookup[nativeArgs[0] as string]) {
|
|
163
|
-
const returnObj = wrapObject(vm, requireLookup[nativeArgs[0] as string], beginAsyncProcess, endAsyncProcess);
|
|
164
|
-
return returnObj;
|
|
165
|
-
} else {
|
|
166
|
-
return vm.undefined;
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
vm.setProp(consoleHandle, "log", logHandle);
|
|
171
|
-
vm.setProp(consoleHandle, "error", errorHandle);
|
|
172
|
-
vm.setProp(vm.global, "require", requireHandle);
|
|
173
|
-
vm.setProp(vm.global, "console", consoleHandle);
|
|
174
|
-
vm.setProp(vm.global, "exports", exportsHandle);
|
|
175
|
-
|
|
176
|
-
consoleHandle.dispose();
|
|
177
|
-
logHandle.dispose();
|
|
178
|
-
exportsHandle.dispose();
|
|
179
|
-
errorHandle.dispose();
|
|
180
|
-
requireHandle.dispose();
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
vm,
|
|
184
|
-
getLastError: () => {
|
|
185
|
-
return lastError;
|
|
186
|
-
},
|
|
187
|
-
isAsyncProcessRunning,
|
|
188
|
-
// make sure code passes the typescript compilation
|
|
189
|
-
checkCode: (code: string) => {
|
|
190
|
-
logger.clear();
|
|
191
|
-
try {
|
|
192
|
-
const compiled = tsCompile(code);
|
|
193
|
-
if (!compiled || compiled.length === 0) {
|
|
194
|
-
logger.error(["Could not compile:", code], "compiler");
|
|
195
|
-
return {
|
|
196
|
-
success: false,
|
|
197
|
-
logs: logger.logs,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
} catch (e) {
|
|
201
|
-
logger.error(["Error testing code:", e], "compiler");
|
|
202
|
-
return {
|
|
203
|
-
success: false,
|
|
204
|
-
logs: logger.logs,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
success: true,
|
|
210
|
-
logs: logger.logs,
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
runCode: (code: string): CodeRunResult => {
|
|
214
|
-
try {
|
|
215
|
-
logger.clear();
|
|
216
|
-
const compiled = tsCompile(code);
|
|
217
|
-
|
|
218
|
-
if (!compiled || compiled.length === 0) {
|
|
219
|
-
logger.error(["Could not compile:", code], "compiler");
|
|
220
|
-
return {
|
|
221
|
-
success: false,
|
|
222
|
-
logs: logger.logs,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// View compiled typescript code for debugging
|
|
227
|
-
// if(debug)
|
|
228
|
-
// console.log(compiled);
|
|
229
|
-
|
|
230
|
-
errorState = false;
|
|
231
|
-
const result = vm.evalCode(compiled);
|
|
232
|
-
|
|
233
|
-
if (result.error) {
|
|
234
|
-
// log out the compiled program with line numbers
|
|
235
|
-
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
logger.error(["Execution failed:", lines.join("\n"), vm.dump(result.error)], "runner");
|
|
239
|
-
|
|
240
|
-
result.error.dispose();
|
|
241
|
-
return {
|
|
242
|
-
success: false,
|
|
243
|
-
logs: logger.logs,
|
|
244
|
-
};
|
|
245
|
-
} else if("value" in result){
|
|
246
|
-
//console.log("Task Result:", vm.dump(result.value));
|
|
247
|
-
|
|
248
|
-
result.value.dispose();
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (errorState) {
|
|
252
|
-
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
253
|
-
logger.error(["An error was reported during execution. Compiled code with line numbers:\n", lines.join("\n")], "runner");
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return {
|
|
257
|
-
success: !errorState,
|
|
258
|
-
logs: logger.logs,
|
|
259
|
-
};
|
|
260
|
-
} else {
|
|
261
|
-
logger.error(["Unknown execution result:", result], "runner");
|
|
262
|
-
return {
|
|
263
|
-
success: false,
|
|
264
|
-
logs: logger.logs,
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
} catch (e) {
|
|
268
|
-
logger.error(["Error running code:", e], "runner");
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return {
|
|
272
|
-
success: false,
|
|
273
|
-
logs: logger.logs,
|
|
274
|
-
};
|
|
275
|
-
},
|
|
276
|
-
};
|
|
277
|
-
}
|
|
1
|
+
import "quickjs-emscripten";
|
|
2
|
+
|
|
3
|
+
import { QuickJSWASMModule } from "quickjs-emscripten";
|
|
4
|
+
import * as ts from "typescript";
|
|
5
|
+
import {
|
|
6
|
+
injectTimingFunctions,
|
|
7
|
+
wrap,
|
|
8
|
+
wrapObject,
|
|
9
|
+
wrapObjectWhitelist,
|
|
10
|
+
} from "./sandbox-wrappers";
|
|
11
|
+
|
|
12
|
+
// Should we use "noEmitOnError": true ?
|
|
13
|
+
function tsCompile(
|
|
14
|
+
source: string,
|
|
15
|
+
options?: ts.TranspileOptions
|
|
16
|
+
): string {
|
|
17
|
+
// Default options -- you could also perform a merge, or use the project tsconfig.json
|
|
18
|
+
if (!options) {
|
|
19
|
+
options = {
|
|
20
|
+
compilerOptions: {
|
|
21
|
+
target: ts.ScriptTarget.ES2022,
|
|
22
|
+
module: ts.ModuleKind.None,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return ts.transpileModule(source, options).outputText;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface GlobalOption {
|
|
30
|
+
value: any;
|
|
31
|
+
whitelist?: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface Globals {
|
|
35
|
+
[key: string]: GlobalOption;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type SandboxLog = {
|
|
39
|
+
type: "log" | "error";
|
|
40
|
+
args: any[];
|
|
41
|
+
source: string
|
|
42
|
+
};
|
|
43
|
+
export type CodeRunResult = {
|
|
44
|
+
success: boolean;
|
|
45
|
+
logs: SandboxLog[];
|
|
46
|
+
}
|
|
47
|
+
type LogSource = "sandbox" | "compiler" | "runner";
|
|
48
|
+
class Logger {
|
|
49
|
+
logs: SandboxLog[] = [];
|
|
50
|
+
debug: boolean = false;
|
|
51
|
+
|
|
52
|
+
constructor(debug: boolean = false) {
|
|
53
|
+
this.debug = debug;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
log(args: any, source: LogSource) {
|
|
57
|
+
if(Array.isArray(args)) {
|
|
58
|
+
this.logs.push({ type: "log", args, source });
|
|
59
|
+
} else {
|
|
60
|
+
this.logs.push({ type: "log", args: [args], source });
|
|
61
|
+
}
|
|
62
|
+
if (this.debug) {
|
|
63
|
+
console.log(`[${source}]:`, ...args);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
error(args: any, source: LogSource) {
|
|
68
|
+
if(Array.isArray(args)) {
|
|
69
|
+
this.logs.push({ type: "error", args, source });
|
|
70
|
+
} else {
|
|
71
|
+
this.logs.push({ type: "error", args: [args], source });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.error(`[${source}]:`, ...args);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
clear() {
|
|
78
|
+
this.logs = [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// function whitelist can be produced using something like:
|
|
85
|
+
// const assistantFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf(apiObject))
|
|
86
|
+
// .filter((f) => f !== "constructor" && !f.startsWith("_"));
|
|
87
|
+
|
|
88
|
+
// Is there some way we can treat the API and globals the same?
|
|
89
|
+
// We could just provide an object for all globals (including the API) and also have the whitelist as a parameter..
|
|
90
|
+
export default async function createSandbox(QuickJS: QuickJSWASMModule, requireLookup:any = {}, globals: Globals = {}, debug:boolean = false) {
|
|
91
|
+
const vm = QuickJS.newContext();
|
|
92
|
+
|
|
93
|
+
let errorState = false;
|
|
94
|
+
let lastError = "";
|
|
95
|
+
|
|
96
|
+
let asyncProcessesRunning = 0;
|
|
97
|
+
|
|
98
|
+
let beginAsyncProcess = () => {
|
|
99
|
+
asyncProcessesRunning++;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
let endAsyncProcess = () => {
|
|
103
|
+
if (asyncProcessesRunning > 0) {
|
|
104
|
+
asyncProcessesRunning--;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
let isAsyncProcessRunning = () => {
|
|
109
|
+
//console.log("asyncProcessesRunning:", asyncProcessesRunning);
|
|
110
|
+
return asyncProcessesRunning > 0;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const logger = new Logger(debug);
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
// const assistantHandle = wrapObjectWhitelist(vm, apiObject, functionWhitelist, beginAsyncProcess, endAsyncProcess);
|
|
118
|
+
// vm.setProp(vm.global, apiGlobalName, assistantHandle)
|
|
119
|
+
|
|
120
|
+
// assistantHandle.dispose();
|
|
121
|
+
|
|
122
|
+
const logHandle = vm.newFunction("log", (...args:any) => {
|
|
123
|
+
const nativeArgs = args.map(vm.dump);
|
|
124
|
+
logger.log(nativeArgs, "sandbox");
|
|
125
|
+
});
|
|
126
|
+
const consoleHandle = vm.newObject();
|
|
127
|
+
const exportsHandle = vm.newObject();
|
|
128
|
+
|
|
129
|
+
const errorHandle = vm.newFunction("error", (...args:any) => {
|
|
130
|
+
try {
|
|
131
|
+
const nativeArgs = args.map(vm.dump);
|
|
132
|
+
|
|
133
|
+
logger.error(nativeArgs, "sandbox");
|
|
134
|
+
lastError = JSON.stringify(nativeArgs);
|
|
135
|
+
errorState = true;
|
|
136
|
+
} catch (e) {
|
|
137
|
+
logger.error(["? Error in error:", e], "sandbox");
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const globalNames = Object.getOwnPropertyNames(globals);
|
|
142
|
+
for (let i = 0; i < globalNames.length; i++) {
|
|
143
|
+
const globalOption: GlobalOption = globals[globalNames[i]];
|
|
144
|
+
const globalObj = globalOption.whitelist
|
|
145
|
+
? wrapObjectWhitelist(
|
|
146
|
+
vm,
|
|
147
|
+
globalOption.value,
|
|
148
|
+
globalOption.whitelist,
|
|
149
|
+
beginAsyncProcess,
|
|
150
|
+
endAsyncProcess
|
|
151
|
+
)
|
|
152
|
+
: wrap(vm, globalOption.value, globalOption, beginAsyncProcess, endAsyncProcess);
|
|
153
|
+
|
|
154
|
+
vm.setProp(vm.global, globalNames[i], globalObj);
|
|
155
|
+
globalObj.dispose();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
injectTimingFunctions(vm, beginAsyncProcess, endAsyncProcess);
|
|
159
|
+
|
|
160
|
+
const requireHandle = vm.newFunction("require", (...args) => {
|
|
161
|
+
const nativeArgs = args.map(vm.dump);
|
|
162
|
+
if(requireLookup[nativeArgs[0] as string]) {
|
|
163
|
+
const returnObj = wrapObject(vm, requireLookup[nativeArgs[0] as string], beginAsyncProcess, endAsyncProcess);
|
|
164
|
+
return returnObj;
|
|
165
|
+
} else {
|
|
166
|
+
return vm.undefined;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
vm.setProp(consoleHandle, "log", logHandle);
|
|
171
|
+
vm.setProp(consoleHandle, "error", errorHandle);
|
|
172
|
+
vm.setProp(vm.global, "require", requireHandle);
|
|
173
|
+
vm.setProp(vm.global, "console", consoleHandle);
|
|
174
|
+
vm.setProp(vm.global, "exports", exportsHandle);
|
|
175
|
+
|
|
176
|
+
consoleHandle.dispose();
|
|
177
|
+
logHandle.dispose();
|
|
178
|
+
exportsHandle.dispose();
|
|
179
|
+
errorHandle.dispose();
|
|
180
|
+
requireHandle.dispose();
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
vm,
|
|
184
|
+
getLastError: () => {
|
|
185
|
+
return lastError;
|
|
186
|
+
},
|
|
187
|
+
isAsyncProcessRunning,
|
|
188
|
+
// make sure code passes the typescript compilation
|
|
189
|
+
checkCode: (code: string) => {
|
|
190
|
+
logger.clear();
|
|
191
|
+
try {
|
|
192
|
+
const compiled = tsCompile(code);
|
|
193
|
+
if (!compiled || compiled.length === 0) {
|
|
194
|
+
logger.error(["Could not compile:", code], "compiler");
|
|
195
|
+
return {
|
|
196
|
+
success: false,
|
|
197
|
+
logs: logger.logs,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
} catch (e) {
|
|
201
|
+
logger.error(["Error testing code:", e], "compiler");
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
logs: logger.logs,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
success: true,
|
|
210
|
+
logs: logger.logs,
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
runCode: (code: string): CodeRunResult => {
|
|
214
|
+
try {
|
|
215
|
+
logger.clear();
|
|
216
|
+
const compiled = tsCompile(code);
|
|
217
|
+
|
|
218
|
+
if (!compiled || compiled.length === 0) {
|
|
219
|
+
logger.error(["Could not compile:", code], "compiler");
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
logs: logger.logs,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// View compiled typescript code for debugging
|
|
227
|
+
// if(debug)
|
|
228
|
+
// console.log(compiled);
|
|
229
|
+
|
|
230
|
+
errorState = false;
|
|
231
|
+
const result = vm.evalCode(compiled);
|
|
232
|
+
|
|
233
|
+
if (result.error) {
|
|
234
|
+
// log out the compiled program with line numbers
|
|
235
|
+
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
logger.error(["Execution failed:", lines.join("\n"), vm.dump(result.error)], "runner");
|
|
239
|
+
|
|
240
|
+
result.error.dispose();
|
|
241
|
+
return {
|
|
242
|
+
success: false,
|
|
243
|
+
logs: logger.logs,
|
|
244
|
+
};
|
|
245
|
+
} else if("value" in result){
|
|
246
|
+
//console.log("Task Result:", vm.dump(result.value));
|
|
247
|
+
|
|
248
|
+
result.value.dispose();
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if (errorState) {
|
|
252
|
+
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
253
|
+
logger.error(["An error was reported during execution. Compiled code with line numbers:\n", lines.join("\n")], "runner");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
success: !errorState,
|
|
258
|
+
logs: logger.logs,
|
|
259
|
+
};
|
|
260
|
+
} else {
|
|
261
|
+
logger.error(["Unknown execution result:", result], "runner");
|
|
262
|
+
return {
|
|
263
|
+
success: false,
|
|
264
|
+
logs: logger.logs,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
} catch (e) {
|
|
268
|
+
logger.error(["Error running code:", e], "runner");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
success: false,
|
|
273
|
+
logs: logger.logs,
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function delay(time):Promise<void> {
|
|
2
|
-
return new Promise<void>(resolve => setTimeout(resolve, time));
|
|
1
|
+
export function delay(time):Promise<void> {
|
|
2
|
+
return new Promise<void>(resolve => setTimeout(resolve, time));
|
|
3
3
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"rootDir": "./src",
|
|
4
|
-
"target": "ES2021" /* Node 16+ per https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping */,
|
|
5
|
-
"module": "nodenext" /* Some imports are really imports: https://www.typescriptlang.org/docs/handbook/esm-node.html */,
|
|
6
|
-
"moduleResolution": "nodenext" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
|
7
|
-
"lib": ["ES2021", "dom"] /* Specify library files to be included in the compilation. */,
|
|
8
|
-
"outDir": "./dist" /* Redirect output structure to the directory. */,
|
|
9
|
-
"declaration": true
|
|
10
|
-
},
|
|
11
|
-
"include": ["**/src/*.ts"],
|
|
12
|
-
"exclude": ["**/node_modules, **/dist"]
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": "./src",
|
|
4
|
+
"target": "ES2021" /* Node 16+ per https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping */,
|
|
5
|
+
"module": "nodenext" /* Some imports are really imports: https://www.typescriptlang.org/docs/handbook/esm-node.html */,
|
|
6
|
+
"moduleResolution": "nodenext" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
|
7
|
+
"lib": ["ES2021", "dom"] /* Specify library files to be included in the compilation. */,
|
|
8
|
+
"outDir": "./dist" /* Redirect output structure to the directory. */,
|
|
9
|
+
"declaration": true
|
|
10
|
+
},
|
|
11
|
+
"include": ["**/src/*.ts"],
|
|
12
|
+
"exclude": ["**/node_modules, **/dist"]
|
|
13
13
|
}
|