UNPKG

20.8 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/v16.4.2/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 cachedDataRejected?: boolean | undefined;
271 }
272 /**
273 * If given a `contextObject`, the `vm.createContext()` method will `prepare
274 * that object` so that it can be used in calls to {@link runInContext} or `script.runInContext()`. Inside such scripts,
275 * the `contextObject` will be the global object, retaining all of its existing
276 * 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
277 * will remain unchanged.
278 *
279 * ```js
280 * const vm = require('vm');
281 *
282 * global.globalVar = 3;
283 *
284 * const context = { globalVar: 1 };
285 * vm.createContext(context);
286 *
287 * vm.runInContext('globalVar *= 2;', context);
288 *
289 * console.log(context);
290 * // Prints: { globalVar: 2 }
291 *
292 * console.log(global.globalVar);
293 * // Prints: 3
294 * ```
295 *
296 * If `contextObject` is omitted (or passed explicitly as `undefined`), a new,
297 * empty `contextified` object will be returned.
298 *
299 * The `vm.createContext()` method is primarily useful for creating a single
300 * context that can be used to run multiple scripts. For instance, if emulating a
301 * web browser, the method can be used to create a single context representing a
302 * window's global object, then run all `<script>` tags together within that
303 * context.
304 *
305 * The provided `name` and `origin` of the context are made visible through the
306 * Inspector API.
307 * @since v0.3.1
308 * @return contextified object.
309 */
310 function createContext(sandbox?: Context, options?: CreateContextOptions): Context;
311 /**
312 * Returns `true` if the given `object` object has been `contextified` using {@link createContext}.
313 * @since v0.11.7
314 */
315 function isContext(sandbox: Context): boolean;
316 /**
317 * The `vm.runInContext()` method compiles `code`, runs it within the context of
318 * the `contextifiedObject`, then returns the result. Running code does not have
319 * access to the local scope. The `contextifiedObject` object _must_ have been
320 * previously `contextified` using the {@link createContext} method.
321 *
322 * If `options` is a string, then it specifies the filename.
323 *
324 * The following example compiles and executes different scripts using a single `contextified` object:
325 *
326 * ```js
327 * const vm = require('vm');
328 *
329 * const contextObject = { globalVar: 1 };
330 * vm.createContext(contextObject);
331 *
332 * for (let i = 0; i < 10; ++i) {
333 * vm.runInContext('globalVar *= 2;', contextObject);
334 * }
335 * console.log(contextObject);
336 * // Prints: { globalVar: 1024 }
337 * ```
338 * @since v0.3.1
339 * @param code The JavaScript code to compile and run.
340 * @param contextifiedObject The `contextified` object that will be used as the `global` when the `code` is compiled and run.
341 * @return the result of the very last statement executed in the script.
342 */
343 function runInContext(code: string, contextifiedObject: Context, options?: RunningScriptOptions | string): any;
344 /**
345 * The `vm.runInNewContext()` first contextifies the given `contextObject` (or
346 * creates a new `contextObject` if passed as `undefined`), compiles the `code`,
347 * runs it within the created context, then returns the result. Running code
348 * does not have access to the local scope.
349 *
350 * If `options` is a string, then it specifies the filename.
351 *
352 * The following example compiles and executes code that increments a global
353 * variable and sets a new one. These globals are contained in the `contextObject`.
354 *
355 * ```js
356 * const vm = require('vm');
357 *
358 * const contextObject = {
359 * animal: 'cat',
360 * count: 2
361 * };
362 *
363 * vm.runInNewContext('count += 1; name = "kitty"', contextObject);
364 * console.log(contextObject);
365 * // Prints: { animal: 'cat', count: 3, name: 'kitty' }
366 * ```
367 * @since v0.3.1
368 * @param code The JavaScript code to compile and run.
369 * @param contextObject An object that will be `contextified`. If `undefined`, a new object will be created.
370 * @return the result of the very last statement executed in the script.
371 */
372 function runInNewContext(code: string, contextObject?: Context, options?: RunningScriptOptions | string): any;
373 /**
374 * `vm.runInThisContext()` compiles `code`, runs it within the context of the
375 * current `global` and returns the result. Running code does not have access to
376 * local scope, but does have access to the current `global` object.
377 *
378 * If `options` is a string, then it specifies the filename.
379 *
380 * The following example illustrates using both `vm.runInThisContext()` and
381 * the JavaScript [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) function to run the same code:
382 *
383 * ```js
384 * const vm = require('vm');
385 * let localVar = 'initial value';
386 *
387 * const vmResult = vm.runInThisContext('localVar = "vm";');
388 * console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
389 * // Prints: vmResult: 'vm', localVar: 'initial value'
390 *
391 * const evalResult = eval('localVar = "eval";');
392 * console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
393 * // Prints: evalResult: 'eval', localVar: 'eval'
394 * ```
395 *
396 * Because `vm.runInThisContext()` does not have access to the local scope,`localVar` is unchanged. In contrast,
397 * [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)_does_ have access to the
398 * 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')`.
399 *
400 * ## Example: Running an HTTP server within a VM
401 *
402 * When using either `script.runInThisContext()` or {@link runInThisContext}, the code is executed within the current V8 global
403 * context. The code passed to this VM context will have its own isolated scope.
404 *
405 * In order to run a simple web server using the `http` module the code passed to
406 * the context must either call `require('http')` on its own, or have a reference
407 * to the `http` module passed to it. For instance:
408 *
409 * ```js
410 * 'use strict';
411 * const vm = require('vm');
412 *
413 * const code = `
414 * ((require) => {
415 * const http = require('http');
416 *
417 * http.createServer((request, response) => {
418 * response.writeHead(200, { 'Content-Type': 'text/plain' });
419 * response.end('Hello World\\n');
420 * }).listen(8124);
421 *
422 * console.log('Server running at http://127.0.0.1:8124/');
423 * })`;
424 *
425 * vm.runInThisContext(code)(require);
426 * ```
427 *
428 * The `require()` in the above case shares the state with the context it is
429 * passed from. This may introduce risks when untrusted code is executed, e.g.
430 * altering objects in the context in unwanted ways.
431 * @since v0.3.1
432 * @param code The JavaScript code to compile and run.
433 * @return the result of the very last statement executed in the script.
434 */
435 function runInThisContext(code: string, options?: RunningScriptOptions | string): any;
436 /**
437 * Compiles the given code into the provided context (if no context is
438 * supplied, the current context is used), and returns it wrapped inside a
439 * function with the given `params`.
440 * @since v10.10.0
441 * @param code The body of the function to compile.
442 * @param params An array of strings containing all parameters for the function.
443 */
444 function compileFunction(code: string, params?: ReadonlyArray<string>, options?: CompileFunctionOptions): Function;
445 /**
446 * Measure the memory known to V8 and used by all contexts known to the
447 * current V8 isolate, or the main context.
448 *
449 * The format of the object that the returned Promise may resolve with is
450 * specific to the V8 engine and may change from one version of V8 to the next.
451 *
452 * The returned result is different from the statistics returned by`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the
453 * memory reachable by each V8 specific contexts in the current instance of
454 * the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure
455 * the memory occupied by each heap space in the current V8 instance.
456 *
457 * ```js
458 * const vm = require('vm');
459 * // Measure the memory used by the main context.
460 * vm.measureMemory({ mode: 'summary' })
461 * // This is the same as vm.measureMemory()
462 * .then((result) => {
463 * // The current format is:
464 * // {
465 * // total: {
466 * // jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
467 * // }
468 * // }
469 * console.log(result);
470 * });
471 *
472 * const context = vm.createContext({ a: 1 });
473 * vm.measureMemory({ mode: 'detailed', execution: 'eager' })
474 * .then((result) => {
475 * // Reference the context here so that it won't be GC'ed
476 * // until the measurement is complete.
477 * console.log(context.a);
478 * // {
479 * // total: {
480 * // jsMemoryEstimate: 2574732,
481 * // jsMemoryRange: [ 2574732, 2904372 ]
482 * // },
483 * // current: {
484 * // jsMemoryEstimate: 2438996,
485 * // jsMemoryRange: [ 2438996, 2768636 ]
486 * // },
487 * // other: [
488 * // {
489 * // jsMemoryEstimate: 135736,
490 * // jsMemoryRange: [ 135736, 465376 ]
491 * // }
492 * // ]
493 * // }
494 * console.log(result);
495 * });
496 * ```
497 * @since v13.10.0
498 * @experimental
499 */
500 function measureMemory(options?: MeasureMemoryOptions): Promise<MemoryMeasurement>;
501}
502declare module 'node:vm' {
503 export * from 'vm';
504}
505
\No newline at end of file