vitest 3.2.0-beta.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE.md +29 -0
  2. package/dist/browser.d.ts +3 -3
  3. package/dist/browser.js +2 -2
  4. package/dist/chunks/{base.DwtwORaC.js → base.Cg0miDlQ.js} +11 -14
  5. package/dist/chunks/{benchmark.BoF7jW0Q.js → benchmark.CYdenmiT.js} +4 -6
  6. package/dist/chunks/{cac.I9MLYfT-.js → cac.6rXCxFY1.js} +76 -143
  7. package/dist/chunks/{cli-api.d6IK1pnk.js → cli-api.Cej3MBjA.js} +1460 -1344
  8. package/dist/chunks/{config.d.UqE-KR0o.d.ts → config.d.D2ROskhv.d.ts} +2 -0
  9. package/dist/chunks/{console.K1NMVOSc.js → console.CtFJOzRO.js} +25 -45
  10. package/dist/chunks/{constants.BZZyIeIE.js → constants.DnKduX2e.js} +1 -0
  11. package/dist/chunks/{coverage.0iPg4Wrz.js → coverage.DVF1vEu8.js} +4 -12
  12. package/dist/chunks/{coverage.OGU09Jbh.js → coverage.EIiagJJP.js} +578 -993
  13. package/dist/chunks/{creator.DGAdZ4Hj.js → creator.GK6I-cL4.js} +39 -83
  14. package/dist/chunks/date.Bq6ZW5rf.js +73 -0
  15. package/dist/chunks/{defaults.DSxsTG0h.js → defaults.B7q_naMc.js} +2 -1
  16. package/dist/chunks/{env.Dq0hM4Xv.js → env.D4Lgay0q.js} +1 -1
  17. package/dist/chunks/{environment.d.D8YDy2v5.d.ts → environment.d.cL3nLXbE.d.ts} +1 -0
  18. package/dist/chunks/{execute.JlGHLJZT.js → execute.B7h3T_Hc.js} +126 -217
  19. package/dist/chunks/{git.DXfdBEfR.js → git.BVQ8w_Sw.js} +1 -3
  20. package/dist/chunks/{global.d.BPa1eL3O.d.ts → global.d.MAmajcmJ.d.ts} +5 -1
  21. package/dist/chunks/{globals.CpxW8ccg.js → globals.DEHgCU4V.js} +7 -6
  22. package/dist/chunks/{index.CV36oG_L.js → index.BZ0g1JD2.js} +430 -625
  23. package/dist/chunks/{index.DswW_LEs.js → index.BbB8_kAK.js} +25 -24
  24. package/dist/chunks/{index.CmC5OK9L.js → index.CIyJn3t1.js} +38 -82
  25. package/dist/chunks/{index.CfXMNXHg.js → index.CdQS2e2Q.js} +4 -2
  26. package/dist/chunks/{index.DFXFpH3w.js → index.CmSc2RE5.js} +85 -105
  27. package/dist/chunks/index.D3XRDfWc.js +213 -0
  28. package/dist/chunks/{inspector.DbDkSkFn.js → inspector.C914Efll.js} +4 -1
  29. package/dist/chunks/{node.3xsWotC9.js → node.fjCdwEIl.js} +1 -1
  30. package/dist/chunks/{reporters.d.CLC9rhKy.d.ts → reporters.d.C1ogPriE.d.ts} +47 -9
  31. package/dist/chunks/{rpc.D9_013TY.js → rpc.Iovn4oWe.js} +10 -19
  32. package/dist/chunks/{runBaseTests.Dn2vyej_.js → runBaseTests.Dd85QTll.js} +27 -31
  33. package/dist/chunks/{setup-common.CYo3Y0dD.js → setup-common.Dd054P77.js} +16 -42
  34. package/dist/chunks/{typechecker.DnTrplSJ.js → typechecker.DRKU1-1g.js} +163 -186
  35. package/dist/chunks/{utils.BfxieIyZ.js → utils.CAioKnHs.js} +9 -14
  36. package/dist/chunks/{utils.CgTj3MsC.js → utils.XdZDrNZV.js} +6 -13
  37. package/dist/chunks/{vi.BFR5YIgu.js → vi.bdSIJ99Y.js} +137 -263
  38. package/dist/chunks/{vite.d.CBZ3M_ru.d.ts → vite.d.DqE4-hhK.d.ts} +3 -1
  39. package/dist/chunks/{vm.C1HHjtNS.js → vm.BThCzidc.js} +164 -212
  40. package/dist/chunks/{worker.d.D5Xdi-Zr.d.ts → worker.d.DvqK5Vmu.d.ts} +1 -1
  41. package/dist/chunks/{worker.d.CoCI7hzP.d.ts → worker.d.tQu2eJQy.d.ts} +5 -3
  42. package/dist/cli.js +5 -5
  43. package/dist/config.cjs +3 -1
  44. package/dist/config.d.ts +7 -6
  45. package/dist/config.js +3 -3
  46. package/dist/coverage.d.ts +4 -4
  47. package/dist/coverage.js +7 -7
  48. package/dist/environments.d.ts +6 -2
  49. package/dist/environments.js +1 -1
  50. package/dist/execute.d.ts +9 -3
  51. package/dist/execute.js +1 -1
  52. package/dist/index.d.ts +28 -15
  53. package/dist/index.js +5 -5
  54. package/dist/node.d.ts +18 -10
  55. package/dist/node.js +17 -17
  56. package/dist/reporters.d.ts +4 -4
  57. package/dist/reporters.js +4 -4
  58. package/dist/runners.d.ts +6 -3
  59. package/dist/runners.js +59 -80
  60. package/dist/snapshot.js +2 -2
  61. package/dist/suite.js +2 -2
  62. package/dist/worker.js +39 -41
  63. package/dist/workers/forks.js +6 -4
  64. package/dist/workers/runVmTests.js +20 -21
  65. package/dist/workers/threads.js +4 -4
  66. package/dist/workers/vmForks.js +6 -6
  67. package/dist/workers/vmThreads.js +6 -6
  68. package/dist/workers.d.ts +4 -4
  69. package/dist/workers.js +10 -10
  70. package/package.json +21 -19
  71. package/dist/chunks/date.CDOsz-HY.js +0 -53
  72. package/dist/chunks/index.CK1YOQaa.js +0 -143
