UNPKG

21 kBTypeScriptView Raw
1/**
2 * The `vm` module enables compiling and running code within V8 Virtual
3 * Machine contexts. **The `vm` module is not a security mechanism. Do**
4 * **not use it to run untrusted code.**
5 *
6 * JavaScript code can be compiled and run immediately or
7 * compiled, saved, and run later.
8 *
9 * A common use case is to run the code in a different V8 Context. This means
10 * invoked code has a different global object than the invoking code.
11 *
12 * One can provide the context by `contextifying` an
13 * object. The invoked code treats any property in the context like a
14 * global variable. Any changes to global variables caused by the invoked
15 * code are reflected in the context object.
16 *
17 * ```js
18 * const vm = require('vm');
19 *
20 * const x = 1;
21 *
22 * const context = { x: 2 };
23 * vm.createContext(context); // Contextify the object.
24 *
25 * const code = 'x += 40; var y = 17;';
26 * // `x` and `y` are global variables in the context.
27 * // Initially, x has the value 2 because that is the value of context.x.
28 * vm.runInContext(code, context);
29 *
30 * console.log(context.x); // 42
31 * console.log(context.y); // 17
32 *
33 * console.log(x); // 1; y is not defined.
34 * ```
35 * @see [source](https://github.com/nodejs/node/blob/v17.0.0/lib/vm.js)
36 */
37declare module 'vm' {
38 interface Context extends NodeJS.Dict<any> {}
39 interface BaseOptions {
40 /**
41 * Specifies the filename used in stack traces produced by this script.
42 * Default: `''`.
43 */
44 filename?: string | undefined;
45 /**
46 * Specifies the line number offset that is displayed in stack traces produced by this script.
47 * Default: `0`.
48 */
49 lineOffset?: number | undefined;
50 /**
51 * Specifies the column number offset that is displayed in stack traces produced by this script.
52 * @default 0
53 */
54 columnOffset?: number | undefined;
55 }
56 interface ScriptOptions extends BaseOptions {
57 displayErrors?: boolean | undefined;
58 timeout?: number | undefined;
59 cachedData?: Buffer | undefined;
60 /** @deprecated in favor of `script.createCachedData()` */
61 produceCachedData?: boolean | undefined;
62 }
63 interface RunningScriptOptions extends BaseOptions {
64 /**
65 * When `true`, if an `Error` occurs while compiling the `code`, the line of code causing the error is attached to the stack trace.
66 * Default: `true`.
67 */
68 displayErrors?: boolean | undefined;
69 /**
70 * Specifies the number of milliseconds to execute code before terminating execution.
71 * If execution is terminated, an `Error` will be thrown. This value must be a strictly positive integer.
72 */
73 timeout?: number | undefined;
74 /**
75 * If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received.
76 * Existing handlers for the event that have been attached via `process.on('SIGINT')` will be disabled during script execution, but will continue to work after that.
77 * If execution is terminated, an `Error` will be thrown.
78 * Default: `false`.
79 */
80 breakOnSigint?: boolean | undefined;
81 /**
82 * If set to `afterEvaluate`, microtasks will be run immediately after the script has run.
83 */
84 microtaskMode?: 'afterEvaluate' | undefined;
85 }
86 interface CompileFunctionOptions extends BaseOptions {
87 /**
88 * Provides an optional data with V8's code cache data for the supplied source.
89 */
90 cachedData?: Buffer | undefined;
91 /**
92 * Specifies whether to produce new cache data.
93 * Default: `false`,
94 */
95 produceCachedData?: boolean | undefined;
96 /**
97 * The sandbox/context in which the said function should be compiled in.
98 */
99 parsingContext?: Context | undefined;
100 /**
101 * An array containing a collection of context extensions (objects wrapping the current scope) to be applied while compiling
102 */
103 contextExtensions?: Object[] | undefined;
104 }
105 interface CreateContextOptions {
106 /**
107 * Human-readable name of the newly created context.
108 * @default 'VM Context i' Where i is an ascending numerical index of the created context.
109 */
110 name?: string | undefined;
111 /**
112 * Corresponds to the newly created context for display purposes.
113 * The origin should be formatted like a `URL`, but with only the scheme, host, and port (if necessary),
114 * like the value of the `url.origin` property of a URL object.
115 * Most notably, this string should omit the trailing slash, as that denotes a path.
116 * @default ''
117 */
118 origin?: string | undefined;
119 codeGeneration?:
120 | {
121 /**
122 * If set to false any calls to eval or function constructors (Function, GeneratorFunction, etc)
123 * will throw an EvalError.
124 * @default true
125 */
126 strings?: boolean | undefined;
127 /**
128 * If set to false any attempt to compile a WebAssembly module will throw a WebAssembly.CompileError.
129 * @default true
130 */
131 wasm?: boolean | undefined;
132 }
133 | undefined;
134 /**
135 * If set to `afterEvaluate`, microtasks will be run immediately after the script has run.
136 */
137 microtaskMode?: 'afterEvaluate' | undefined;
138 }
139 type MeasureMemoryMode = 'summary' | 'detailed';
140 interface MeasureMemoryOptions {
141 /**
142 * @default 'summary'
143 */
144 mode?: MeasureMemoryMode | undefined;
145 context?: Context | undefined;
146 }
147 interface MemoryMeasurement {
148 total: {
149 jsMemoryEstimate: number;
150 jsMemoryRange: [number, number];
151 };
152 }
153 /**
154 * Instances of the `vm.Script` class contain precompiled scripts that can be
155 * executed in specific contexts.
156 * @since v0.3.1
157 */
158 class Script {
159 constructor(code: string, options?: ScriptOptions);
160 /**
161 * Runs the compiled code contained by the `vm.Script` object within the given`contextifiedObject` and returns the result. Running code does not have access
162 * to local scope.
163 *
164 * The following example compiles code that increments a global variable, sets
165 * the value of another global variable, then execute the code multiple times.
166 * The globals are contained in the `context` object.
167 *
168 * ```js
169 * const vm = require('vm');
170 *
171 * const context = {
172 * animal: 'cat',
173 * count: 2
174 * };
175 *
176 * const script = new vm.Script('count += 1; name = "kitty";');
177 *
178 * vm.createContext(context);
179 * for (let i = 0; i < 10; ++i) {
180 * script.runInContext(context);
181 * }
182 *
183 * console.log(context);
184 * // Prints: { animal: 'cat', count: 12, name: 'kitty' }
185 * ```
186 *
187 * Using the `timeout` or `breakOnSigint` options will result in new event loops
188 * and corresponding threads being started, which have a non-zero performance
189 * overhead.
190 * @since v0.3.1
191 * @param contextifiedObject A `contextified` object as returned by the `vm.createContext()` method.
192 * @return the result of the very last statement executed in the script.
193 */
194 runInContext(contextifiedObject: Context, options?: RunningScriptOptions): any;
195 /**
196 * First contextifies the given `contextObject`, runs the compiled code contained
197 * by the `vm.Script` object within the created context, and returns the result.
198 * Running code does not have access to local scope.
199 *
200 * The following example compiles code that sets a global variable, then executes
201 * the code multiple times in different contexts. The globals are set on and
202 * contained within each individual `context`.
203 *
204 * ```js
205 * const vm = require('vm');
206 *
207 * const script = new vm.Script('globalVar = "set"');
208 *
209 * const contexts = [{}, {}, {}];
210 * contexts.forEach((context) => {
211 * script.runInNewContext(context);
212 * });
213 *
214 * console.log(contexts);
215 * // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
216 * ```
217 * @since v0.3.1
218 * @param contextObject An object that will be `contextified`. If `undefined`, a new object will be created.
219 * @return the result of the very last statement executed in the script.
220 */
221 runInNewContext(contextObject?: Context, options?: RunningScriptOptions): any;
222 /**
223 * Runs the compiled code contained by the `vm.Script` within the context of the
224 * current `global` object. Running code does not have access to local scope, but_does_ have access to the current `global` object.
225 *
226 * The following example compiles code that increments a `global` variable then
227 * executes that code multiple times:
228 *
229 * ```js
230 * const vm = require('vm');
231 *
232 * global.globalVar = 0;
233 *
234 * const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
235 *
236 * for (let i = 0; i < 1000; ++i) {
237 * script.runInThisContext();
238 * }
239 *
240 * console.log(globalVar);
241 *
242 * // 1000
243 * ```
244 * @since v0.3.1
245 * @return the result of the very last statement executed in the script.
246 */
247 runInThisContext(options?: RunningScriptOptions): any;
248 /**
249 * Creates a code cache that can be used with the `Script` constructor's`cachedData` option. Returns a `Buffer`. This method may be called at any
250 * time and any number of times.
251 *
252 * ```js
253 * const script = new vm.Script(`
254 * function add(a, b) {
255 * return a + b;
256 * }
257 *
258 * const x = add(1, 2);
259 * `);
260 *
261 * const cacheWithoutX = script.createCachedData();
262 *
263 * script.runInThisContext();
264 *
265 * const cacheWithX = script.createCachedData();
266 * ```
267 * @since v10.6.0
268 */
269 createCachedData(): Buffer;
270 /** @deprecated in favor of `script.createCachedData()` */
271 cachedDataProduced?: boolean | undefined;
272 cachedDataRejected?: boolean | undefined;
273 cachedData?: Buffer | undefined;
274 }
275 /**
276 * If given a `contextObject`, the `vm.createContext()` method will `prepare
277 * that object` so that it can be used in calls to {@link runInContext} or `script.runInContext()`. Inside such scripts,
278 * the `contextObject` will be the global object, retaining all of its existing
279 * properties but also having the built-in objects and functions any standard [global object](https://es5.github.io/#x15.1) has. Outside of scripts run by the vm module, global variables
280 * will remain unchanged.
281 *
282 * ```js
283 * const vm = require('vm');
284 *
285 * global.globalVar = 3;
286 *
287 * const context = { globalVar: 1 };
288 * vm.createContext(context);
289 *
290 * vm.runInContext('globalVar *= 2;', context);
291 *
292 * console.log(context);
293 * // Prints: { globalVar: 2 }
294 *
295 * console.log(global.globalVar);
296 * // Prints: 3
297 * ```
298 *
299 * If `contextObject` is omitted (or passed explicitly as `undefined`), a new,
300 * empty `contextified` object will be returned.
301 *
302 * The `vm.createContext()` method is primarily useful for creating a single
303 * context that can be used to run multiple scripts. For instance, if emulating a
304 * web browser, the method can be used to create a single context representing a
305 * window's global object, then run all `<script>` tags together within that
306 * context.
307 *
308 * The provided `name` and `origin` of the context are made visible through the
309 * Inspector API.
310 * @since v0.3.1
311 * @return contextified object.
312 */
313 function createContext(sandbox?: Context, options?: CreateContextOptions): Context;
314 /**
315 * Returns `true` if the given `object` object has been `contextified` using {@link createContext}.
316 * @since v0.11.7
317 */
318 function isContext(sandbox: Context): boolean;
319 /**
320 * The `vm.runInContext()` method compiles `code`, runs it within the context of
321 * the `contextifiedObject`, then returns the result. Running code does not have
322 * access to the local scope. The `contextifiedObject` object _must_ have been
323 * previously `contextified` using the {@link createContext} method.
324 *
325 * If `options` is a string, then it specifies the filename.
326 *
327 * The following example compiles and executes different scripts using a single `contextified` object:
328 *
329 * ```js
330 * const vm = require('vm');
331 *
332 * const contextObject = { globalVar: 1 };
333 * vm.createContext(contextObject);
334 *
335 * for (let i = 0; i < 10; ++i) {
336 * vm.runInContext('globalVar *= 2;', contextObject);
337 * }
338 * console.log(contextObject);
339 * // Prints: { globalVar: 1024 }
340 * ```
341 * @since v0.3.1
342 * @param code The JavaScript code to compile and run.
343 * @param contextifiedObject The `contextified` object that will be used as the `global` when the `code` is compiled and run.
344 * @return the result of the very last statement executed in the script.
345 */
346 function runInContext(code: string, contextifiedObject: Context, options?: RunningScriptOptions | string): any;
347 /**
348 * The `vm.runInNewContext()` first contextifies the given `contextObject` (or
349 * creates a new `contextObject` if passed as `undefined`), compiles the `code`,
350 * runs it within the created context, then returns the result. Running code
351 * does not have access to the local scope.
352 *
353 * If `options` is a string, then it specifies the filename.
354 *
355 * The following example compiles and executes code that increments a global
356 * variable and sets a new one. These globals are contained in the `contextObject`.
357 *
358 * ```js
359 * const vm = require('vm');
360 *
361 * const contextObject = {
362 * animal: 'cat',
363 * count: 2
364 * };
365 *
366 * vm.runInNewContext('count += 1; name = "kitty"', contextObject);
367 * console.log(contextObject);
368 * // Prints: { animal: 'cat', count: 3, name: 'kitty' }
369 * ```
370 * @since v0.3.1
371 * @param code The JavaScript code to compile and run.
372 * @param contextObject An object that will be `contextified`. If `undefined`, a new object will be created.
373 * @return the result of the very last statement executed in the script.
374 */
375 function runInNewContext(code: string, contextObject?: Context, options?: RunningScriptOptions | string): any;
376 /**
377 * `vm.runInThisContext()` compiles `code`, runs it within the context of the
378 * current `global` and returns the result. Running code does not have access to
379 * local scope, but does have access to the current `global` object.
380 *
381 * If `options` is a string, then it specifies the filename.
382 *
383 * The following example illustrates using both `vm.runInThisContext()` and
384 * the JavaScript [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) function to run the same code:
385 *
386 * ```js
387 * const vm = require('vm');
388 * let localVar = 'initial value';
389 *
390 * const vmResult = vm.runInThisContext('localVar = "vm";');
391 * console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
392 * // Prints: vmResult: 'vm', localVar: 'initial value'
393 *
394 * const evalResult = eval('localVar = "eval";');
395 * console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
396 * // Prints: evalResult: 'eval', localVar: 'eval'
397 * ```
398 *
399 * Because `vm.runInThisContext()` does not have access to the local scope,`localVar` is unchanged. In contrast,
400 * [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) _does_ have access to the
401 * local scope, so the value `localVar` is changed. In this way`vm.runInThisContext()` is much like an [indirect `eval()` call](https://es5.github.io/#x10.4.2), e.g.`(0,eval)('code')`.
402 *
403 * ## Example: Running an HTTP server within a VM
404 *
405 * When using either `script.runInThisContext()` or {@link runInThisContext}, the code is executed within the current V8 global
406 * context. The code passed to this VM context will have its own isolated scope.
407 *
408 * In order to run a simple web server using the `http` module the code passed to
409 * the context must either call `require('http')` on its own, or have a reference
410 * to the `http` module passed to it. For instance:
411 *
412 * ```js
413 * 'use strict';
414 * const vm = require('vm');
415 *
416 * const code = `
417 * ((require) => {
418 * const http = require('http');
419 *
420 * http.createServer((request, response) => {
421 * response.writeHead(200, { 'Content-Type': 'text/plain' });
422 * response.end('Hello World\\n');
423 * }).listen(8124);
424 *
425 * console.log('Server running at http://127.0.0.1:8124/');
426 * })`;
427 *
428 * vm.runInThisContext(code)(require);
429 * ```
430 *
431 * The `require()` in the above case shares the state with the context it is
432 * passed from. This may introduce risks when untrusted code is executed, e.g.
433 * altering objects in the context in unwanted ways.
434 * @since v0.3.1
435 * @param code The JavaScript code to compile and run.
436 * @return the result of the very last statement executed in the script.
437 */
438 function runInThisContext(code: string, options?: RunningScriptOptions | string): any;
439 /**
440 * Compiles the given code into the provided context (if no context is
441 * supplied, the current context is used), and returns it wrapped inside a
442 * function with the given `params`.
443 * @since v10.10.0
444 * @param code The body of the function to compile.
445 * @param params An array of strings containing all parameters for the function.
446 */
447 function compileFunction(code: string, params?: ReadonlyArray<string>, options?: CompileFunctionOptions): Function;
448 /**
449 * Measure the memory known to V8 and used by all contexts known to the
450 * current V8 isolate, or the main context.
451 *
452 * The format of the object that the returned Promise may resolve with is
453 * specific to the V8 engine and may change from one version of V8 to the next.
454 *
455 * The returned result is different from the statistics returned by`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the
456 * memory reachable by each V8 specific contexts in the current instance of
457 * the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure
458 * the memory occupied by each heap space in the current V8 instance.
459 *
460 * ```js
461 * const vm = require('vm');
462 * // Measure the memory used by the main context.
463 * vm.measureMemory({ mode: 'summary' })
464 * // This is the same as vm.measureMemory()
465 * .then((result) => {
466 * // The current format is:
467 * // {
468 * // total: {
469 * // jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
470 * // }
471 * // }
472 * console.log(result);
473 * });
474 *
475 * const context = vm.createContext({ a: 1 });
476 * vm.measureMemory({ mode: 'detailed', execution: 'eager' })
477 * .then((result) => {
478 * // Reference the context here so that it won't be GC'ed
479 * // until the measurement is complete.
480 * console.log(context.a);
481 * // {
482 * // total: {
483 * // jsMemoryEstimate: 2574732,
484 * // jsMemoryRange: [ 2574732, 2904372 ]
485 * // },
486 * // current: {
487 * // jsMemoryEstimate: 2438996,
488 * // jsMemoryRange: [ 2438996, 2768636 ]
489 * // },
490 * // other: [
491 * // {
492 * // jsMemoryEstimate: 135736,
493 * // jsMemoryRange: [ 135736, 465376 ]
494 * // }
495 * // ]
496 * // }
497 * console.log(result);
498 * });
499 * ```
500 * @since v13.10.0
501 * @experimental
502 */
503 function measureMemory(options?: MeasureMemoryOptions): Promise<MemoryMeasurement>;
504}
505declare module 'node:vm' {
506 export * from 'vm';
507}
508
\No newline at end of file