vm.d.ts (20940B)
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 * import vm from 'node: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.9.0/lib/vm.js) 36 */ 37 declare 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 * import vm from 'node: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 * import vm from 'node: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 * import vm from 'node: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 * import vm from 'node: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 * import vm from 'node: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 * import vm from 'node: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 * import vm from 'node: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 * import vm from 'node:vm'; 415 * 416 * const code = ` 417 * ((require) => { 418 * const http = require('node:http'); 419 * http.createServer((request, response) => { 420 * response.writeHead(200, { 'Content-Type': 'text/plain' }); 421 * response.end('Hello World\\n'); 422 * }).listen(8124); 423 * 424 * console.log('Server running at http://127.0.0.1:8124/'); 425 * })`; 426 * 427 * vm.runInThisContext(code)(require); 428 * ``` 429 * 430 * The `require()` in the above case shares the state with the context it is 431 * passed from. This may introduce risks when untrusted code is executed, e.g. 432 * altering objects in the context in unwanted ways. 433 * @since v0.3.1 434 * @param code The JavaScript code to compile and run. 435 * @return the result of the very last statement executed in the script. 436 */ 437 function runInThisContext(code: string, options?: RunningScriptOptions | string): any; 438 /** 439 * Compiles the given code into the provided context (if no context is 440 * supplied, the current context is used), and returns it wrapped inside a 441 * function with the given `params`. 442 * @since v10.10.0 443 * @param code The body of the function to compile. 444 * @param params An array of strings containing all parameters for the function. 445 */ 446 function compileFunction(code: string, params?: readonly string[], options?: CompileFunctionOptions): Function; 447 /** 448 * Measure the memory known to V8 and used by all contexts known to the 449 * current V8 isolate, or the main context. 450 * 451 * The format of the object that the returned Promise may resolve with is 452 * specific to the V8 engine and may change from one version of V8 to the next. 453 * 454 * The returned result is different from the statistics returned by`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the 455 * memory reachable by each V8 specific contexts in the current instance of 456 * the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure 457 * the memory occupied by each heap space in the current V8 instance. 458 * 459 * ```js 460 * import vm from 'node:vm'; 461 * // Measure the memory used by the main context. 462 * vm.measureMemory({ mode: 'summary' }) 463 * // This is the same as vm.measureMemory() 464 * .then((result) => { 465 * // The current format is: 466 * // { 467 * // total: { 468 * // jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ] 469 * // } 470 * // } 471 * console.log(result); 472 * }); 473 * 474 * const context = vm.createContext({ a: 1 }); 475 * vm.measureMemory({ mode: 'detailed', execution: 'eager' }) 476 * .then((result) => { 477 * // Reference the context here so that it won't be GC'ed 478 * // until the measurement is complete. 479 * console.log(context.a); 480 * // { 481 * // total: { 482 * // jsMemoryEstimate: 2574732, 483 * // jsMemoryRange: [ 2574732, 2904372 ] 484 * // }, 485 * // current: { 486 * // jsMemoryEstimate: 2438996, 487 * // jsMemoryRange: [ 2438996, 2768636 ] 488 * // }, 489 * // other: [ 490 * // { 491 * // jsMemoryEstimate: 135736, 492 * // jsMemoryRange: [ 135736, 465376 ] 493 * // } 494 * // ] 495 * // } 496 * console.log(result); 497 * }); 498 * ``` 499 * @since v13.10.0 500 * @experimental 501 */ 502 function measureMemory(options?: MeasureMemoryOptions): Promise<MemoryMeasurement>; 503 } 504 declare module "node:vm" { 505 export * from "vm"; 506 }