@@ -2,23 +2,21 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
2
2
  import vm, { isContext } from 'node:vm';
3
3
  import { dirname, basename, extname, normalize, join, resolve } from 'pathe';
4
4
  import { distDir } from '../path.js';
5
- import { createCustomConsole } from './console.K1NMVOSc.js';
6
- import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.JlGHLJZT.js';
5
+ import { createCustomConsole } from './console.CtFJOzRO.js';
6
+ import { g as getDefaultRequestStubs, s as startVitestExecutor } from './execute.B7h3T_Hc.js';
7
7
  import fs from 'node:fs';
8
8
  import { dirname as dirname$1 } from 'node:path';
9
9
  import { isPrimitive, isNodeBuiltin, toArray, getCachedData, setCacheData, isBareImport } from 'vite-node/utils';
10
10
  import { createRequire, Module } from 'node:module';
11
11
  import { CSS_LANGS_RE, KNOWN_ASSET_RE } from 'vite-node/constants';
12
- import { p as provideWorkerState } from './utils.CgTj3MsC.js';
12
+ import { p as provideWorkerState } from './utils.XdZDrNZV.js';
13
13
 
14
14
  function interopCommonJsModule(interopDefault, mod) {
15
- if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) {
16
- return {
17
- keys: [],
18
- moduleExports: {},
19
- defaultExport: mod
20
- };
21
- }
15
+ if (isPrimitive(mod) || Array.isArray(mod) || mod instanceof Promise) return {
16
+ keys: [],
17
+ moduleExports: {},
18
+ defaultExport: mod
19
+ };
22
20
  if (interopDefault !== false && "__esModule" in mod && !isPrimitive(mod.default)) {
23
21
  const defaultKets = Object.keys(mod.default);
24
22
  const moduleKeys = Object.keys(mod);
@@ -42,12 +40,12 @@ const SyntheticModule = vm.SyntheticModule;
42
40
  const SourceTextModule = vm.SourceTextModule;
43
41
 
44
42
  const _require = createRequire(import.meta.url);
45
- const requiresCache = new WeakMap();
43
+ const requiresCache = /* @__PURE__ */ new WeakMap();
46
44
  class CommonjsExecutor {
47
45
  context;
48
- requireCache = new Map();
46
+ requireCache = /* @__PURE__ */ new Map();
49
47
  publicRequireCache = this.createProxyCache();
50
- moduleCache = new Map();
48
+ moduleCache = /* @__PURE__ */ new Map();
51
49
  builtinCache = Object.create(null);
52
50
  extensions = Object.create(null);
53
51
  fs;
@@ -58,6 +56,7 @@ class CommonjsExecutor {
58
56
  this.fs = options.fileMap;
59
57
  this.interopDefault = options.interopDefault;
60
58
  const primitives = vm.runInContext("({ Object, Array, Error })", this.context);
59
+ // eslint-disable-next-line ts/no-this-alias
61
60
  const executor = this;
62
61
  this.Module = class Module$1 {
63
62
  exports;
@@ -71,6 +70,7 @@ class CommonjsExecutor {
71
70
  paths = [];
72
71
  constructor(id = "", parent) {
73
72
  this.exports = primitives.Object.create(Object.prototype);
73
+ // in our case the path should always be resolved already
74
74
  this.path = dirname(id);
75
75
  this.id = id;
76
76
  this.filename = id;
@@ -79,9 +79,7 @@ class CommonjsExecutor {
79
79
  }
80
80
  get require() {
81
81
  const require = requiresCache.get(this);
82
- if (require) {
83
- return require;
84
- }
82
+ if (require) return require;
85
83
  const _require = Module$1.createRequire(this.id);
86
84
  requiresCache.set(this, _require);
87
85
  return _require;
@@ -89,12 +87,16 @@ class CommonjsExecutor {
89
87
  static register = () => {
90
88
  throw new Error(`[vitest] "register" is not available when running in Vitest.`);
91
89
  };
90
+ static registerHooks = () => {
91
+ throw new Error(`[vitest] "registerHooks" is not available when running in Vitest.`);
92
+ };
92
93
  _compile(code, filename) {
93
94
  const cjsModule = Module$1.wrap(code);
94
95
  const script = new vm.Script(cjsModule, {
95
96
  filename,
96
97
  importModuleDynamically: options.importModuleDynamically
97
98
  });
99
+ // @ts-expect-error mark script with current identifier
98
100
  script.identifier = filename;
99
101
  const fn = script.runInContext(executor.context);
100
102
  const __dirname = dirname(filename);
@@ -106,6 +108,7 @@ class CommonjsExecutor {
106
108
  this.loaded = true;
107
109
  }
108
110
  }
111
+ // exposed for external use, Node.js does the opposite
109
112
  static _load = (request, parent, _isMain) => {
110
113
  const require = Module$1.createRequire(parent?.filename ?? request);
111
114
  return require(request);
@@ -126,11 +129,17 @@ class CommonjsExecutor {
126
129
  static runMain = () => {
127
130
  throw new primitives.Error("[vitest] \"runMain\" is not implemented.");
128
131
  };
132
+ // @ts-expect-error not typed
129
133
  static _resolveFilename = Module._resolveFilename;
134
+ // @ts-expect-error not typed
130
135
  static _findPath = Module._findPath;
136
+ // @ts-expect-error not typed
131
137
  static _initPaths = Module._initPaths;
138
+ // @ts-expect-error not typed
132
139
  static _preloadModules = Module._preloadModules;
140
+ // @ts-expect-error not typed
133
141
  static _resolveLookupPaths = Module._resolveLookupPaths;
142
+ // @ts-expect-error not typed
134
143
  static globalPaths = Module.globalPaths;
135
144
  static isBuiltin = Module.isBuiltin;
136
145
  static constants = Module.constants;
@@ -157,9 +166,7 @@ class CommonjsExecutor {
157
166
  const require = (id) => {
158
167
  const resolved = _require.resolve(id);
159
168
  const ext = extname(resolved);
160
- if (ext === ".node" || isNodeBuiltin(resolved)) {
161
- return this.requireCoreModule(resolved);
162
- }
169
+ if (ext === ".node" || isNodeBuiltin(resolved)) return this.requireCoreModule(resolved);
163
170
  const module = new this.Module(resolved);
164
171
  return this.loadCommonJSModule(module, resolved);
165
172
  };
@@ -169,7 +176,7 @@ class CommonjsExecutor {
169
176
  set: () => {},
170
177
  configurable: true
171
178
  });
172
- require.main = undefined;
179
+ require.main = void 0;
173
180
  require.cache = this.publicRequireCache;
174
181
  return require;
175
182
  };
@@ -189,11 +196,10 @@ class CommonjsExecutor {
189
196
  }
190
197
  });
191
198
  }
199
+ // very naive implementation for Node.js require
192
200
  loadCommonJSModule(module, filename) {
193
201
  const cached = this.requireCache.get(filename);
194
- if (cached) {
195
- return cached.exports;
196
- }
202
+ if (cached) return cached.exports;
197
203
  const extension = this.findLongestRegisteredExtension(filename);
198
204
  const loader = this.extensions[extension] || this.extensions[".js"];
199
205
  loader(module, filename);
@@ -204,28 +210,21 @@ class CommonjsExecutor {
204
210
  let currentExtension;
205
211
  let index;
206
212
  let startIndex = 0;
213
+ // eslint-disable-next-line no-cond-assign
207
214
  while ((index = name.indexOf(".", startIndex)) !== -1) {
208
215
  startIndex = index + 1;
209
- if (index === 0) {
210
- continue;
211
- }
216
+ if (index === 0) continue;
212
217
  currentExtension = name.slice(index);
213
- if (this.extensions[currentExtension]) {
214
- return currentExtension;
215
- }
218
+ if (this.extensions[currentExtension]) return currentExtension;
216
219
  }
217
220
  return ".js";
218
221
  }
219
222
  getCoreSyntheticModule(identifier) {
220
- if (this.moduleCache.has(identifier)) {
221
- return this.moduleCache.get(identifier);
222
- }
223
+ if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
223
224
  const exports = this.require(identifier);
224
225
  const keys = Object.keys(exports);
225
226
  const module = new SyntheticModule([...keys, "default"], () => {
226
- for (const key of keys) {
227
- module.setExport(key, exports[key]);
228
- }
227
+ for (const key of keys) module.setExport(key, exports[key]);
229
228
  module.setExport("default", exports);
230
229
  }, {
231
230
  context: this.context,
@@ -235,15 +234,12 @@ class CommonjsExecutor {
235
234
  return module;
236
235
  }
237
236
  getCjsSyntheticModule(path, identifier) {
238
- if (this.moduleCache.has(identifier)) {
239
- return this.moduleCache.get(identifier);
240
- }
237
+ if (this.moduleCache.has(identifier)) return this.moduleCache.get(identifier);
241
238
  const exports = this.require(path);
239
+ // TODO: technically module should be parsed to find static exports, implement for strict mode in #2854
242
240
  const { keys, moduleExports, defaultExport } = interopCommonJsModule(this.interopDefault, exports);
243
241
  const module = new SyntheticModule([...keys, "default"], function() {
244
- for (const key of keys) {
245
- this.setExport(key, moduleExports[key]);
246
- }
242
+ for (const key of keys) this.setExport(key, moduleExports[key]);
247
243
  this.setExport("default", defaultExport);
248
244
  }, {
249
245
  context: this.context,
@@ -252,19 +248,51 @@ class CommonjsExecutor {
252
248
  this.moduleCache.set(identifier, module);
253
249
  return module;
254
250
  }
251
+ // TODO: use this in strict mode, when available in #2854
252
+ // private _getNamedCjsExports(path: string): Set<string> {
253
+ // const cachedNamedExports = this.cjsNamedExportsMap.get(path)
254
+ // if (cachedNamedExports) {
255
+ // return cachedNamedExports
256
+ // }
257
+ // if (extname(path) === '.node') {
258
+ // const moduleExports = this.require(path)
259
+ // const namedExports = new Set(Object.keys(moduleExports))
260
+ // this.cjsNamedExportsMap.set(path, namedExports)
261
+ // return namedExports
262
+ // }
263
+ // const code = this.fs.readFile(path)
264
+ // const { exports, reexports } = parseCjs(code, path)
265
+ // const namedExports = new Set(exports)
266
+ // this.cjsNamedExportsMap.set(path, namedExports)
267
+ // for (const reexport of reexports) {
268
+ // if (isNodeBuiltin(reexport)) {
269
+ // const exports = this.require(reexport)
270
+ // if (exports !== null && typeof exports === 'object') {
271
+ // for (const e of Object.keys(exports)) {
272
+ // namedExports.add(e)
273
+ // }
274
+ // }
275
+ // }
276
+ // else {
277
+ // const require = this.createRequire(path)
278
+ // const resolved = require.resolve(reexport)
279
+ // const exports = this._getNamedCjsExports(resolved)
280
+ // for (const e of exports) {
281
+ // namedExports.add(e)
282
+ // }
283
+ // }
284
+ // }
285
+ // return namedExports
286
+ // }
255
287
  require(identifier) {
256
288
  const ext = extname(identifier);
257
- if (ext === ".node" || isNodeBuiltin(identifier)) {
258
- return this.requireCoreModule(identifier);
259
- }
289
+ if (ext === ".node" || isNodeBuiltin(identifier)) return this.requireCoreModule(identifier);
260
290
  const module = new this.Module(identifier);
261
291
  return this.loadCommonJSModule(module, identifier);
262
292
  }
263
293
  requireCoreModule(identifier) {
264
294
  const normalized = identifier.replace(/^node:/, "");
265
- if (this.builtinCache[normalized]) {
266
- return this.builtinCache[normalized].exports;
267
- }
295
+ if (this.builtinCache[normalized]) return this.builtinCache[normalized].exports;
268
296
  const moduleExports = _require(identifier);
269
297
  if (identifier === "node:module" || identifier === "module") {
270
298
  const module = new this.Module("/module.js");
@@ -273,14 +301,15 @@ class CommonjsExecutor {
273
301
  return module.exports;
274
302
  }
275
303
  this.builtinCache[normalized] = _require.cache[normalized];
304
+ // TODO: should we wrap module to rethrow context errors?
276
305
  return moduleExports;
277
306
  }
278
307
  }
279
308
 
280
309
  const dataURIRegex = /^data:(?<mime>text\/javascript|application\/json|application\/wasm)(?:;(?<encoding>charset=utf-8|base64))?,(?<code>.*)$/;
281
310
  class EsmExecutor {
282
- moduleCache = new Map();
283
- esmLinkMap = new WeakMap();
311
+ moduleCache = /* @__PURE__ */ new Map();
312
+ esmLinkMap = /* @__PURE__ */ new WeakMap();
284
313
  context;
285
314
  #httpIp = IPnumber("127.0.0.0");
286
315
  constructor(executor, options) {
@@ -288,26 +317,21 @@ class EsmExecutor {
288
317
  this.context = options.context;
289
318
  }
290
319
  async evaluateModule(m) {
291
- if (m.status === "unlinked") {
292
- this.esmLinkMap.set(m, m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier)));
293
- }
320
+ if (m.status === "unlinked") this.esmLinkMap.set(m, m.link((identifier, referencer) => this.executor.resolveModule(identifier, referencer.identifier)));
294
321
  await this.esmLinkMap.get(m);
295
- if (m.status === "linked") {
296
- await m.evaluate();
297
- }
322
+ if (m.status === "linked") await m.evaluate();
298
323
  return m;
299
324
  }
300
325
  async createEsModule(fileURL, getCode) {
301
326
  const cached = this.moduleCache.get(fileURL);
302
- if (cached) {
303
- return cached;
304
- }
327
+ if (cached) return cached;
305
328
  const promise = this.loadEsModule(fileURL, getCode);
306
329
  this.moduleCache.set(fileURL, promise);
307
330
  return promise;
308
331
  }
309
332
  async loadEsModule(fileURL, getCode) {
310
333
  const code = await getCode();
334
+ // TODO: should not be allowed in strict mode, implement in #2854
311
335
  if (fileURL.endsWith(".json")) {
312
336
  const m = new SyntheticModule(["default"], function() {
313
337
  const result = JSON.parse(code);
@@ -337,53 +361,40 @@ class EsmExecutor {
337
361
  }
338
362
  async createWebAssemblyModule(fileUrl, getCode) {
339
363
  const cached = this.moduleCache.get(fileUrl);
340
- if (cached) {
341
- return cached;
342
- }
364
+ if (cached) return cached;
343
365
  const m = this.loadWebAssemblyModule(getCode(), fileUrl);
344
366
  this.moduleCache.set(fileUrl, m);
345
367
  return m;
346
368
  }
347
369
  async createNetworkModule(fileUrl) {
370
+ // https://nodejs.org/api/esm.html#https-and-http-imports
348
371
  if (fileUrl.startsWith("http:")) {
349
372
  const url = new URL(fileUrl);
350
- if (url.hostname !== "localhost" && url.hostname !== "::1" && (IPnumber(url.hostname) & IPmask(8)) !== this.#httpIp) {
351
- throw new Error(
352
- // we don't know the importer, so it's undefined (the same happens in --pool=threads)
353
- `import of '${fileUrl}' by undefined is not supported: ` + "http can only be used to load local resources (use https instead)."
354
- );
355
- }
373
+ if (url.hostname !== "localhost" && url.hostname !== "::1" && (IPnumber(url.hostname) & IPmask(8)) !== this.#httpIp) throw new Error(
374
+ // we don't know the importer, so it's undefined (the same happens in --pool=threads)
375
+ `import of '${fileUrl}' by undefined is not supported: http can only be used to load local resources (use https instead).`
376
+ );
356
377
  }
357
378
  return this.createEsModule(fileUrl, () => fetch(fileUrl).then((r) => r.text()));
358
379
  }
359
380
  async loadWebAssemblyModule(source, identifier) {
360
381
  const cached = this.moduleCache.get(identifier);
361
- if (cached) {
362
- return cached;
363
- }
382
+ if (cached) return cached;
364
383
  const wasmModule = await WebAssembly.compile(source);
365
384
  const exports = WebAssembly.Module.exports(wasmModule);
366
385
  const imports = WebAssembly.Module.imports(wasmModule);
367
386
  const moduleLookup = {};
368
- for (const { module } of imports) {
369
- if (moduleLookup[module] === undefined) {
370
- moduleLookup[module] = await this.executor.resolveModule(module, identifier);
371
- }
372
- }
387
+ for (const { module } of imports) if (moduleLookup[module] === void 0) moduleLookup[module] = await this.executor.resolveModule(module, identifier);
373
388
  const evaluateModule = (module) => this.evaluateModule(module);
374
389
  const syntheticModule = new SyntheticModule(exports.map(({ name }) => name), async function() {
375
390
  const importsObject = {};
376
391
  for (const { module, name } of imports) {
377
- if (!importsObject[module]) {
378
- importsObject[module] = {};
379
- }
392
+ if (!importsObject[module]) importsObject[module] = {};
380
393
  await evaluateModule(moduleLookup[module]);
381
394
  importsObject[module][name] = moduleLookup[module].namespace[name];
382
395
  }
383
396
  const wasmInstance = new WebAssembly.Instance(wasmModule, importsObject);
384
- for (const { name } of exports) {
385
- this.setExport(name, wasmInstance.exports[name]);
386
- }
397
+ for (const { name } of exports) this.setExport(name, wasmInstance.exports[name]);
387
398
  }, {
388
399
  context: this.context,
389
400
  identifier
@@ -398,34 +409,22 @@ class EsmExecutor {
398
409
  }
399
410
  async createDataModule(identifier) {
400
411
  const cached = this.moduleCache.get(identifier);
401
- if (cached) {
402
- return cached;
403
- }
412
+ if (cached) return cached;
404
413
  const match = identifier.match(dataURIRegex);
405
- if (!match || !match.groups) {
406
- throw new Error("Invalid data URI");
407
- }
414
+ if (!match || !match.groups) throw new Error("Invalid data URI");
408
415
  const mime = match.groups.mime;
409
416
  const encoding = match.groups.encoding;
410
417
  if (mime === "application/wasm") {
411
- if (!encoding) {
412
- throw new Error("Missing data URI encoding");
413
- }
414
- if (encoding !== "base64") {
415
- throw new Error(`Invalid data URI encoding: ${encoding}`);
416
- }
418
+ if (!encoding) throw new Error("Missing data URI encoding");
419
+ if (encoding !== "base64") throw new Error(`Invalid data URI encoding: ${encoding}`);
417
420
  const module = this.loadWebAssemblyModule(Buffer.from(match.groups.code, "base64"), identifier);
418
421
  this.moduleCache.set(identifier, module);
419
422
  return module;
420
423
  }
421
424
  let code = match.groups.code;
422
- if (!encoding || encoding === "charset=utf-8") {
423
- code = decodeURIComponent(code);
424
- } else if (encoding === "base64") {
425
- code = Buffer.from(code, "base64").toString();
426
- } else {
427
- throw new Error(`Invalid data URI encoding: ${encoding}`);
428
- }
425
+ if (!encoding || encoding === "charset=utf-8") code = decodeURIComponent(code);
426
+ else if (encoding === "base64") code = Buffer.from(code, "base64").toString();
427
+ else throw new Error(`Invalid data URI encoding: ${encoding}`);
429
428
  if (mime === "application/json") {
430
429
  const module = new SyntheticModule(["default"], function() {
431
430
  const obj = JSON.parse(code);
@@ -442,9 +441,7 @@ class EsmExecutor {
442
441
  }
443
442
  function IPnumber(address) {
444
443
  const ip = address.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
445
- if (ip) {
446
- return (+ip[1] << 24) + (+ip[2] << 16) + (+ip[3] << 8) + +ip[4];
447
- }
444
+ if (ip) return (+ip[1] << 24) + (+ip[2] << 16) + (+ip[3] << 8) + +ip[4];
448
445
  throw new Error(`Expected IP address, received ${address}`);
449
446
  }
450
447
  function IPmask(maskSize) {
@@ -461,9 +458,7 @@ class ViteExecutor {
461
458
  }
462
459
  resolve = (identifier, parent) => {
463
460
  if (identifier === CLIENT_ID) {
464
- if (this.workerState.environment.transformMode === "web") {
465
- return identifier;
466
- }
461
+ if (this.workerState.environment.transformMode === "web") return identifier;
467
462
  const packageName = this.getPackageName(parent);
468
463
  throw new Error(`[vitest] Vitest cannot handle ${CLIENT_ID} imported in ${parent} when running in SSR environment. Add "${packageName}" to "ssr.noExternal" if you are using Vite SSR, or to "server.deps.inline" if you are using Vite Node.`);
469
464
  }
@@ -474,28 +469,20 @@ class ViteExecutor {
474
469
  getPackageName(modulePath) {
475
470
  const path = normalize(modulePath);
476
471
  let name = path.split("/node_modules/").pop() || "";
477
- if (name?.startsWith("@")) {
478
- name = name.split("/").slice(0, 2).join("/");
479
- } else {
480
- name = name.split("/")[0];
481
- }
472
+ if (name?.startsWith("@")) name = name.split("/").slice(0, 2).join("/");
473
+ else name = name.split("/")[0];
482
474
  return name;
483
475
  }
484
476
  async createViteModule(fileUrl) {
485
- if (fileUrl === CLIENT_FILE) {
486
- return this.createViteClientModule();
487
- }
477
+ if (fileUrl === CLIENT_FILE) return this.createViteClientModule();
488
478
  const cached = this.esm.resolveCachedModule(fileUrl);
489
- if (cached) {
490
- return cached;
491
- }
479
+ if (cached) return cached;
492
480
  return this.esm.createEsModule(fileUrl, async () => {
493
481
  try {
494
482
  const result = await this.options.transform(fileUrl, "web");
495
- if (result.code) {
496
- return result.code;
497
- }
483
+ if (result.code) return result.code;
498
484
  } catch (cause) {
485
+ // rethrow vite error if it cannot load the module because it's not resolved
499
486
  if (typeof cause === "object" && cause.code === "ERR_LOAD_URL" || typeof cause?.message === "string" && cause.message.includes("Failed to load url")) {
500
487
  const error = new Error(`Cannot find module '${fileUrl}'`, { cause });
501
488
  error.code = "ERR_MODULE_NOT_FOUND";
@@ -508,9 +495,7 @@ class ViteExecutor {
508
495
  createViteClientModule() {
509
496
  const identifier = CLIENT_ID;
510
497
  const cached = this.esm.resolveCachedModule(identifier);
511
- if (cached) {
512
- return cached;
513
- }
498
+ if (cached) return cached;
514
499
  const stub = this.options.viteClientModule;
515
500
  const moduleKeys = Object.keys(stub);
516
501
  const module = new SyntheticModule(moduleKeys, function() {
@@ -526,29 +511,21 @@ class ViteExecutor {
526
511
  }
527
512
  canResolve = (fileUrl) => {
528
513
  const transformMode = this.workerState.environment.transformMode;
529
- if (transformMode !== "web") {
530
- return false;
531
- }
532
- if (fileUrl === CLIENT_FILE) {
533
- return true;
534
- }
514
+ if (transformMode !== "web") return false;
515
+ if (fileUrl === CLIENT_FILE) return true;
535
516
  const config = this.workerState.config.deps?.web || {};
536
517
  const [modulePath] = fileUrl.split("?");
537
- if (config.transformCss && CSS_LANGS_RE.test(modulePath)) {
538
- return true;
539
- }
540
- if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath)) {
541
- return true;
542
- }
543
- if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath))) {
544
- return true;
545
- }
518
+ if (config.transformCss && CSS_LANGS_RE.test(modulePath)) return true;
519
+ if (config.transformAssets && KNOWN_ASSET_RE.test(modulePath)) return true;
520
+ if (toArray(config.transformGlobPattern).some((pattern) => pattern.test(modulePath))) return true;
546
521
  return false;
547
522
  };
548
523
  }
549
524
 
550
525
  const { existsSync, statSync } = fs;
526
+ // always defined when we use vm pool
551
527
  const nativeResolve = import.meta.resolve;
528
+ // TODO: improve Node.js strict mode support in #2854
552
529
  class ExternalModulesExecutor {
553
530
  cjs;
554
531
  esm;
@@ -587,24 +564,22 @@ class ExternalModulesExecutor {
587
564
  createRequire(identifier) {
588
565
  return this.cjs.createRequire(identifier);
589
566
  }
567
+ // dynamic import can be used in both ESM and CJS, so we have it in the executor
590
568
  importModuleDynamically = async (specifier, referencer) => {
591
569
  const module = await this.resolveModule(specifier, referencer.identifier);
592
570
  return await this.esm.evaluateModule(module);
593
571
  };
594
572
  resolveModule = async (specifier, referencer) => {
595
573
  let identifier = this.resolve(specifier, referencer);
596
- if (identifier instanceof Promise) {
597
- identifier = await identifier;
598
- }
574
+ if (identifier instanceof Promise) identifier = await identifier;
599
575
  return await this.createModule(identifier);
600
576
  };
601
577
  resolve(specifier, parent) {
602
578
  for (const resolver of this.resolvers) {
603
579
  const id = resolver(specifier, parent);
604
- if (id) {
605
- return id;
606
- }
580
+ if (id) return id;
607
581
  }
582
+ // import.meta.resolve can be asynchronous in older +18 Node versions
608
583
  return nativeResolve(specifier, parent);
609
584
  }
610
585
  findNearestPackageData(basedir) {
@@ -612,63 +587,50 @@ class ExternalModulesExecutor {
612
587
  const packageCache = this.options.packageCache;
613
588
  while (basedir) {
614
589
  const cached = getCachedData(packageCache, basedir, originalBasedir);
615
- if (cached) {
616
- return cached;
617
- }
590
+ if (cached) return cached;
618
591
  const pkgPath = join(basedir, "package.json");
619
592
  try {
620
593
  if (statSync(pkgPath, { throwIfNoEntry: false })?.isFile()) {
621
594
  const pkgData = JSON.parse(this.fs.readFile(pkgPath));
622
- if (packageCache) {
623
- setCacheData(packageCache, pkgData, basedir, originalBasedir);
624
- }
595
+ if (packageCache) setCacheData(packageCache, pkgData, basedir, originalBasedir);
625
596
  return pkgData;
626
597
  }
627
598
  } catch {}
628
599
  const nextBasedir = dirname$1(basedir);
629
- if (nextBasedir === basedir) {
630
- break;
631
- }
600
+ if (nextBasedir === basedir) break;
632
601
  basedir = nextBasedir;
633
602
  }
634
603
  return {};
635
604
  }
636
605
  getModuleInformation(identifier) {
637
- if (identifier.startsWith("data:")) {
638
- return {
639
- type: "data",
640
- url: identifier,
641
- path: identifier
642
- };
643
- }
606
+ if (identifier.startsWith("data:")) return {
607
+ type: "data",
608
+ url: identifier,
609
+ path: identifier
610
+ };
644
611
  const extension = extname(identifier);
645
- if (extension === ".node" || isNodeBuiltin(identifier)) {
646
- return {
647
- type: "builtin",
648
- url: identifier,
649
- path: identifier
650
- };
651
- }
652
- if (this.isNetworkSupported && (identifier.startsWith("http:") || identifier.startsWith("https:"))) {
653
- return {
654
- type: "network",
655
- url: identifier,
656
- path: identifier
657
- };
658
- }
612
+ if (extension === ".node" || isNodeBuiltin(identifier)) return {
613
+ type: "builtin",
614
+ url: identifier,
615
+ path: identifier
616
+ };
617
+ if (this.isNetworkSupported && (identifier.startsWith("http:") || identifier.startsWith("https:"))) return {
618
+ type: "network",
619
+ url: identifier,
620
+ path: identifier
621
+ };
659
622
  const isFileUrl = identifier.startsWith("file://");
660
623
  const pathUrl = isFileUrl ? fileURLToPath(identifier.split("?")[0]) : identifier;
661
624
  const fileUrl = isFileUrl ? identifier : pathToFileURL(pathUrl).toString();
662
625
  let type;
663
- if (this.vite.canResolve(fileUrl)) {
664
- type = "vite";
665
- } else if (extension === ".mjs") {
666
- type = "module";
667
- } else if (extension === ".cjs") {
668
- type = "commonjs";
669
- } else if (extension === ".wasm") {
670
- type = "wasm";
671
- } else {
626
+ if (this.vite.canResolve(fileUrl)) type = "vite";
627
+ else if (extension === ".mjs") type = "module";
628
+ else if (extension === ".cjs") type = "commonjs";
629
+ else if (extension === ".wasm")
630
+ // still experimental on NodeJS --experimental-wasm-modules
631
+ // cf. ESM_FILE_FORMAT(url) in https://nodejs.org/docs/latest-v20.x/api/esm.html#resolution-algorithm
632
+ type = "wasm";
633
+ else {
672
634
  const pkgData = this.findNearestPackageData(normalize(pathUrl));
673
635
  type = pkgData.type === "module" ? "module" : "commonjs";
674
636
  }
@@ -680,6 +642,8 @@ class ExternalModulesExecutor {
680
642
  }
681
643
  createModule(identifier) {
682
644
  const { type, url, path } = this.getModuleInformation(identifier);
645
+ // create ERR_MODULE_NOT_FOUND on our own since latest NodeJS's import.meta.resolve doesn't throw on non-existing namespace or path
646
+ // https://github.com/nodejs/node/pull/49038
683
647
  if ((type === "module" || type === "commonjs" || type === "wasm") && !existsSync(path)) {
684
648
  const error = new Error(`Cannot find ${isBareImport(path) ? "package" : "module"} '${path}'`);
685
649
  error.code = "ERR_MODULE_NOT_FOUND";
@@ -700,46 +664,34 @@ class ExternalModulesExecutor {
700
664
  }
701
665
  }
702
666
  get isNetworkSupported() {
703
- if (this.#networkSupported == null) {
704
- if (process.execArgv.includes("--experimental-network-imports")) {
705
- this.#networkSupported = true;
706
- } else if (process.env.NODE_OPTIONS?.includes("--experimental-network-imports")) {
707
- this.#networkSupported = true;
708
- } else {
709
- this.#networkSupported = false;
710
- }
711
- }
667
+ if (this.#networkSupported == null) if (process.execArgv.includes("--experimental-network-imports")) this.#networkSupported = true;
668
+ else if (process.env.NODE_OPTIONS?.includes("--experimental-network-imports")) this.#networkSupported = true;
669
+ else this.#networkSupported = false;
712
670
  return this.#networkSupported;
713
671
  }
714
672
  }
715
673
 
716
674
  const { promises, readFileSync } = fs;
717
675
  class FileMap {
718
- fsCache = new Map();
719
- fsBufferCache = new Map();
676
+ fsCache = /* @__PURE__ */ new Map();
677
+ fsBufferCache = /* @__PURE__ */ new Map();
720
678
  async readFileAsync(path) {
721
679
  const cached = this.fsCache.get(path);
722
- if (cached != null) {
723
- return cached;
724
- }
680
+ if (cached != null) return cached;
725
681
  const source = await promises.readFile(path, "utf-8");
726
682
  this.fsCache.set(path, source);
727
683
  return source;
728
684
  }
729
685
  readFile(path) {
730
686
  const cached = this.fsCache.get(path);
731
- if (cached != null) {
732
- return cached;
733
- }
687
+ if (cached != null) return cached;
734
688
  const source = readFileSync(path, "utf-8");
735
689
  this.fsCache.set(path, source);
736
690
  return source;
737
691
  }
738
692
  readBuffer(path) {
739
693
  const cached = this.fsBufferCache.get(path);
740
- if (cached != null) {
741
- return cached;
742
- }
694
+ if (cached != null) return cached;
743
695
  const buffer = readFileSync(path);
744
696
  this.fsBufferCache.set(path, buffer);
745
697
  return buffer;
@@ -748,28 +700,28 @@ class FileMap {
748
700
 
749
701
  const entryFile = pathToFileURL(resolve(distDir, "workers/runVmTests.js")).href;
750
702
  const fileMap = new FileMap();
751
- const packageCache = new Map();
703
+ const packageCache = /* @__PURE__ */ new Map();
752
704
  async function runVmTests(method, state) {
753
705
  const { environment, ctx, rpc } = state;
754
706
  if (!environment.setupVM) {
755
707
  const envName = ctx.environment.name;
756
708
  const packageId = envName[0] === "." ? envName : `vitest-environment-${envName}`;
757
- throw new TypeError(`Environment "${ctx.environment.name}" is not a valid environment. ` + `Path "${packageId}" doesn't support vm environment because it doesn't provide "setupVM" method.`);
709
+ throw new TypeError(`Environment "${ctx.environment.name}" is not a valid environment. Path "${packageId}" doesn't support vm environment because it doesn't provide "setupVM" method.`);
758
710
  }
759
711
  const vm = await environment.setupVM(ctx.environment.options || ctx.config.environmentOptions || {});
760
712
  state.durations.environment = performance.now() - state.durations.environment;
761
713
  process.env.VITEST_VM_POOL = "1";
762
- if (!vm.getVmContext) {
763
- throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
764
- }
714
+ if (!vm.getVmContext) throw new TypeError(`Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`);
765
715
  const context = vm.getVmContext();
766
- if (!isContext(context)) {
767
- throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`);
768
- }
716
+ if (!isContext(context)) throw new TypeError(`Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`);
769
717
  provideWorkerState(context, state);
718
+ // this is unfortunately needed for our own dependencies
719
+ // we need to find a way to not rely on this by default
720
+ // because browser doesn't provide these globals
770
721
  context.process = process;
771
722
  context.global = context;
772
723
  context.console = state.config.disableConsoleIntercept ? console : createCustomConsole(state);
724
+ // TODO: don't hardcode setImmediate in fake timers defaults
773
725
  context.setImmediate = setImmediate;
774
726
  context.clearImmediate = clearImmediate;
775
727
  const stubs = getDefaultRequestStubs(context);
@@ -791,7 +743,7 @@ async function runVmTests(method, state) {
791
743
  const { run } = await executor.importExternalModule(entryFile);
792
744
  const fileSpecs = ctx.files.map((f) => typeof f === "string" ? {
793
745
  filepath: f,
794
- testLocations: undefined
746
+ testLocations: void 0
795
747
  } : f);
796
748
  try {
797
749
  await run(method, fileSpecs, ctx.config, executor);