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.
@@ -1,250 +1,250 @@
1
- import "quickjs-emscripten";
2
- import { QuickJSDeferredPromise } from "quickjs-emscripten";
3
-
4
-
5
- let promiseId = 0;
6
- let openPromises = {};
7
-
8
- export function wrapPromise(vm, promise: Promise<any>, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
9
- promiseId += 1;
10
-
11
- const vmPromise = vm.newPromise()
12
- vmPromise._promiseId = promiseId;
13
- beginAsyncProcess();
14
- promise.then((...args) => {
15
- //console.log("Promised resolved", args);
16
- endAsyncProcess();
17
- const wrappedArgs = args.map((arg) => wrap(vm, arg, undefined, beginAsyncProcess, endAsyncProcess));
18
- openPromises[vmPromise._promiseId] = null;
19
- vmPromise.resolve(...wrappedArgs);
20
- wrappedArgs.forEach((arg) => arg.dispose());
21
- }).catch((...args) => {
22
- //console.log("Promised rejected", args);
23
- const wrappedArgs = args.map((arg) => wrap(vm, arg, undefined, beginAsyncProcess, endAsyncProcess));
24
- vmPromise.reject(...wrappedArgs);
25
- wrappedArgs.forEach((arg) => arg.dispose());
26
- openPromises[vmPromise._promiseId] = null;
27
- });
28
- vmPromise.settled.then( () => {
29
- endAsyncProcess();
30
- vm.runtime.executePendingJobs();
31
- })
32
-
33
- openPromises[promiseId] = vmPromise;
34
-
35
- return vmPromise.handle
36
- }
37
-
38
- export function rejectOpenPromises(vm) {
39
- for (const [id, promise ] of Object.entries(openPromises)) {
40
- if (promise !== null) {
41
- (promise as QuickJSDeferredPromise).reject(vm.newError("Shutting down"));
42
- openPromises[id] = null;
43
- }
44
- }
45
-
46
- vm.runtime.executePendingJobs();
47
- }
48
-
49
- export function wrap(vm, value: any, context: object, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
50
- if (value === null) {
51
- return null;
52
- } else if (typeof value === 'object' && typeof value.then === 'function') {
53
- //console.log("Wrapped promise");
54
- return wrapPromise(vm, value, beginAsyncProcess, endAsyncProcess);
55
- } else if (typeof value === "function") {
56
- //console.log("Wrapped function")
57
- return wrapGenericFunction(vm, value, context, beginAsyncProcess, endAsyncProcess);
58
- } else if (Array.isArray(value)) {
59
- //console.log("Wrapped array")
60
- return wrapArray(vm, value, beginAsyncProcess, endAsyncProcess);
61
- } else if (value === null) {
62
- //console.log("Wrapped null")
63
- return vm.null;
64
- } else if (typeof value === "object") {
65
- //console.log("Wrapped object")
66
- return wrapObject(vm, value, beginAsyncProcess, endAsyncProcess);
67
- } else if (typeof value === "string") {
68
- //console.log("Wrapped string")
69
- return vm.newString(value)
70
- } else if (typeof value === "number") {
71
- //console.log("Wrapped number")
72
- return vm.newNumber(value);
73
- } else if (typeof value === "bigint") {
74
- //console.log("Wrapped bigint")
75
- return vm.newBigInt(value);
76
- } else if (typeof value === "boolean") {
77
- // since there is no newBoolean, we have to do this
78
- return vm.evalCode(value ? "true" : "false").value;
79
- } else if (typeof value === "undefined") {
80
- return vm.undefined
81
- } else {
82
- return null
83
- }
84
- }
85
-
86
- export function wrapObject(vm, obj: any, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
87
- const vmObject = vm.newObject();
88
-
89
- for (const [key, value] of Object.entries(obj)) {
90
- //console.log("wrapping", key, value)
91
- let wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
92
-
93
- if (wrappedValue !== null) {
94
- vm.setProp(vmObject, key, wrappedValue);
95
- if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
96
- wrappedValue.dispose();
97
- }
98
- }
99
- }
100
-
101
- return vmObject;
102
- }
103
-
104
- export function wrapObjectWhitelist(vm, obj: any, whitelist: string[], beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
105
- const vmObject = vm.newObject();
106
-
107
- whitelist.forEach((key) => {
108
- const value = obj[key];
109
- //console.log("wrapping", key, value)
110
- const wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
111
-
112
- if (wrappedValue !== null) {
113
- vm.setProp(vmObject, key, wrappedValue);
114
- if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
115
- wrappedValue.dispose();
116
- }
117
- }
118
- });
119
-
120
- return vmObject;
121
- }
122
-
123
- export function wrapArray(vm, arr: any[], beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
124
- const vmArray = vm.newArray();
125
-
126
- for (let i = 0; i < arr.length; i++) {
127
- let wrappedValue = wrap(vm, arr[i], arr, beginAsyncProcess, endAsyncProcess);
128
- vm.setProp(vmArray, i, wrappedValue);
129
- if (wrappedValue != vm.undefined && wrappedValue != vm.null) {
130
- wrappedValue.dispose();
131
- }
132
- }
133
-
134
- return vmArray;
135
- }
136
-
137
- export function wrapGenericFunction(vm, fn: Function, context: object = undefined, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
138
- const vmFn = vm.newFunction(fn.name, (...args) => {
139
- const unwrappedArgs: any[] = args.map(vm.dump)
140
- //console.log("Wrapped function called", fn.name, unwrappedArgs )
141
- try {
142
- const result = fn.call(context, ...unwrappedArgs);
143
- //console.log("result", result);
144
- const wrappedResult = wrap(vm, result, undefined, beginAsyncProcess, endAsyncProcess);
145
- return wrappedResult;
146
- } catch (e) {
147
- console.log("Error", e);
148
- }
149
-
150
- });
151
- return vmFn;
152
- }
153
-
154
- export function injectTimingFunctions(vm, cbAddedTimer, cbRemovedTimer, maxTimeout = 600000): void {
155
- // Should we impose a limit on how long things can run for?
156
- const timeoutFunctionHandles = {};
157
- const _setTimeout = vm.newFunction("setTimeout", (vmFnHandle, timeoutHandle) => {
158
- // Make a copy because otherwise vmFnHandle does not live long enough to call after the timeout
159
- const vmFnHandleCopy = vmFnHandle.dup()
160
- let timeout = vm.dump(timeoutHandle)
161
-
162
- // cap timeout at max timeout
163
- if(timeout > maxTimeout) {
164
- timeout = maxTimeout;
165
- }
166
-
167
- // console.log("Sandbox calling timeout for: " + timeout);
168
- cbAddedTimer();
169
- const timeoutID = setTimeout(() => {
170
- timeoutFunctionHandles[timeoutID.toString()] = null;
171
- // callFunction(vmFnHandleCopy) will call the vm function
172
- // in the context of the vm
173
- // we pass vm.undefined because we need to pass something for the "this" argument
174
- //console.log("Sandbox called timeout function")
175
- cbRemovedTimer();
176
- vm.callFunction(vmFnHandleCopy, vm.undefined)
177
- vmFnHandleCopy.dispose()
178
- vm.runtime.executePendingJobs();
179
- }, timeout)
180
- timeoutFunctionHandles[timeoutID.toString()] = vmFnHandleCopy;
181
-
182
- return vm.newNumber(timeoutID);
183
- });
184
-
185
- vm.setProp(vm.global, "setTimeout", _setTimeout);
186
- _setTimeout.dispose();
187
- const intervalFunctionHandles = {};
188
- const _setInterval = vm.newFunction("setInterval", (vmFnHandle, timeoutHandle) => {
189
- // Make a copy because otherwise vmFnHandle does not live long enough to call after the timeout
190
- const vmFnHandleCopy = vmFnHandle.dup()
191
- let timeout = vm.dump(timeoutHandle)
192
-
193
- // cap timeout at max timeout
194
- if(timeout > maxTimeout) {
195
- timeout = maxTimeout;
196
- }
197
-
198
- //console.log("Sandbox calling interval for: " + timeout);
199
- const maxRepetitions = 99;
200
- let repetitions = 0;
201
- cbAddedTimer();
202
- const intervalId = setInterval(() => {
203
- repetitions += 1;
204
- intervalFunctionHandles[intervalId.toString()] = null
205
-
206
-
207
- // callFunction(vmFnHandleCopy) will call the vm function
208
- // in the context of the vm
209
- // we pass vm.undefined because we need to pass something for the "this" argument
210
- vm.callFunction(vmFnHandleCopy, vm.undefined)
211
- vm.runtime.executePendingJobs();
212
-
213
- if (repetitions > maxRepetitions) {
214
- console.log("Sandbox interval exceeded max repetitions");
215
- clearInterval(intervalId);
216
- cbRemovedTimer();
217
- return;
218
- }
219
- }, timeout);
220
- intervalFunctionHandles[intervalId.toString()] = vmFnHandleCopy;
221
-
222
- return vm.newNumber(intervalId);
223
- });
224
- vm.setProp(vm.global, "setInterval", _setInterval);
225
- _setInterval.dispose();
226
-
227
- const _clearTimeout = vm.newFunction("clearTimeout", (timeoutIdHandle) => {
228
- const timeoutId = vm.dump(timeoutIdHandle);
229
- const timeoutHandle = timeoutFunctionHandles[timeoutId.toString()];
230
- if (timeoutHandle) {
231
- cbRemovedTimer();
232
- timeoutHandle.dispose();
233
- clearTimeout(timeoutId);
234
- }
235
- });
236
- vm.setProp(vm.global, "clearTimeout", _clearTimeout);
237
- _clearTimeout.dispose();
238
-
239
- const _clearInterval = vm.newFunction("clearInterval", (intervalIdHandle) => {
240
- const intervalId = vm.dump(intervalIdHandle);
241
- const intervalHandle = intervalFunctionHandles[intervalId.toString()];
242
- if (intervalId) {
243
- cbRemovedTimer();
244
- intervalHandle.dispose();
245
- clearInterval(intervalId);
246
- }
247
- });
248
- vm.setProp(vm.global, "clearInterval", _clearInterval);
249
- _clearInterval.dispose();
1
+ import "quickjs-emscripten";
2
+ import { QuickJSDeferredPromise } from "quickjs-emscripten";
3
+
4
+
5
+ let promiseId = 0;
6
+ let openPromises = {};
7
+
8
+ export function wrapPromise(vm, promise: Promise<any>, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
9
+ promiseId += 1;
10
+
11
+ const vmPromise = vm.newPromise()
12
+ vmPromise._promiseId = promiseId;
13
+ beginAsyncProcess();
14
+ promise.then((...args) => {
15
+ //console.log("Promised resolved", args);
16
+ endAsyncProcess();
17
+ const wrappedArgs = args.map((arg) => wrap(vm, arg, undefined, beginAsyncProcess, endAsyncProcess));
18
+ openPromises[vmPromise._promiseId] = null;
19
+ vmPromise.resolve(...wrappedArgs);
20
+ wrappedArgs.forEach((arg) => arg.dispose());
21
+ }).catch((...args) => {
22
+ //console.log("Promised rejected", args);
23
+ const wrappedArgs = args.map((arg) => wrap(vm, arg, undefined, beginAsyncProcess, endAsyncProcess));
24
+ vmPromise.reject(...wrappedArgs);
25
+ wrappedArgs.forEach((arg) => arg.dispose());
26
+ openPromises[vmPromise._promiseId] = null;
27
+ });
28
+ vmPromise.settled.then( () => {
29
+ endAsyncProcess();
30
+ vm.runtime.executePendingJobs();
31
+ })
32
+
33
+ openPromises[promiseId] = vmPromise;
34
+
35
+ return vmPromise.handle
36
+ }
37
+
38
+ export function rejectOpenPromises(vm) {
39
+ for (const [id, promise ] of Object.entries(openPromises)) {
40
+ if (promise !== null) {
41
+ (promise as QuickJSDeferredPromise).reject(vm.newError("Shutting down"));
42
+ openPromises[id] = null;
43
+ }
44
+ }
45
+
46
+ vm.runtime.executePendingJobs();
47
+ }
48
+
49
+ export function wrap(vm, value: any, context: object, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
50
+ if (value === null) {
51
+ return null;
52
+ } else if (typeof value === 'object' && typeof value.then === 'function') {
53
+ //console.log("Wrapped promise");
54
+ return wrapPromise(vm, value, beginAsyncProcess, endAsyncProcess);
55
+ } else if (typeof value === "function") {
56
+ //console.log("Wrapped function")
57
+ return wrapGenericFunction(vm, value, context, beginAsyncProcess, endAsyncProcess);
58
+ } else if (Array.isArray(value)) {
59
+ //console.log("Wrapped array")
60
+ return wrapArray(vm, value, beginAsyncProcess, endAsyncProcess);
61
+ } else if (value === null) {
62
+ //console.log("Wrapped null")
63
+ return vm.null;
64
+ } else if (typeof value === "object") {
65
+ //console.log("Wrapped object")
66
+ return wrapObject(vm, value, beginAsyncProcess, endAsyncProcess);
67
+ } else if (typeof value === "string") {
68
+ //console.log("Wrapped string")
69
+ return vm.newString(value)
70
+ } else if (typeof value === "number") {
71
+ //console.log("Wrapped number")
72
+ return vm.newNumber(value);
73
+ } else if (typeof value === "bigint") {
74
+ //console.log("Wrapped bigint")
75
+ return vm.newBigInt(value);
76
+ } else if (typeof value === "boolean") {
77
+ // since there is no newBoolean, we have to do this
78
+ return vm.evalCode(value ? "true" : "false").value;
79
+ } else if (typeof value === "undefined") {
80
+ return vm.undefined
81
+ } else {
82
+ return null
83
+ }
84
+ }
85
+
86
+ export function wrapObject(vm, obj: any, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
87
+ const vmObject = vm.newObject();
88
+
89
+ for (const [key, value] of Object.entries(obj)) {
90
+ //console.log("wrapping", key, value)
91
+ let wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
92
+
93
+ if (wrappedValue !== null) {
94
+ vm.setProp(vmObject, key, wrappedValue);
95
+ if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
96
+ wrappedValue.dispose();
97
+ }
98
+ }
99
+ }
100
+
101
+ return vmObject;
102
+ }
103
+
104
+ export function wrapObjectWhitelist(vm, obj: any, whitelist: string[], beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
105
+ const vmObject = vm.newObject();
106
+
107
+ whitelist.forEach((key) => {
108
+ const value = obj[key];
109
+ //console.log("wrapping", key, value)
110
+ const wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
111
+
112
+ if (wrappedValue !== null) {
113
+ vm.setProp(vmObject, key, wrappedValue);
114
+ if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
115
+ wrappedValue.dispose();
116
+ }
117
+ }
118
+ });
119
+
120
+ return vmObject;
121
+ }
122
+
123
+ export function wrapArray(vm, arr: any[], beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
124
+ const vmArray = vm.newArray();
125
+
126
+ for (let i = 0; i < arr.length; i++) {
127
+ let wrappedValue = wrap(vm, arr[i], arr, beginAsyncProcess, endAsyncProcess);
128
+ vm.setProp(vmArray, i, wrappedValue);
129
+ if (wrappedValue != vm.undefined && wrappedValue != vm.null) {
130
+ wrappedValue.dispose();
131
+ }
132
+ }
133
+
134
+ return vmArray;
135
+ }
136
+
137
+ export function wrapGenericFunction(vm, fn: Function, context: object = undefined, beginAsyncProcess: () => void, endAsyncProcess: () => void): any {
138
+ const vmFn = vm.newFunction(fn.name, (...args) => {
139
+ const unwrappedArgs: any[] = args.map(vm.dump)
140
+ //console.log("Wrapped function called", fn.name, unwrappedArgs )
141
+ try {
142
+ const result = fn.call(context, ...unwrappedArgs);
143
+ //console.log("result", result);
144
+ const wrappedResult = wrap(vm, result, undefined, beginAsyncProcess, endAsyncProcess);
145
+ return wrappedResult;
146
+ } catch (e) {
147
+ console.log("Error", e);
148
+ }
149
+
150
+ });
151
+ return vmFn;
152
+ }
153
+
154
+ export function injectTimingFunctions(vm, cbAddedTimer, cbRemovedTimer, maxTimeout = 600000): void {
155
+ // Should we impose a limit on how long things can run for?
156
+ const timeoutFunctionHandles = {};
157
+ const _setTimeout = vm.newFunction("setTimeout", (vmFnHandle, timeoutHandle) => {
158
+ // Make a copy because otherwise vmFnHandle does not live long enough to call after the timeout
159
+ const vmFnHandleCopy = vmFnHandle.dup()
160
+ let timeout = vm.dump(timeoutHandle)
161
+
162
+ // cap timeout at max timeout
163
+ if(timeout > maxTimeout) {
164
+ timeout = maxTimeout;
165
+ }
166
+
167
+ // console.log("Sandbox calling timeout for: " + timeout);
168
+ cbAddedTimer();
169
+ const timeoutID = setTimeout(() => {
170
+ timeoutFunctionHandles[timeoutID.toString()] = null;
171
+ // callFunction(vmFnHandleCopy) will call the vm function
172
+ // in the context of the vm
173
+ // we pass vm.undefined because we need to pass something for the "this" argument
174
+ //console.log("Sandbox called timeout function")
175
+ cbRemovedTimer();
176
+ vm.callFunction(vmFnHandleCopy, vm.undefined)
177
+ vmFnHandleCopy.dispose()
178
+ vm.runtime.executePendingJobs();
179
+ }, timeout)
180
+ timeoutFunctionHandles[timeoutID.toString()] = vmFnHandleCopy;
181
+
182
+ return vm.newNumber(timeoutID);
183
+ });
184
+
185
+ vm.setProp(vm.global, "setTimeout", _setTimeout);
186
+ _setTimeout.dispose();
187
+ const intervalFunctionHandles = {};
188
+ const _setInterval = vm.newFunction("setInterval", (vmFnHandle, timeoutHandle) => {
189
+ // Make a copy because otherwise vmFnHandle does not live long enough to call after the timeout
190
+ const vmFnHandleCopy = vmFnHandle.dup()
191
+ let timeout = vm.dump(timeoutHandle)
192
+
193
+ // cap timeout at max timeout
194
+ if(timeout > maxTimeout) {
195
+ timeout = maxTimeout;
196
+ }
197
+
198
+ //console.log("Sandbox calling interval for: " + timeout);
199
+ const maxRepetitions = 99;
200
+ let repetitions = 0;
201
+ cbAddedTimer();
202
+ const intervalId = setInterval(() => {
203
+ repetitions += 1;
204
+ intervalFunctionHandles[intervalId.toString()] = null
205
+
206
+
207
+ // callFunction(vmFnHandleCopy) will call the vm function
208
+ // in the context of the vm
209
+ // we pass vm.undefined because we need to pass something for the "this" argument
210
+ vm.callFunction(vmFnHandleCopy, vm.undefined)
211
+ vm.runtime.executePendingJobs();
212
+
213
+ if (repetitions > maxRepetitions) {
214
+ console.log("Sandbox interval exceeded max repetitions");
215
+ clearInterval(intervalId);
216
+ cbRemovedTimer();
217
+ return;
218
+ }
219
+ }, timeout);
220
+ intervalFunctionHandles[intervalId.toString()] = vmFnHandleCopy;
221
+
222
+ return vm.newNumber(intervalId);
223
+ });
224
+ vm.setProp(vm.global, "setInterval", _setInterval);
225
+ _setInterval.dispose();
226
+
227
+ const _clearTimeout = vm.newFunction("clearTimeout", (timeoutIdHandle) => {
228
+ const timeoutId = vm.dump(timeoutIdHandle);
229
+ const timeoutHandle = timeoutFunctionHandles[timeoutId.toString()];
230
+ if (timeoutHandle) {
231
+ cbRemovedTimer();
232
+ timeoutHandle.dispose();
233
+ clearTimeout(timeoutId);
234
+ }
235
+ });
236
+ vm.setProp(vm.global, "clearTimeout", _clearTimeout);
237
+ _clearTimeout.dispose();
238
+
239
+ const _clearInterval = vm.newFunction("clearInterval", (intervalIdHandle) => {
240
+ const intervalId = vm.dump(intervalIdHandle);
241
+ const intervalHandle = intervalFunctionHandles[intervalId.toString()];
242
+ if (intervalId) {
243
+ cbRemovedTimer();
244
+ intervalHandle.dispose();
245
+ clearInterval(intervalId);
246
+ }
247
+ });
248
+ vm.setProp(vm.global, "clearInterval", _clearInterval);
249
+ _clearInterval.dispose();
250
250
  }