89d91eea1d10e170d77e6310392f32afee414c10dc9c939de22ed847eb97590bd96e681c5c92c6ddbc5f1fb4c93479de495ef20aac3b417a6e79c3e2d2de87 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. /**
  2. * The `node:vm` module enables compiling and running code within V8 Virtual
  3. * Machine contexts.
  4. *
  5. * **The `node:vm` module is not a security**
  6. * **mechanism. Do not use it to run untrusted code.**
  7. *
  8. * JavaScript code can be compiled and run immediately or
  9. * compiled, saved, and run later.
  10. *
  11. * A common use case is to run the code in a different V8 Context. This means
  12. * invoked code has a different global object than the invoking code.
  13. *
  14. * One can provide the context by `contextifying` an
  15. * object. The invoked code treats any property in the context like a
  16. * global variable. Any changes to global variables caused by the invoked
  17. * code are reflected in the context object.
  18. *
  19. * ```js
  20. * import vm from 'node:vm';
  21. *
  22. * const x = 1;
  23. *
  24. * const context = { x: 2 };
  25. * vm.createContext(context); // Contextify the object.
  26. *
  27. * const code = 'x += 40; var y = 17;';
  28. * // `x` and `y` are global variables in the context.
  29. * // Initially, x has the value 2 because that is the value of context.x.
  30. * vm.runInContext(code, context);
  31. *
  32. * console.log(context.x); // 42
  33. * console.log(context.y); // 17
  34. *
  35. * console.log(x); // 1; y is not defined.
  36. * ```
  37. * @see [source](https://github.com/nodejs/node/blob/v22.x/lib/vm.js)
  38. */
  39. declare module "vm" {
  40. import { ImportAttributes } from "node:module";
  41. interface Context extends NodeJS.Dict<any> {}
  42. interface BaseOptions {
  43. /**
  44. * Specifies the filename used in stack traces produced by this script.
  45. * @default ''
  46. */
  47. filename?: string | undefined;
  48. /**
  49. * Specifies the line number offset that is displayed in stack traces produced by this script.
  50. * @default 0
  51. */
  52. lineOffset?: number | undefined;
  53. /**
  54. * Specifies the column number offset that is displayed in stack traces produced by this script.
  55. * @default 0
  56. */
  57. columnOffset?: number | undefined;
  58. }
  59. interface ScriptOptions extends BaseOptions {
  60. /**
  61. * Provides an optional data with V8's code cache data for the supplied source.
  62. */
  63. cachedData?: Buffer | NodeJS.ArrayBufferView | undefined;
  64. /** @deprecated in favor of `script.createCachedData()` */
  65. produceCachedData?: boolean | undefined;
  66. /**
  67. * Used to specify how the modules should be loaded during the evaluation of this script when `import()` is called. This option is
  68. * part of the experimental modules API. We do not recommend using it in a production environment. For detailed information, see
  69. * [Support of dynamic `import()` in compilation APIs](https://nodejs.org/docs/latest-v22.x/api/vm.html#support-of-dynamic-import-in-compilation-apis).
  70. */
  71. importModuleDynamically?:
  72. | ((specifier: string, script: Script, importAttributes: ImportAttributes) => Module | Promise<Module>)
  73. | typeof constants.USE_MAIN_CONTEXT_DEFAULT_LOADER
  74. | undefined;
  75. }
  76. interface RunningScriptOptions extends BaseOptions {
  77. /**
  78. * When `true`, if an `Error` occurs while compiling the `code`, the line of code causing the error is attached to the stack trace.
  79. * @default true
  80. */
  81. displayErrors?: boolean | undefined;
  82. /**
  83. * Specifies the number of milliseconds to execute code before terminating execution.
  84. * If execution is terminated, an `Error` will be thrown. This value must be a strictly positive integer.
  85. */
  86. timeout?: number | undefined;
  87. /**
  88. * If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received.
  89. * 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.
  90. * If execution is terminated, an `Error` will be thrown.
  91. * @default false
  92. */
  93. breakOnSigint?: boolean | undefined;
  94. }
  95. interface RunningScriptInNewContextOptions extends RunningScriptOptions {
  96. /**
  97. * Human-readable name of the newly created context.
  98. */
  99. contextName?: CreateContextOptions["name"];
  100. /**
  101. * Origin corresponding to the newly created context for display purposes. The origin should be formatted like a URL,
  102. * but with only the scheme, host, and port (if necessary), like the value of the `url.origin` property of a `URL` object.
  103. * Most notably, this string should omit the trailing slash, as that denotes a path.
  104. */
  105. contextOrigin?: CreateContextOptions["origin"];
  106. contextCodeGeneration?: CreateContextOptions["codeGeneration"];
  107. /**
  108. * If set to `afterEvaluate`, microtasks will be run immediately after the script has run.
  109. */
  110. microtaskMode?: CreateContextOptions["microtaskMode"];
  111. }
  112. interface RunningCodeOptions extends RunningScriptOptions {
  113. /**
  114. * Provides an optional data with V8's code cache data for the supplied source.
  115. */
  116. cachedData?: ScriptOptions["cachedData"] | undefined;
  117. importModuleDynamically?: ScriptOptions["importModuleDynamically"];
  118. }
  119. interface RunningCodeInNewContextOptions extends RunningScriptInNewContextOptions {
  120. /**
  121. * Provides an optional data with V8's code cache data for the supplied source.
  122. */
  123. cachedData?: ScriptOptions["cachedData"] | undefined;
  124. importModuleDynamically?: ScriptOptions["importModuleDynamically"];
  125. }
  126. interface CompileFunctionOptions extends BaseOptions {
  127. /**
  128. * Provides an optional data with V8's code cache data for the supplied source.
  129. */
  130. cachedData?: ScriptOptions["cachedData"] | undefined;
  131. /**
  132. * Specifies whether to produce new cache data.
  133. * @default false
  134. */
  135. produceCachedData?: boolean | undefined;
  136. /**
  137. * The sandbox/context in which the said function should be compiled in.
  138. */
  139. parsingContext?: Context | undefined;
  140. /**
  141. * An array containing a collection of context extensions (objects wrapping the current scope) to be applied while compiling
  142. */
  143. contextExtensions?: Object[] | undefined;
  144. }
  145. interface CreateContextOptions {
  146. /**
  147. * Human-readable name of the newly created context.
  148. * @default 'VM Context i' Where i is an ascending numerical index of the created context.
  149. */
  150. name?: string | undefined;
  151. /**
  152. * Corresponds to the newly created context for display purposes.
  153. * The origin should be formatted like a `URL`, but with only the scheme, host, and port (if necessary),
  154. * like the value of the `url.origin` property of a URL object.
  155. * Most notably, this string should omit the trailing slash, as that denotes a path.
  156. * @default ''
  157. */
  158. origin?: string | undefined;
  159. codeGeneration?:
  160. | {
  161. /**
  162. * If set to false any calls to eval or function constructors (Function, GeneratorFunction, etc)
  163. * will throw an EvalError.
  164. * @default true
  165. */
  166. strings?: boolean | undefined;
  167. /**
  168. * If set to false any attempt to compile a WebAssembly module will throw a WebAssembly.CompileError.
  169. * @default true
  170. */
  171. wasm?: boolean | undefined;
  172. }
  173. | undefined;
  174. /**
  175. * If set to `afterEvaluate`, microtasks will be run immediately after the script has run.
  176. */
  177. microtaskMode?: "afterEvaluate" | undefined;
  178. }
  179. type MeasureMemoryMode = "summary" | "detailed";
  180. interface MeasureMemoryOptions {
  181. /**
  182. * @default 'summary'
  183. */
  184. mode?: MeasureMemoryMode | undefined;
  185. /**
  186. * @default 'default'
  187. */
  188. execution?: "default" | "eager" | undefined;
  189. }
  190. interface MemoryMeasurement {
  191. total: {
  192. jsMemoryEstimate: number;
  193. jsMemoryRange: [number, number];
  194. };
  195. }
  196. /**
  197. * Instances of the `vm.Script` class contain precompiled scripts that can be
  198. * executed in specific contexts.
  199. * @since v0.3.1
  200. */
  201. class Script {
  202. constructor(code: string, options?: ScriptOptions | string);
  203. /**
  204. * Runs the compiled code contained by the `vm.Script` object within the given `contextifiedObject` and returns the result. Running code does not have access
  205. * to local scope.
  206. *
  207. * The following example compiles code that increments a global variable, sets
  208. * the value of another global variable, then execute the code multiple times.
  209. * The globals are contained in the `context` object.
  210. *
  211. * ```js
  212. * import vm from 'node:vm';
  213. *
  214. * const context = {
  215. * animal: 'cat',
  216. * count: 2,
  217. * };
  218. *
  219. * const script = new vm.Script('count += 1; name = "kitty";');
  220. *
  221. * vm.createContext(context);
  222. * for (let i = 0; i < 10; ++i) {
  223. * script.runInContext(context);
  224. * }
  225. *
  226. * console.log(context);
  227. * // Prints: { animal: 'cat', count: 12, name: 'kitty' }
  228. * ```
  229. *
  230. * Using the `timeout` or `breakOnSigint` options will result in new event loops
  231. * and corresponding threads being started, which have a non-zero performance
  232. * overhead.
  233. * @since v0.3.1
  234. * @param contextifiedObject A `contextified` object as returned by the `vm.createContext()` method.
  235. * @return the result of the very last statement executed in the script.
  236. */
  237. runInContext(contextifiedObject: Context, options?: RunningScriptOptions): any;
  238. /**
  239. * This method is a shortcut to `script.runInContext(vm.createContext(options), options)`.
  240. * It does several things at once:
  241. *
  242. * 1. Creates a new context.
  243. * 2. If `contextObject` is an object, contextifies it with the new context.
  244. * If `contextObject` is undefined, creates a new object and contextifies it.
  245. * If `contextObject` is `vm.constants.DONT_CONTEXTIFY`, don't contextify anything.
  246. * 3. Runs the compiled code contained by the `vm.Script` object within the created context. The code
  247. * does not have access to the scope in which this method is called.
  248. * 4. Returns the result.
  249. *
  250. * The following example compiles code that sets a global variable, then executes
  251. * the code multiple times in different contexts. The globals are set on and
  252. * contained within each individual `context`.
  253. *
  254. * ```js
  255. * const vm = require('node:vm');
  256. *
  257. * const script = new vm.Script('globalVar = "set"');
  258. *
  259. * const contexts = [{}, {}, {}];
  260. * contexts.forEach((context) => {
  261. * script.runInNewContext(context);
  262. * });
  263. *
  264. * console.log(contexts);
  265. * // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
  266. *
  267. * // This would throw if the context is created from a contextified object.
  268. * // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary
  269. * // global objects that can be frozen.
  270. * const freezeScript = new vm.Script('Object.freeze(globalThis); globalThis;');
  271. * const frozenContext = freezeScript.runInNewContext(vm.constants.DONT_CONTEXTIFY);
  272. * ```
  273. * @since v0.3.1
  274. * @param contextObject Either `vm.constants.DONT_CONTEXTIFY` or an object that will be contextified.
  275. * If `undefined`, an empty contextified object will be created for backwards compatibility.
  276. * @return the result of the very last statement executed in the script.
  277. */
  278. runInNewContext(
  279. contextObject?: Context | typeof constants.DONT_CONTEXTIFY,
  280. options?: RunningScriptInNewContextOptions,
  281. ): any;
  282. /**
  283. * Runs the compiled code contained by the `vm.Script` within the context of the
  284. * current `global` object. Running code does not have access to local scope, but _does_ have access to the current `global` object.
  285. *
  286. * The following example compiles code that increments a `global` variable then
  287. * executes that code multiple times:
  288. *
  289. * ```js
  290. * import vm from 'node:vm';
  291. *
  292. * global.globalVar = 0;
  293. *
  294. * const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
  295. *
  296. * for (let i = 0; i < 1000; ++i) {
  297. * script.runInThisContext();
  298. * }
  299. *
  300. * console.log(globalVar);
  301. *
  302. * // 1000
  303. * ```
  304. * @since v0.3.1
  305. * @return the result of the very last statement executed in the script.
  306. */
  307. runInThisContext(options?: RunningScriptOptions): any;
  308. /**
  309. * 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
  310. * time and any number of times.
  311. *
  312. * The code cache of the `Script` doesn't contain any JavaScript observable
  313. * states. The code cache is safe to be saved along side the script source and
  314. * used to construct new `Script` instances multiple times.
  315. *
  316. * Functions in the `Script` source can be marked as lazily compiled and they are
  317. * not compiled at construction of the `Script`. These functions are going to be
  318. * compiled when they are invoked the first time. The code cache serializes the
  319. * metadata that V8 currently knows about the `Script` that it can use to speed up
  320. * future compilations.
  321. *
  322. * ```js
  323. * const script = new vm.Script(`
  324. * function add(a, b) {
  325. * return a + b;
  326. * }
  327. *
  328. * const x = add(1, 2);
  329. * `);
  330. *
  331. * const cacheWithoutAdd = script.createCachedData();
  332. * // In `cacheWithoutAdd` the function `add()` is marked for full compilation
  333. * // upon invocation.
  334. *
  335. * script.runInThisContext();
  336. *
  337. * const cacheWithAdd = script.createCachedData();
  338. * // `cacheWithAdd` contains fully compiled function `add()`.
  339. * ```
  340. * @since v10.6.0
  341. */
  342. createCachedData(): Buffer;
  343. /** @deprecated in favor of `script.createCachedData()` */
  344. cachedDataProduced?: boolean | undefined;
  345. /**
  346. * When `cachedData` is supplied to create the `vm.Script`, this value will be set
  347. * to either `true` or `false` depending on acceptance of the data by V8.
  348. * Otherwise the value is `undefined`.
  349. * @since v5.7.0
  350. */
  351. cachedDataRejected?: boolean | undefined;
  352. cachedData?: Buffer | undefined;
  353. /**
  354. * When the script is compiled from a source that contains a source map magic
  355. * comment, this property will be set to the URL of the source map.
  356. *
  357. * ```js
  358. * import vm from 'node:vm';
  359. *
  360. * const script = new vm.Script(`
  361. * function myFunc() {}
  362. * //# sourceMappingURL=sourcemap.json
  363. * `);
  364. *
  365. * console.log(script.sourceMapURL);
  366. * // Prints: sourcemap.json
  367. * ```
  368. * @since v19.1.0, v18.13.0
  369. */
  370. sourceMapURL?: string | undefined;
  371. }
  372. /**
  373. * If the given `contextObject` is an object, the `vm.createContext()` method will
  374. * [prepare that object](https://nodejs.org/docs/latest-v22.x/api/vm.html#what-does-it-mean-to-contextify-an-object)
  375. * and return a reference to it so that it can be used in calls to {@link runInContext} or
  376. * [`script.runInContext()`](https://nodejs.org/docs/latest-v22.x/api/vm.html#scriptrunincontextcontextifiedobject-options).
  377. * Inside such scripts, the global object will be wrapped by the `contextObject`, retaining all of its
  378. * existing properties but also having the built-in objects and functions any standard
  379. * [global object](https://es5.github.io/#x15.1) has. Outside of scripts run by the vm module, global
  380. * variables will remain unchanged.
  381. *
  382. * ```js
  383. * const vm = require('node:vm');
  384. *
  385. * global.globalVar = 3;
  386. *
  387. * const context = { globalVar: 1 };
  388. * vm.createContext(context);
  389. *
  390. * vm.runInContext('globalVar *= 2;', context);
  391. *
  392. * console.log(context);
  393. * // Prints: { globalVar: 2 }
  394. *
  395. * console.log(global.globalVar);
  396. * // Prints: 3
  397. * ```
  398. *
  399. * If `contextObject` is omitted (or passed explicitly as `undefined`), a new,
  400. * empty contextified object will be returned.
  401. *
  402. * When the global object in the newly created context is contextified, it has some quirks
  403. * compared to ordinary global objects. For example, it cannot be frozen. To create a context
  404. * without the contextifying quirks, pass `vm.constants.DONT_CONTEXTIFY` as the `contextObject`
  405. * argument. See the documentation of `vm.constants.DONT_CONTEXTIFY` for details.
  406. *
  407. * The `vm.createContext()` method is primarily useful for creating a single
  408. * context that can be used to run multiple scripts. For instance, if emulating a
  409. * web browser, the method can be used to create a single context representing a
  410. * window's global object, then run all `<script>` tags together within that
  411. * context.
  412. *
  413. * The provided `name` and `origin` of the context are made visible through the
  414. * Inspector API.
  415. * @since v0.3.1
  416. * @param contextObject Either `vm.constants.DONT_CONTEXTIFY` or an object that will be contextified.
  417. * If `undefined`, an empty contextified object will be created for backwards compatibility.
  418. * @return contextified object.
  419. */
  420. function createContext(
  421. contextObject?: Context | typeof constants.DONT_CONTEXTIFY,
  422. options?: CreateContextOptions,
  423. ): Context;
  424. /**
  425. * Returns `true` if the given `object` object has been contextified using {@link createContext},
  426. * or if it's the global object of a context created using `vm.constants.DONT_CONTEXTIFY`.
  427. * @since v0.11.7
  428. */
  429. function isContext(sandbox: Context): boolean;
  430. /**
  431. * The `vm.runInContext()` method compiles `code`, runs it within the context of
  432. * the `contextifiedObject`, then returns the result. Running code does not have
  433. * access to the local scope. The `contextifiedObject` object _must_ have been
  434. * previously `contextified` using the {@link createContext} method.
  435. *
  436. * If `options` is a string, then it specifies the filename.
  437. *
  438. * The following example compiles and executes different scripts using a single `contextified` object:
  439. *
  440. * ```js
  441. * import vm from 'node:vm';
  442. *
  443. * const contextObject = { globalVar: 1 };
  444. * vm.createContext(contextObject);
  445. *
  446. * for (let i = 0; i < 10; ++i) {
  447. * vm.runInContext('globalVar *= 2;', contextObject);
  448. * }
  449. * console.log(contextObject);
  450. * // Prints: { globalVar: 1024 }
  451. * ```
  452. * @since v0.3.1
  453. * @param code The JavaScript code to compile and run.
  454. * @param contextifiedObject The `contextified` object that will be used as the `global` when the `code` is compiled and run.
  455. * @return the result of the very last statement executed in the script.
  456. */
  457. function runInContext(code: string, contextifiedObject: Context, options?: RunningCodeOptions | string): any;
  458. /**
  459. * This method is a shortcut to
  460. * `(new vm.Script(code, options)).runInContext(vm.createContext(options), options)`.
  461. * If `options` is a string, then it specifies the filename.
  462. *
  463. * It does several things at once:
  464. *
  465. * 1. Creates a new context.
  466. * 2. If `contextObject` is an object, contextifies it with the new context.
  467. * If `contextObject` is undefined, creates a new object and contextifies it.
  468. * If `contextObject` is `vm.constants.DONT_CONTEXTIFY`, don't contextify anything.
  469. * 3. Compiles the code as a`vm.Script`
  470. * 4. Runs the compield code within the created context. The code does not have access to the scope in
  471. * which this method is called.
  472. * 5. Returns the result.
  473. *
  474. * The following example compiles and executes code that increments a global
  475. * variable and sets a new one. These globals are contained in the `contextObject`.
  476. *
  477. * ```js
  478. * const vm = require('node:vm');
  479. *
  480. * const contextObject = {
  481. * animal: 'cat',
  482. * count: 2,
  483. * };
  484. *
  485. * vm.runInNewContext('count += 1; name = "kitty"', contextObject);
  486. * console.log(contextObject);
  487. * // Prints: { animal: 'cat', count: 3, name: 'kitty' }
  488. *
  489. * // This would throw if the context is created from a contextified object.
  490. * // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that
  491. * // can be frozen.
  492. * const frozenContext = vm.runInNewContext('Object.freeze(globalThis); globalThis;', vm.constants.DONT_CONTEXTIFY);
  493. * ```
  494. * @since v0.3.1
  495. * @param code The JavaScript code to compile and run.
  496. * @param contextObject Either `vm.constants.DONT_CONTEXTIFY` or an object that will be contextified.
  497. * If `undefined`, an empty contextified object will be created for backwards compatibility.
  498. * @return the result of the very last statement executed in the script.
  499. */
  500. function runInNewContext(
  501. code: string,
  502. contextObject?: Context | typeof constants.DONT_CONTEXTIFY,
  503. options?: RunningCodeInNewContextOptions | string,
  504. ): any;
  505. /**
  506. * `vm.runInThisContext()` compiles `code`, runs it within the context of the
  507. * current `global` and returns the result. Running code does not have access to
  508. * local scope, but does have access to the current `global` object.
  509. *
  510. * If `options` is a string, then it specifies the filename.
  511. *
  512. * The following example illustrates using both `vm.runInThisContext()` and
  513. * the JavaScript [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) function to run the same code:
  514. *
  515. * ```js
  516. * import vm from 'node:vm';
  517. * let localVar = 'initial value';
  518. *
  519. * const vmResult = vm.runInThisContext('localVar = "vm";');
  520. * console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
  521. * // Prints: vmResult: 'vm', localVar: 'initial value'
  522. *
  523. * const evalResult = eval('localVar = "eval";');
  524. * console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
  525. * // Prints: evalResult: 'eval', localVar: 'eval'
  526. * ```
  527. *
  528. * Because `vm.runInThisContext()` does not have access to the local scope, `localVar` is unchanged. In contrast,
  529. * [`eval()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) _does_ have access to the
  530. * 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')`.
  531. *
  532. * ## Example: Running an HTTP server within a VM
  533. *
  534. * When using either `script.runInThisContext()` or {@link runInThisContext}, the code is executed within the current V8 global
  535. * context. The code passed to this VM context will have its own isolated scope.
  536. *
  537. * In order to run a simple web server using the `node:http` module the code passed
  538. * to the context must either import `node:http` on its own, or have a
  539. * reference to the `node:http` module passed to it. For instance:
  540. *
  541. * ```js
  542. * 'use strict';
  543. * import vm from 'node:vm';
  544. *
  545. * const code = `
  546. * ((require) => {
  547. * const http = require('node:http');
  548. *
  549. * http.createServer((request, response) => {
  550. * response.writeHead(200, { 'Content-Type': 'text/plain' });
  551. * response.end('Hello World\\n');
  552. * }).listen(8124);
  553. *
  554. * console.log('Server running at http://127.0.0.1:8124/');
  555. * })`;
  556. *
  557. * vm.runInThisContext(code)(require);
  558. * ```
  559. *
  560. * The `require()` in the above case shares the state with the context it is
  561. * passed from. This may introduce risks when untrusted code is executed, e.g.
  562. * altering objects in the context in unwanted ways.
  563. * @since v0.3.1
  564. * @param code The JavaScript code to compile and run.
  565. * @return the result of the very last statement executed in the script.
  566. */
  567. function runInThisContext(code: string, options?: RunningCodeOptions | string): any;
  568. /**
  569. * Compiles the given code into the provided context (if no context is
  570. * supplied, the current context is used), and returns it wrapped inside a
  571. * function with the given `params`.
  572. * @since v10.10.0
  573. * @param code The body of the function to compile.
  574. * @param params An array of strings containing all parameters for the function.
  575. */
  576. function compileFunction(
  577. code: string,
  578. params?: readonly string[],
  579. options?: CompileFunctionOptions,
  580. ): Function & {
  581. cachedData?: Script["cachedData"] | undefined;
  582. cachedDataProduced?: Script["cachedDataProduced"] | undefined;
  583. cachedDataRejected?: Script["cachedDataRejected"] | undefined;
  584. };
  585. /**
  586. * Measure the memory known to V8 and used by all contexts known to the
  587. * current V8 isolate, or the main context.
  588. *
  589. * The format of the object that the returned Promise may resolve with is
  590. * specific to the V8 engine and may change from one version of V8 to the next.
  591. *
  592. * The returned result is different from the statistics returned by `v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the
  593. * memory reachable by each V8 specific contexts in the current instance of
  594. * the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure
  595. * the memory occupied by each heap space in the current V8 instance.
  596. *
  597. * ```js
  598. * import vm from 'node:vm';
  599. * // Measure the memory used by the main context.
  600. * vm.measureMemory({ mode: 'summary' })
  601. * // This is the same as vm.measureMemory()
  602. * .then((result) => {
  603. * // The current format is:
  604. * // {
  605. * // total: {
  606. * // jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
  607. * // }
  608. * // }
  609. * console.log(result);
  610. * });
  611. *
  612. * const context = vm.createContext({ a: 1 });
  613. * vm.measureMemory({ mode: 'detailed', execution: 'eager' })
  614. * .then((result) => {
  615. * // Reference the context here so that it won't be GC'ed
  616. * // until the measurement is complete.
  617. * console.log(context.a);
  618. * // {
  619. * // total: {
  620. * // jsMemoryEstimate: 2574732,
  621. * // jsMemoryRange: [ 2574732, 2904372 ]
  622. * // },
  623. * // current: {
  624. * // jsMemoryEstimate: 2438996,
  625. * // jsMemoryRange: [ 2438996, 2768636 ]
  626. * // },
  627. * // other: [
  628. * // {
  629. * // jsMemoryEstimate: 135736,
  630. * // jsMemoryRange: [ 135736, 465376 ]
  631. * // }
  632. * // ]
  633. * // }
  634. * console.log(result);
  635. * });
  636. * ```
  637. * @since v13.10.0
  638. * @experimental
  639. */
  640. function measureMemory(options?: MeasureMemoryOptions): Promise<MemoryMeasurement>;
  641. interface ModuleEvaluateOptions {
  642. timeout?: RunningScriptOptions["timeout"] | undefined;
  643. breakOnSigint?: RunningScriptOptions["breakOnSigint"] | undefined;
  644. }
  645. type ModuleLinker = (
  646. specifier: string,
  647. referencingModule: Module,
  648. extra: {
  649. attributes: ImportAttributes;
  650. },
  651. ) => Module | Promise<Module>;
  652. type ModuleStatus = "unlinked" | "linking" | "linked" | "evaluating" | "evaluated" | "errored";
  653. /**
  654. * This feature is only available with the `--experimental-vm-modules` command
  655. * flag enabled.
  656. *
  657. * The `vm.Module` class provides a low-level interface for using
  658. * ECMAScript modules in VM contexts. It is the counterpart of the `vm.Script` class that closely mirrors [Module Record](https://262.ecma-international.org/14.0/#sec-abstract-module-records) s as
  659. * defined in the ECMAScript
  660. * specification.
  661. *
  662. * Unlike `vm.Script` however, every `vm.Module` object is bound to a context from
  663. * its creation. Operations on `vm.Module` objects are intrinsically asynchronous,
  664. * in contrast with the synchronous nature of `vm.Script` objects. The use of
  665. * 'async' functions can help with manipulating `vm.Module` objects.
  666. *
  667. * Using a `vm.Module` object requires three distinct steps: creation/parsing,
  668. * linking, and evaluation. These three steps are illustrated in the following
  669. * example.
  670. *
  671. * This implementation lies at a lower level than the `ECMAScript Module
  672. * loader`. There is also no way to interact with the Loader yet, though
  673. * support is planned.
  674. *
  675. * ```js
  676. * import vm from 'node:vm';
  677. *
  678. * const contextifiedObject = vm.createContext({
  679. * secret: 42,
  680. * print: console.log,
  681. * });
  682. *
  683. * // Step 1
  684. * //
  685. * // Create a Module by constructing a new `vm.SourceTextModule` object. This
  686. * // parses the provided source text, throwing a `SyntaxError` if anything goes
  687. * // wrong. By default, a Module is created in the top context. But here, we
  688. * // specify `contextifiedObject` as the context this Module belongs to.
  689. * //
  690. * // Here, we attempt to obtain the default export from the module "foo", and
  691. * // put it into local binding "secret".
  692. *
  693. * const bar = new vm.SourceTextModule(`
  694. * import s from 'foo';
  695. * s;
  696. * print(s);
  697. * `, { context: contextifiedObject });
  698. *
  699. * // Step 2
  700. * //
  701. * // "Link" the imported dependencies of this Module to it.
  702. * //
  703. * // The provided linking callback (the "linker") accepts two arguments: the
  704. * // parent module (`bar` in this case) and the string that is the specifier of
  705. * // the imported module. The callback is expected to return a Module that
  706. * // corresponds to the provided specifier, with certain requirements documented
  707. * // in `module.link()`.
  708. * //
  709. * // If linking has not started for the returned Module, the same linker
  710. * // callback will be called on the returned Module.
  711. * //
  712. * // Even top-level Modules without dependencies must be explicitly linked. The
  713. * // callback provided would never be called, however.
  714. * //
  715. * // The link() method returns a Promise that will be resolved when all the
  716. * // Promises returned by the linker resolve.
  717. * //
  718. * // Note: This is a contrived example in that the linker function creates a new
  719. * // "foo" module every time it is called. In a full-fledged module system, a
  720. * // cache would probably be used to avoid duplicated modules.
  721. *
  722. * async function linker(specifier, referencingModule) {
  723. * if (specifier === 'foo') {
  724. * return new vm.SourceTextModule(`
  725. * // The "secret" variable refers to the global variable we added to
  726. * // "contextifiedObject" when creating the context.
  727. * export default secret;
  728. * `, { context: referencingModule.context });
  729. *
  730. * // Using `contextifiedObject` instead of `referencingModule.context`
  731. * // here would work as well.
  732. * }
  733. * throw new Error(`Unable to resolve dependency: ${specifier}`);
  734. * }
  735. * await bar.link(linker);
  736. *
  737. * // Step 3
  738. * //
  739. * // Evaluate the Module. The evaluate() method returns a promise which will
  740. * // resolve after the module has finished evaluating.
  741. *
  742. * // Prints 42.
  743. * await bar.evaluate();
  744. * ```
  745. * @since v13.0.0, v12.16.0
  746. * @experimental
  747. */
  748. class Module {
  749. /**
  750. * The specifiers of all dependencies of this module. The returned array is frozen
  751. * to disallow any changes to it.
  752. *
  753. * Corresponds to the `[[RequestedModules]]` field of [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records) s in
  754. * the ECMAScript specification.
  755. */
  756. dependencySpecifiers: readonly string[];
  757. /**
  758. * If the `module.status` is `'errored'`, this property contains the exception
  759. * thrown by the module during evaluation. If the status is anything else,
  760. * accessing this property will result in a thrown exception.
  761. *
  762. * The value `undefined` cannot be used for cases where there is not a thrown
  763. * exception due to possible ambiguity with `throw undefined;`.
  764. *
  765. * Corresponds to the `[[EvaluationError]]` field of [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records) s
  766. * in the ECMAScript specification.
  767. */
  768. error: any;
  769. /**
  770. * The identifier of the current module, as set in the constructor.
  771. */
  772. identifier: string;
  773. context: Context;
  774. /**
  775. * The namespace object of the module. This is only available after linking
  776. * (`module.link()`) has completed.
  777. *
  778. * Corresponds to the [GetModuleNamespace](https://tc39.es/ecma262/#sec-getmodulenamespace) abstract operation in the ECMAScript
  779. * specification.
  780. */
  781. namespace: Object;
  782. /**
  783. * The current status of the module. Will be one of:
  784. *
  785. * * `'unlinked'`: `module.link()` has not yet been called.
  786. * * `'linking'`: `module.link()` has been called, but not all Promises returned
  787. * by the linker function have been resolved yet.
  788. * * `'linked'`: The module has been linked successfully, and all of its
  789. * dependencies are linked, but `module.evaluate()` has not yet been called.
  790. * * `'evaluating'`: The module is being evaluated through a `module.evaluate()` on
  791. * itself or a parent module.
  792. * * `'evaluated'`: The module has been successfully evaluated.
  793. * * `'errored'`: The module has been evaluated, but an exception was thrown.
  794. *
  795. * Other than `'errored'`, this status string corresponds to the specification's [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records)'s `[[Status]]` field. `'errored'`
  796. * corresponds to `'evaluated'` in the specification, but with `[[EvaluationError]]` set to a
  797. * value that is not `undefined`.
  798. */
  799. status: ModuleStatus;
  800. /**
  801. * Evaluate the module.
  802. *
  803. * This must be called after the module has been linked; otherwise it will reject.
  804. * It could be called also when the module has already been evaluated, in which
  805. * case it will either do nothing if the initial evaluation ended in success
  806. * (`module.status` is `'evaluated'`) or it will re-throw the exception that the
  807. * initial evaluation resulted in (`module.status` is `'errored'`).
  808. *
  809. * This method cannot be called while the module is being evaluated
  810. * (`module.status` is `'evaluating'`).
  811. *
  812. * Corresponds to the [Evaluate() concrete method](https://tc39.es/ecma262/#sec-moduleevaluation) field of [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records) s in the
  813. * ECMAScript specification.
  814. * @return Fulfills with `undefined` upon success.
  815. */
  816. evaluate(options?: ModuleEvaluateOptions): Promise<void>;
  817. /**
  818. * Link module dependencies. This method must be called before evaluation, and
  819. * can only be called once per module.
  820. *
  821. * The function is expected to return a `Module` object or a `Promise` that
  822. * eventually resolves to a `Module` object. The returned `Module` must satisfy the
  823. * following two invariants:
  824. *
  825. * * It must belong to the same context as the parent `Module`.
  826. * * Its `status` must not be `'errored'`.
  827. *
  828. * If the returned `Module`'s `status` is `'unlinked'`, this method will be
  829. * recursively called on the returned `Module` with the same provided `linker` function.
  830. *
  831. * `link()` returns a `Promise` that will either get resolved when all linking
  832. * instances resolve to a valid `Module`, or rejected if the linker function either
  833. * throws an exception or returns an invalid `Module`.
  834. *
  835. * The linker function roughly corresponds to the implementation-defined [HostResolveImportedModule](https://tc39.es/ecma262/#sec-hostresolveimportedmodule) abstract operation in the
  836. * ECMAScript
  837. * specification, with a few key differences:
  838. *
  839. * * The linker function is allowed to be asynchronous while [HostResolveImportedModule](https://tc39.es/ecma262/#sec-hostresolveimportedmodule) is synchronous.
  840. *
  841. * The actual [HostResolveImportedModule](https://tc39.es/ecma262/#sec-hostresolveimportedmodule) implementation used during module
  842. * linking is one that returns the modules linked during linking. Since at
  843. * that point all modules would have been fully linked already, the [HostResolveImportedModule](https://tc39.es/ecma262/#sec-hostresolveimportedmodule) implementation is fully synchronous per
  844. * specification.
  845. *
  846. * Corresponds to the [Link() concrete method](https://tc39.es/ecma262/#sec-moduledeclarationlinking) field of [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records) s in
  847. * the ECMAScript specification.
  848. */
  849. link(linker: ModuleLinker): Promise<void>;
  850. }
  851. interface SourceTextModuleOptions {
  852. /**
  853. * String used in stack traces.
  854. * @default 'vm:module(i)' where i is a context-specific ascending index.
  855. */
  856. identifier?: string | undefined;
  857. /**
  858. * Provides an optional data with V8's code cache data for the supplied source.
  859. */
  860. cachedData?: ScriptOptions["cachedData"] | undefined;
  861. context?: Context | undefined;
  862. lineOffset?: BaseOptions["lineOffset"] | undefined;
  863. columnOffset?: BaseOptions["columnOffset"] | undefined;
  864. /**
  865. * Called during evaluation of this module to initialize the `import.meta`.
  866. */
  867. initializeImportMeta?: ((meta: ImportMeta, module: SourceTextModule) => void) | undefined;
  868. importModuleDynamically?:
  869. | ((
  870. specifier: string,
  871. referrer: SourceTextModule,
  872. importAttributes: ImportAttributes,
  873. ) => Module | Promise<Module>)
  874. | undefined;
  875. }
  876. /**
  877. * This feature is only available with the `--experimental-vm-modules` command
  878. * flag enabled.
  879. *
  880. * The `vm.SourceTextModule` class provides the [Source Text Module Record](https://tc39.es/ecma262/#sec-source-text-module-records) as
  881. * defined in the ECMAScript specification.
  882. * @since v9.6.0
  883. * @experimental
  884. */
  885. class SourceTextModule extends Module {
  886. /**
  887. * Creates a new `SourceTextModule` instance.
  888. * @param code JavaScript Module code to parse
  889. */
  890. constructor(code: string, options?: SourceTextModuleOptions);
  891. }
  892. interface SyntheticModuleOptions {
  893. /**
  894. * String used in stack traces.
  895. * @default 'vm:module(i)' where i is a context-specific ascending index.
  896. */
  897. identifier?: string | undefined;
  898. /**
  899. * The contextified object as returned by the `vm.createContext()` method, to compile and evaluate this module in.
  900. */
  901. context?: Context | undefined;
  902. }
  903. /**
  904. * This feature is only available with the `--experimental-vm-modules` command
  905. * flag enabled.
  906. *
  907. * The `vm.SyntheticModule` class provides the [Synthetic Module Record](https://heycam.github.io/webidl/#synthetic-module-records) as
  908. * defined in the WebIDL specification. The purpose of synthetic modules is to
  909. * provide a generic interface for exposing non-JavaScript sources to ECMAScript
  910. * module graphs.
  911. *
  912. * ```js
  913. * import vm from 'node:vm';
  914. *
  915. * const source = '{ "a": 1 }';
  916. * const module = new vm.SyntheticModule(['default'], function() {
  917. * const obj = JSON.parse(source);
  918. * this.setExport('default', obj);
  919. * });
  920. *
  921. * // Use `module` in linking...
  922. * ```
  923. * @since v13.0.0, v12.16.0
  924. * @experimental
  925. */
  926. class SyntheticModule extends Module {
  927. /**
  928. * Creates a new `SyntheticModule` instance.
  929. * @param exportNames Array of names that will be exported from the module.
  930. * @param evaluateCallback Called when the module is evaluated.
  931. */
  932. constructor(
  933. exportNames: string[],
  934. evaluateCallback: (this: SyntheticModule) => void,
  935. options?: SyntheticModuleOptions,
  936. );
  937. /**
  938. * This method is used after the module is linked to set the values of exports. If
  939. * it is called before the module is linked, an `ERR_VM_MODULE_STATUS` error
  940. * will be thrown.
  941. *
  942. * ```js
  943. * import vm from 'node:vm';
  944. *
  945. * const m = new vm.SyntheticModule(['x'], () => {
  946. * m.setExport('x', 1);
  947. * });
  948. *
  949. * await m.link(() => {});
  950. * await m.evaluate();
  951. *
  952. * assert.strictEqual(m.namespace.x, 1);
  953. * ```
  954. * @since v13.0.0, v12.16.0
  955. * @param name Name of the export to set.
  956. * @param value The value to set the export to.
  957. */
  958. setExport(name: string, value: any): void;
  959. }
  960. /**
  961. * Returns an object containing commonly used constants for VM operations.
  962. * @since v21.7.0, v20.12.0
  963. */
  964. namespace constants {
  965. /**
  966. * A constant that can be used as the `importModuleDynamically` option to `vm.Script`
  967. * and `vm.compileFunction()` so that Node.js uses the default ESM loader from the main
  968. * context to load the requested module.
  969. *
  970. * For detailed information, see [Support of dynamic `import()` in compilation APIs](https://nodejs.org/docs/latest-v22.x/api/vm.html#support-of-dynamic-import-in-compilation-apis).
  971. * @since v21.7.0, v20.12.0
  972. */
  973. const USE_MAIN_CONTEXT_DEFAULT_LOADER: number;
  974. /**
  975. * This constant, when used as the `contextObject` argument in vm APIs, instructs Node.js to create
  976. * a context without wrapping its global object with another object in a Node.js-specific manner.
  977. * As a result, the `globalThis` value inside the new context would behave more closely to an ordinary
  978. * one.
  979. *
  980. * When `vm.constants.DONT_CONTEXTIFY` is used as the `contextObject` argument to {@link createContext},
  981. * the returned object is a proxy-like object to the global object in the newly created context with
  982. * fewer Node.js-specific quirks. It is reference equal to the `globalThis` value in the new context,
  983. * can be modified from outside the context, and can be used to access built-ins in the new context directly.
  984. * @since v22.8.0
  985. */
  986. const DONT_CONTEXTIFY: number;
  987. }
  988. }
  989. declare module "node:vm" {
  990. export * from "vm";
  991. }