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
@@ -1,5 +1,6 @@
1
1
  import { Console } from 'node:console';
2
2
 
3
+ // SEE https://github.com/jsdom/jsdom/blob/master/lib/jsdom/living/interfaces.js
3
4
  const LIVING_KEYS = [
4
5
  "DOMException",
5
6
  "URL",
@@ -245,12 +246,8 @@ const skipKeys = [
245
246
  function getWindowKeys(global, win, additionalKeys = []) {
246
247
  const keysArray = [...additionalKeys, ...KEYS];
247
248
  const keys = new Set(keysArray.concat(Object.getOwnPropertyNames(win)).filter((k) => {
248
- if (skipKeys.includes(k)) {
249
- return false;
250
- }
251
- if (k in global) {
252
- return keysArray.includes(k);
253
- }
249
+ if (skipKeys.includes(k)) return false;
250
+ if (k in global) return keysArray.includes(k);
254
251
  return true;
255
252
  }));
256
253
  return keys;
@@ -261,21 +258,15 @@ function isClassLikeName(name) {
261
258
  function populateGlobal(global, win, options = {}) {
262
259
  const { bindFunctions = false } = options;
263
260
  const keys = getWindowKeys(global, win, options.additionalKeys);
264
- const originals = new Map();
265
- const overrideObject = new Map();
261
+ const originals = /* @__PURE__ */ new Map();
262
+ const overrideObject = /* @__PURE__ */ new Map();
266
263
  for (const key of keys) {
267
264
  const boundFunction = bindFunctions && typeof win[key] === "function" && !isClassLikeName(key) && win[key].bind(win);
268
- if (KEYS.includes(key) && key in global) {
269
- originals.set(key, global[key]);
270
- }
265
+ if (KEYS.includes(key) && key in global) originals.set(key, global[key]);
271
266
  Object.defineProperty(global, key, {
272
267
  get() {
273
- if (overrideObject.has(key)) {
274
- return overrideObject.get(key);
275
- }
276
- if (boundFunction) {
277
- return boundFunction;
278
- }
268
+ if (overrideObject.has(key)) return overrideObject.get(key);
269
+ if (boundFunction) return boundFunction;
279
270
  return win[key];
280
271
  },
281
272
  set(v) {
@@ -288,16 +279,13 @@ function populateGlobal(global, win, options = {}) {
288
279
  global.self = global;
289
280
  global.top = global;
290
281
  global.parent = global;
291
- if (global.global) {
292
- global.global = global;
293
- }
294
- if (global.document && global.document.defaultView) {
295
- Object.defineProperty(global.document, "defaultView", {
296
- get: () => global,
297
- enumerable: true,
298
- configurable: true
299
- });
300
- }
282
+ if (global.global) global.global = global;
283
+ // rewrite defaultView to reference the same global context
284
+ if (global.document && global.document.defaultView) Object.defineProperty(global.document, "defaultView", {
285
+ get: () => global,
286
+ enumerable: true,
287
+ configurable: true
288
+ });
301
289
  skipKeys.forEach((k) => keys.add(k));
302
290
  return {
303
291
  keys,
@@ -320,7 +308,9 @@ var edge = {
320
308
  getVmContext() {
321
309
  return vm.context;
322
310
  },
323
- teardown() {}
311
+ teardown() {
312
+ // nothing to teardown
313
+ }
324
314
  };
325
315
  },
326
316
  async setup(global) {
@@ -329,9 +319,7 @@ var edge = {
329
319
  context.global = context;
330
320
  context.Buffer = Buffer;
331
321
  KEYS.forEach((key) => {
332
- if (key in global) {
333
- context[key] = global[key];
334
- }
322
+ if (key in global) context[key] = global[key];
335
323
  });
336
324
  return context;
337
325
  } });
@@ -347,9 +335,7 @@ async function teardownWindow(win) {
347
335
  if (win.close && win.happyDOM.abort) {
348
336
  await win.happyDOM.abort();
349
337
  win.close();
350
- } else {
351
- win.happyDOM.cancelAsync();
352
- }
338
+ } else win.happyDOM.cancelAsync();
353
339
  }
354
340
  var happy = {
355
341
  name: "happy-dom",
@@ -358,32 +344,34 @@ var happy = {
358
344
  const { Window } = await import('happy-dom');
359
345
  let win = new Window({
360
346
  ...happyDOM,
361
- console: console && globalThis.console ? globalThis.console : undefined,
347
+ console: console && globalThis.console ? globalThis.console : void 0,
362
348
  url: happyDOM.url || "http://localhost:3000",
363
349
  settings: {
364
350
  ...happyDOM.settings,
365
351
  disableErrorCapturing: true
366
352
  }
367
353
  });
354
+ // TODO: browser doesn't expose Buffer, but a lot of dependencies use it
368
355
  win.Buffer = Buffer;
369
- if (typeof structuredClone !== "undefined" && !win.structuredClone) {
370
- win.structuredClone = structuredClone;
371
- }
356
+ // inject structuredClone if it exists
357
+ if (typeof structuredClone !== "undefined" && !win.structuredClone) win.structuredClone = structuredClone;
372
358
  return {
373
359
  getVmContext() {
374
360
  return win;
375
361
  },
376
362
  async teardown() {
377
363
  await teardownWindow(win);
378
- win = undefined;
364
+ win = void 0;
379
365
  }
380
366
  };
381
367
  },
382
368
  async setup(global, { happyDOM = {} }) {
369
+ // happy-dom v3 introduced a breaking change to Window, but
370
+ // provides GlobalWindow as a way to use previous behaviour
383
371
  const { Window, GlobalWindow } = await import('happy-dom');
384
372
  const win = new (GlobalWindow || Window)({
385
373
  ...happyDOM,
386
- console: console && global.console ? global.console : undefined,
374
+ console: console && global.console ? global.console : void 0,
387
375
  url: happyDOM.url || "http://localhost:3000",
388
376
  settings: {
389
377
  ...happyDOM.settings,
@@ -410,23 +398,17 @@ var happy = {
410
398
  function catchWindowErrors(window) {
411
399
  let userErrorListenerCount = 0;
412
400
  function throwUnhandlerError(e) {
413
- if (userErrorListenerCount === 0 && e.error != null) {
414
- process.emit("uncaughtException", e.error);
415
- }
401
+ if (userErrorListenerCount === 0 && e.error != null) process.emit("uncaughtException", e.error);
416
402
  }
417
403
  const addEventListener = window.addEventListener.bind(window);
418
404
  const removeEventListener = window.removeEventListener.bind(window);
419
405
  window.addEventListener("error", throwUnhandlerError);
420
406
  window.addEventListener = function(...args) {
421
- if (args[0] === "error") {
422
- userErrorListenerCount++;
423
- }
407
+ if (args[0] === "error") userErrorListenerCount++;
424
408
  return addEventListener.apply(this, args);
425
409
  };
426
410
  window.removeEventListener = function(...args) {
427
- if (args[0] === "error" && userErrorListenerCount) {
428
- userErrorListenerCount--;
429
- }
411
+ if (args[0] === "error" && userErrorListenerCount) userErrorListenerCount--;
430
412
  return removeEventListener.apply(this, args);
431
413
  };
432
414
  return function clearErrorHandlers() {
@@ -441,19 +423,22 @@ var jsdom = {
441
423
  const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
442
424
  let dom = new JSDOM(html, {
443
425
  pretendToBeVisual,
444
- resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : undefined),
426
+ resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
445
427
  runScripts,
446
428
  url,
447
- virtualConsole: console && globalThis.console ? new VirtualConsole().sendTo(globalThis.console) : undefined,
448
- cookieJar: cookieJar ? new CookieJar() : undefined,
429
+ virtualConsole: console && globalThis.console ? new VirtualConsole().sendTo(globalThis.console) : void 0,
430
+ cookieJar: cookieJar ? new CookieJar() : void 0,
449
431
  includeNodeLocations,
450
432
  contentType,
451
433
  userAgent,
452
434
  ...restOptions
453
435
  });
454
436
  const clearWindowErrors = catchWindowErrors(dom.window);
437
+ // TODO: browser doesn't expose Buffer, but a lot of dependencies use it
455
438
  dom.window.Buffer = Buffer;
456
439
  dom.window.jsdom = dom;
440
+ // inject web globals if they missing in JSDOM but otherwise available in Nodejs
441
+ // https://nodejs.org/dist/latest/docs/api/globals.html
457
442
  const globalNames = [
458
443
  "structuredClone",
459
444
  "fetch",
@@ -467,9 +452,7 @@ var jsdom = {
467
452
  ];
468
453
  for (const name of globalNames) {
469
454
  const value = globalThis[name];
470
- if (typeof value !== "undefined" && typeof dom.window[name] === "undefined") {
471
- dom.window[name] = value;
472
- }
455
+ if (typeof value !== "undefined" && typeof dom.window[name] === "undefined") dom.window[name] = value;
473
456
  }
474
457
  return {
475
458
  getVmContext() {
@@ -478,7 +461,7 @@ var jsdom = {
478
461
  teardown() {
479
462
  clearWindowErrors();
480
463
  dom.window.close();
481
- dom = undefined;
464
+ dom = void 0;
482
465
  }
483
466
  };
484
467
  },
@@ -487,11 +470,11 @@ var jsdom = {
487
470
  const { html = "<!DOCTYPE html>", userAgent, url = "http://localhost:3000", contentType = "text/html", pretendToBeVisual = true, includeNodeLocations = false, runScripts = "dangerously", resources, console = false, cookieJar = false,...restOptions } = jsdom;
488
471
  const dom = new JSDOM(html, {
489
472
  pretendToBeVisual,
490
- resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : undefined),
473
+ resources: resources ?? (userAgent ? new ResourceLoader({ userAgent }) : void 0),
491
474
  runScripts,
492
475
  url,
493
- virtualConsole: console && global.console ? new VirtualConsole().sendTo(global.console) : undefined,
494
- cookieJar: cookieJar ? new CookieJar() : undefined,
476
+ virtualConsole: console && global.console ? new VirtualConsole().sendTo(global.console) : void 0,
477
+ cookieJar: cookieJar ? new CookieJar() : void 0,
495
478
  includeNodeLocations,
496
479
  contentType,
497
480
  userAgent,
@@ -510,6 +493,7 @@ var jsdom = {
510
493
  }
511
494
  };
512
495
 
496
+ // some globals we do not want, either because deprecated or we set it ourselves
513
497
  const denyList = new Set([
514
498
  "GLOBAL",
515
499
  "root",
@@ -520,9 +504,7 @@ const denyList = new Set([
520
504
  ]);
521
505
  const nodeGlobals = new Map(Object.getOwnPropertyNames(globalThis).filter((global) => !denyList.has(global)).map((nodeGlobalsKey) => {
522
506
  const descriptor = Object.getOwnPropertyDescriptor(globalThis, nodeGlobalsKey);
523
- if (!descriptor) {
524
- throw new Error(`No property descriptor for ${nodeGlobalsKey}, this is a bug in Vitest.`);
525
- }
507
+ if (!descriptor) throw new Error(`No property descriptor for ${nodeGlobalsKey}, this is a bug in Vitest.`);
526
508
  return [nodeGlobalsKey, descriptor];
527
509
  }));
528
510
  var node = {
@@ -533,59 +515,57 @@ var node = {
533
515
  let context = vm.createContext();
534
516
  let global = vm.runInContext("this", context);
535
517
  const contextGlobals = new Set(Object.getOwnPropertyNames(global));
536
- for (const [nodeGlobalsKey, descriptor] of nodeGlobals) {
537
- if (!contextGlobals.has(nodeGlobalsKey)) {
538
- if (descriptor.configurable) {
539
- Object.defineProperty(global, nodeGlobalsKey, {
540
- configurable: true,
541
- enumerable: descriptor.enumerable,
542
- get() {
543
- const val = globalThis[nodeGlobalsKey];
544
- Object.defineProperty(global, nodeGlobalsKey, {
545
- configurable: true,
546
- enumerable: descriptor.enumerable,
547
- value: val,
548
- writable: descriptor.writable === true || nodeGlobalsKey === "performance"
549
- });
550
- return val;
551
- },
552
- set(val) {
553
- Object.defineProperty(global, nodeGlobalsKey, {
554
- configurable: true,
555
- enumerable: descriptor.enumerable,
556
- value: val,
557
- writable: true
558
- });
559
- }
560
- });
561
- } else if ("value" in descriptor) {
562
- Object.defineProperty(global, nodeGlobalsKey, {
563
- configurable: false,
564
- enumerable: descriptor.enumerable,
565
- value: descriptor.value,
566
- writable: descriptor.writable
567
- });
568
- } else {
569
- Object.defineProperty(global, nodeGlobalsKey, {
570
- configurable: false,
571
- enumerable: descriptor.enumerable,
572
- get: descriptor.get,
573
- set: descriptor.set
574
- });
575
- }
518
+ for (const [nodeGlobalsKey, descriptor] of nodeGlobals) if (!contextGlobals.has(nodeGlobalsKey)) if (descriptor.configurable) Object.defineProperty(global, nodeGlobalsKey, {
519
+ configurable: true,
520
+ enumerable: descriptor.enumerable,
521
+ get() {
522
+ // @ts-expect-error: no index signature
523
+ const val = globalThis[nodeGlobalsKey];
524
+ // override lazy getter
525
+ Object.defineProperty(global, nodeGlobalsKey, {
526
+ configurable: true,
527
+ enumerable: descriptor.enumerable,
528
+ value: val,
529
+ writable: descriptor.writable === true || nodeGlobalsKey === "performance"
530
+ });
531
+ return val;
532
+ },
533
+ set(val) {
534
+ // override lazy getter
535
+ Object.defineProperty(global, nodeGlobalsKey, {
536
+ configurable: true,
537
+ enumerable: descriptor.enumerable,
538
+ value: val,
539
+ writable: true
540
+ });
576
541
  }
577
- }
542
+ });
543
+ else if ("value" in descriptor) Object.defineProperty(global, nodeGlobalsKey, {
544
+ configurable: false,
545
+ enumerable: descriptor.enumerable,
546
+ value: descriptor.value,
547
+ writable: descriptor.writable
548
+ });
549
+ else Object.defineProperty(global, nodeGlobalsKey, {
550
+ configurable: false,
551
+ enumerable: descriptor.enumerable,
552
+ get: descriptor.get,
553
+ set: descriptor.set
554
+ });
578
555
  global.global = global;
579
556
  global.Buffer = Buffer;
580
557
  global.ArrayBuffer = ArrayBuffer;
558
+ // TextEncoder (global or via 'util') references a Uint8Array constructor
559
+ // different than the global one used by users in tests. This makes sure the
560
+ // same constructor is referenced by both.
581
561
  global.Uint8Array = Uint8Array;
582
562
  return {
583
563
  getVmContext() {
584
564
  return context;
585
565
  },
586
566
  teardown() {
587
- context = undefined;
588
- global = undefined;
567
+ context = void 0;
568
+ global = void 0;
589
569
  }
590
570
  };
591
571
  },
@@ -0,0 +1,213 @@
1
+ import process from 'node:process';
2
+ import fs from 'node:fs/promises';
3
+ import path, { resolve } from 'node:path';
4
+ import { existsSync } from 'node:fs';
5
+ import { x } from 'tinyexec';
6
+
7
+ const AGENTS = [
8
+ "npm",
9
+ "yarn",
10
+ "yarn@berry",
11
+ "pnpm",
12
+ "pnpm@6",
13
+ "bun",
14
+ "deno"
15
+ ];
16
+ const LOCKS = {
17
+ "bun.lock": "bun",
18
+ "bun.lockb": "bun",
19
+ "deno.lock": "deno",
20
+ "pnpm-lock.yaml": "pnpm",
21
+ "pnpm-workspace.yaml": "pnpm",
22
+ "yarn.lock": "yarn",
23
+ "package-lock.json": "npm",
24
+ "npm-shrinkwrap.json": "npm"
25
+ };
26
+ const INSTALL_METADATA = {
27
+ "node_modules/.deno/": "deno",
28
+ "node_modules/.pnpm/": "pnpm",
29
+ "node_modules/.yarn-state.yml": "yarn",
30
+ // yarn v2+ (node-modules)
31
+ "node_modules/.yarn_integrity": "yarn",
32
+ // yarn v1
33
+ "node_modules/.package-lock.json": "npm",
34
+ ".pnp.cjs": "yarn",
35
+ // yarn v3+ (pnp)
36
+ ".pnp.js": "yarn",
37
+ // yarn v2 (pnp)
38
+ "bun.lock": "bun",
39
+ "bun.lockb": "bun"
40
+ };
41
+
42
+ async function pathExists(path2, type) {
43
+ try {
44
+ const stat = await fs.stat(path2);
45
+ return type === "file" ? stat.isFile() : stat.isDirectory();
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+ function* lookup(cwd = process.cwd()) {
51
+ let directory = path.resolve(cwd);
52
+ const { root } = path.parse(directory);
53
+ while (directory && directory !== root) {
54
+ yield directory;
55
+ directory = path.dirname(directory);
56
+ }
57
+ }
58
+ async function parsePackageJson(filepath, onUnknown) {
59
+ return !filepath || !pathExists(filepath, "file") ? null : await handlePackageManager(filepath, onUnknown);
60
+ }
61
+ async function detect(options = {}) {
62
+ const {
63
+ cwd,
64
+ strategies = ["lockfile", "packageManager-field", "devEngines-field"],
65
+ onUnknown
66
+ } = options;
67
+ let stopDir;
68
+ if (typeof options.stopDir === "string") {
69
+ const resolved = path.resolve(options.stopDir);
70
+ stopDir = (dir) => dir === resolved;
71
+ } else {
72
+ stopDir = options.stopDir;
73
+ }
74
+ for (const directory of lookup(cwd)) {
75
+ for (const strategy of strategies) {
76
+ switch (strategy) {
77
+ case "lockfile": {
78
+ for (const lock of Object.keys(LOCKS)) {
79
+ if (await pathExists(path.join(directory, lock), "file")) {
80
+ const name = LOCKS[lock];
81
+ const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown);
82
+ if (result)
83
+ return result;
84
+ else
85
+ return { name, agent: name };
86
+ }
87
+ }
88
+ break;
89
+ }
90
+ case "packageManager-field":
91
+ case "devEngines-field": {
92
+ const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown);
93
+ if (result)
94
+ return result;
95
+ break;
96
+ }
97
+ case "install-metadata": {
98
+ for (const metadata of Object.keys(INSTALL_METADATA)) {
99
+ const fileOrDir = metadata.endsWith("/") ? "dir" : "file";
100
+ if (await pathExists(path.join(directory, metadata), fileOrDir)) {
101
+ const name = INSTALL_METADATA[metadata];
102
+ const agent = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name;
103
+ return { name, agent };
104
+ }
105
+ }
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ if (stopDir?.(directory))
111
+ break;
112
+ }
113
+ return null;
114
+ }
115
+ function getNameAndVer(pkg) {
116
+ const handelVer = (version) => version?.match(/\d+(\.\d+){0,2}/)?.[0] ?? version;
117
+ if (typeof pkg.packageManager === "string") {
118
+ const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@");
119
+ return { name, ver: handelVer(ver) };
120
+ }
121
+ if (typeof pkg.devEngines?.packageManager?.name === "string") {
122
+ return {
123
+ name: pkg.devEngines.packageManager.name,
124
+ ver: handelVer(pkg.devEngines.packageManager.version)
125
+ };
126
+ }
127
+ return void 0;
128
+ }
129
+ async function handlePackageManager(filepath, onUnknown) {
130
+ try {
131
+ const pkg = JSON.parse(await fs.readFile(filepath, "utf8"));
132
+ let agent;
133
+ const nameAndVer = getNameAndVer(pkg);
134
+ if (nameAndVer) {
135
+ const name = nameAndVer.name;
136
+ const ver = nameAndVer.ver;
137
+ let version = ver;
138
+ if (name === "yarn" && ver && Number.parseInt(ver) > 1) {
139
+ agent = "yarn@berry";
140
+ version = "berry";
141
+ return { name, agent, version };
142
+ } else if (name === "pnpm" && ver && Number.parseInt(ver) < 7) {
143
+ agent = "pnpm@6";
144
+ return { name, agent, version };
145
+ } else if (AGENTS.includes(name)) {
146
+ agent = name;
147
+ return { name, agent, version };
148
+ } else {
149
+ return onUnknown?.(pkg.packageManager) ?? null;
150
+ }
151
+ }
152
+ } catch {
153
+ }
154
+ return null;
155
+ }
156
+ function isMetadataYarnClassic(metadataPath) {
157
+ return metadataPath.endsWith(".yarn_integrity");
158
+ }
159
+
160
+ // src/detect.ts
161
+ async function detectPackageManager(cwd = process.cwd()) {
162
+ const result = await detect({
163
+ cwd,
164
+ onUnknown(packageManager) {
165
+ console.warn("[@antfu/install-pkg] Unknown packageManager:", packageManager);
166
+ return void 0;
167
+ }
168
+ });
169
+ return result?.agent || null;
170
+ }
171
+ async function installPackage(names, options = {}) {
172
+ const detectedAgent = options.packageManager || await detectPackageManager(options.cwd) || "npm";
173
+ const [agent] = detectedAgent.split("@");
174
+ if (!Array.isArray(names))
175
+ names = [names];
176
+ const args = (typeof options.additionalArgs === "function" ? options.additionalArgs(agent, detectedAgent) : options.additionalArgs) || [];
177
+ if (options.preferOffline) {
178
+ if (detectedAgent === "yarn@berry")
179
+ args.unshift("--cached");
180
+ else
181
+ args.unshift("--prefer-offline");
182
+ }
183
+ if (agent === "pnpm") {
184
+ args.unshift(
185
+ /**
186
+ * Prevent pnpm from removing installed devDeps while `NODE_ENV` is `production`
187
+ * @see https://pnpm.io/cli/install#--prod--p
188
+ */
189
+ "--prod=false"
190
+ );
191
+ if (existsSync(resolve(options.cwd ?? process.cwd(), "pnpm-workspace.yaml"))) {
192
+ args.unshift("-w");
193
+ }
194
+ }
195
+ return x(
196
+ agent,
197
+ [
198
+ agent === "yarn" ? "add" : "install",
199
+ options.dev ? "-D" : "",
200
+ ...args,
201
+ ...names
202
+ ].filter(Boolean),
203
+ {
204
+ nodeOptions: {
205
+ stdio: options.silent ? "ignore" : "inherit",
206
+ cwd: options.cwd
207
+ },
208
+ throwOnError: true
209
+ }
210
+ );
211
+ }
212
+
213
+ export { detectPackageManager, installPackage };
@@ -13,11 +13,13 @@ function setupInspect(ctx) {
13
13
  const isEnabled = config.inspector.enabled;
14
14
  if (isEnabled) {
15
15
  inspector = __require("node:inspector");
16
- const isOpen = inspector.url() !== undefined;
16
+ // Inspector may be open already if "isolate: false" is used
17
+ const isOpen = inspector.url() !== void 0;
17
18
  if (!isOpen) {
18
19
  inspector.open(config.inspector.port, config.inspector.host, config.inspector.waitForDebugger);
19
20
  if (config.inspectBrk) {
20
21
  const firstTestFile = typeof ctx.files[0] === "string" ? ctx.files[0] : ctx.files[0].filepath;
22
+ // Stop at first test file
21
23
  if (firstTestFile) {
22
24
  session = new inspector.Session();
23
25
  session.connect();
@@ -46,6 +48,7 @@ function closeInspector(config) {
46
48
  }
47
49
  }
48
50
  function shouldKeepOpen(config) {
51
+ // In watch mode the inspector can persist re-runs if isolation is disabled and a single worker is used
49
52
  const isIsolatedSingleThread = config.pool === "threads" && config.poolOptions?.threads?.isolate === false && config.poolOptions?.threads?.singleThread;
50
53
  const isIsolatedSingleFork = config.pool === "forks" && config.poolOptions?.forks?.isolate === false && config.poolOptions?.forks?.singleFork;
51
54
  return config.watch && (isIsolatedSingleFork || isIsolatedSingleThread);
@@ -1,5 +1,5 @@
1
1
  import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
2
- import { g as getWorkerState } from './utils.CgTj3MsC.js';
2
+ import { g as getWorkerState } from './utils.XdZDrNZV.js';
3
3
  import '@vitest/utils';
4
4
 
5
5
  class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {