@nx/jest 22.6.0-beta.13 → 22.6.0-beta.14

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/jest",
3
- "version": "22.6.0-beta.13",
3
+ "version": "22.6.0-beta.14",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Jest contains executors and generators allowing your workspace to use the powerful Jest testing capabilities.",
6
6
  "repository": {
@@ -37,8 +37,8 @@
37
37
  "dependencies": {
38
38
  "@jest/reporters": "^30.0.2",
39
39
  "@jest/test-result": "^30.0.2",
40
- "@nx/devkit": "22.6.0-beta.13",
41
- "@nx/js": "22.6.0-beta.13",
40
+ "@nx/devkit": "22.6.0-beta.14",
41
+ "@nx/js": "22.6.0-beta.14",
42
42
  "@phenomnomnominal/tsquery": "~6.1.4",
43
43
  "identity-obj-proxy": "3.0.0",
44
44
  "jest-config": "^30.0.2",
@@ -52,7 +52,7 @@
52
52
  "yargs-parser": "21.1.1"
53
53
  },
54
54
  "devDependencies": {
55
- "nx": "22.6.0-beta.13"
55
+ "nx": "22.6.0-beta.14"
56
56
  },
57
57
  "publishConfig": {
58
58
  "access": "public"
@@ -12,6 +12,16 @@ export interface JestPluginOptions {
12
12
  * and test matcher instead of Jest's.
13
13
  */
14
14
  disableJestRuntime?: boolean;
15
+ /**
16
+ * Whether to use Jest's resolver (jest-resolve) for resolving config file
17
+ * references (presets, transforms, setup files, module name mappers, etc.)
18
+ * as task inputs. When false, uses path-based classification which is fast
19
+ * but cannot follow symlinks or honor custom moduleDirectories/modulePaths.
20
+ * Enable this if your config references workspace-linked packages or relies
21
+ * on Jest-specific resolution behavior.
22
+ * @default true when disableJestRuntime is false, false otherwise
23
+ */
24
+ useJestResolver?: boolean;
15
25
  }
16
26
  export declare const createNodes: CreateNodesV2<JestPluginOptions>;
17
27
  export declare const createNodesV2: CreateNodesV2<JestPluginOptions>;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../packages/jest/src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EASd,MAAM,YAAY,CAAC;AA4BpB,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAmBD,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,iBAAiB,CAiFxD,CAAC;AAEF,eAAO,MAAM,aAAa,kCAAc,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../packages/jest/src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,aAAa,EASd,MAAM,YAAY,CAAC;AA6BpB,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAmBD,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,iBAAiB,CAiFxD,CAAC;AAEF,eAAO,MAAM,aAAa,kCAAc,CAAC"}
@@ -17,6 +17,7 @@ const plugins_1 = require("nx/src/utils/plugins");
17
17
  const workspace_context_1 = require("nx/src/utils/workspace-context");
18
18
  const versions_1 = require("../utils/versions");
19
19
  const pmc = (0, devkit_1.getPackageManagerCommand)();
20
+ const REPORTER_BUILTINS = new Set(['default', 'github-actions', 'summary']);
20
21
  function readTargetsCache(cachePath) {
21
22
  return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' && (0, node_fs_1.existsSync)(cachePath)
22
23
  ? (0, devkit_1.readJsonFile)(cachePath)
@@ -147,8 +148,13 @@ async function buildJestTargets(configFilePath, projectRoot, options, context, p
147
148
  });
148
149
  // Not normalizing it here since also affects options for convert-to-inferred.
149
150
  const disableJestRuntime = options.disableJestRuntime !== false;
151
+ const useJestResolver = options.useJestResolver ?? !disableJestRuntime;
152
+ // Jest defaults rootDir to the config file's directory, but allows overrides
153
+ const rootDir = rawConfig.rootDir
154
+ ? (0, node_path_1.resolve)((0, node_path_1.dirname)(absConfigFilePath), rawConfig.rootDir)
155
+ : (0, node_path_1.resolve)(context.workspaceRoot, projectRoot);
150
156
  const cache = (target.cache = true);
151
- const inputs = (target.inputs = getInputs(namedInputs, rawConfig.preset, projectRoot, context.workspaceRoot, disableJestRuntime));
157
+ const inputs = (target.inputs = await getInputs(namedInputs, rawConfig, rootDir, projectRoot, context.workspaceRoot, presetCache, useJestResolver));
152
158
  let metadata;
153
159
  const groupName = options?.ciGroupName ?? (0, plugins_1.deriveGroupNameFromTarget)(options?.ciTargetName);
154
160
  if (disableJestRuntime) {
@@ -156,7 +162,7 @@ async function buildJestTargets(configFilePath, projectRoot, options, context, p
156
162
  ? (0, node_path_1.join)(context.workspaceRoot, projectRoot, rawConfig.coverageDirectory)
157
163
  : undefined, undefined, context));
158
164
  if (options?.ciTargetName) {
159
- const { specs, testMatch } = await getTestPaths(projectRoot, rawConfig, absConfigFilePath, context, presetCache);
165
+ const { specs, testMatch } = await getTestPaths(projectRoot, rawConfig, rootDir, context, presetCache);
160
166
  const targetGroup = [];
161
167
  const dependsOn = [];
162
168
  metadata = {
@@ -341,71 +347,79 @@ async function buildJestTargets(configFilePath, projectRoot, options, context, p
341
347
  }
342
348
  return { targets, metadata };
343
349
  }
344
- function getInputs(namedInputs, preset, projectRoot, workspaceRoot, disableJestRuntime) {
350
+ async function getInputs(namedInputs, rawConfig, rootDir, projectRoot, workspaceRoot, presetCache, useJestResolver) {
345
351
  const inputs = [
346
352
  ...('production' in namedInputs
347
353
  ? ['default', '^production']
348
354
  : ['default', '^default']),
349
355
  ];
350
356
  const externalDependencies = ['jest'];
351
- const presetInput = disableJestRuntime
352
- ? resolvePresetInputWithoutJestResolver(preset, projectRoot, workspaceRoot)
353
- : resolvePresetInputWithJestResolver(preset, projectRoot, workspaceRoot);
357
+ const resolvedModulePaths = rawConfig.modulePaths?.map((p) => replaceRootDirInPath(rootDir, p));
358
+ const jestResolve = useJestResolver
359
+ ? requireJestUtil('jest-resolve', projectRoot, workspaceRoot).default
360
+ : null;
361
+ const presetInput = jestResolve
362
+ ? resolvePresetInputWithJestResolver(rawConfig.preset, rootDir, projectRoot, workspaceRoot, jestResolve, rawConfig.moduleDirectories, resolvedModulePaths)
363
+ : resolvePresetInputWithoutJestResolver(rawConfig.preset, rootDir, projectRoot, workspaceRoot);
364
+ // Track preset file path to avoid duplicating it with config-derived inputs
365
+ let presetInputPath = null;
354
366
  if (presetInput) {
355
367
  if (typeof presetInput !== 'string' &&
356
368
  'externalDependencies' in presetInput) {
357
369
  externalDependencies.push(...presetInput.externalDependencies);
358
370
  }
359
371
  else {
372
+ presetInputPath = presetInput;
360
373
  inputs.push(presetInput);
361
374
  }
362
375
  }
376
+ const resolveFilePath = jestResolve
377
+ ? createJestResolveFilePathResolver(rootDir, projectRoot, workspaceRoot, jestResolve, rawConfig.moduleDirectories, resolvedModulePaths)
378
+ : createFilePathResolverWithoutJest(rootDir, projectRoot, workspaceRoot);
379
+ const configInputs = await getConfigFileInputs(rawConfig, rootDir, presetCache, resolveFilePath);
380
+ for (const fileInput of configInputs.fileInputs) {
381
+ if (fileInput !== presetInputPath) {
382
+ inputs.push(fileInput);
383
+ }
384
+ }
385
+ for (const dep of configInputs.externalDeps) {
386
+ if (!externalDependencies.includes(dep)) {
387
+ externalDependencies.push(dep);
388
+ }
389
+ }
363
390
  inputs.push({ externalDependencies });
364
391
  return inputs;
365
392
  }
366
- function resolvePresetInputWithoutJestResolver(presetValue, projectRoot, workspaceRoot) {
393
+ function resolvePresetInputWithoutJestResolver(presetValue, rootDir, projectRoot, workspaceRoot) {
367
394
  if (!presetValue)
368
395
  return null;
369
- const presetPath = replaceRootDirInPath(projectRoot, presetValue);
370
- const isNpmPackage = !presetValue.startsWith('.') && !(0, node_path_1.isAbsolute)(presetPath);
371
- if (isNpmPackage) {
372
- return { externalDependencies: [presetValue] };
373
- }
374
- if (presetPath.startsWith('..')) {
375
- const relativePath = (0, node_path_1.relative)(workspaceRoot, (0, node_path_1.join)(projectRoot, presetPath));
376
- return (0, node_path_1.join)('{workspaceRoot}', relativePath);
377
- }
378
- else {
379
- const relativePath = (0, node_path_1.relative)(projectRoot, presetPath);
380
- return (0, node_path_1.join)('{projectRoot}', relativePath);
396
+ const presetPath = replaceRootDirInPath(rootDir, presetValue);
397
+ const isNpmLike = !presetValue.startsWith('.') && !(0, node_path_1.isAbsolute)(presetPath);
398
+ if (isNpmLike) {
399
+ return { externalDependencies: [extractPackageName(presetValue)] };
381
400
  }
401
+ const absoluteProjectRoot = (0, node_path_1.resolve)(workspaceRoot, projectRoot);
402
+ return classifyResolvedPath((0, node_path_1.resolve)(rootDir, presetPath), absoluteProjectRoot, workspaceRoot);
382
403
  }
383
404
  // preset resolution adapted from:
384
405
  // https://github.com/jestjs/jest/blob/c54bccd657fb4cf060898717c09f633b4da3eec4/packages/jest-config/src/normalize.ts#L122
385
- function resolvePresetInputWithJestResolver(presetValue, projectRoot, workspaceRoot) {
406
+ function resolvePresetInputWithJestResolver(presetValue, rootDir, projectRoot, workspaceRoot, jestResolve, moduleDirectories, modulePaths) {
386
407
  if (!presetValue)
387
408
  return null;
388
- let presetPath = replaceRootDirInPath(projectRoot, presetValue);
389
- const isNpmPackage = !presetValue.startsWith('.') && !(0, node_path_1.isAbsolute)(presetPath);
409
+ let presetPath = replaceRootDirInPath(rootDir, presetValue);
390
410
  presetPath = presetPath.startsWith('.')
391
411
  ? presetPath
392
412
  : (0, node_path_1.join)(presetPath, 'jest-preset');
393
- const { default: jestResolve } = requireJestUtil('jest-resolve', projectRoot, workspaceRoot);
394
- const absoluteProjectRoot = (0, node_path_1.join)(workspaceRoot, projectRoot);
395
413
  const presetModule = jestResolve.findNodeModule(presetPath, {
396
- basedir: absoluteProjectRoot,
414
+ basedir: rootDir,
397
415
  extensions: ['.json', '.js', '.cjs', '.mjs'],
416
+ moduleDirectory: moduleDirectories,
417
+ paths: modulePaths,
398
418
  });
399
419
  if (!presetModule) {
400
420
  return null;
401
421
  }
402
- if (isNpmPackage) {
403
- return { externalDependencies: [presetValue] };
404
- }
405
- const relativePath = (0, node_path_1.relative)(absoluteProjectRoot, presetModule);
406
- return relativePath.startsWith('..')
407
- ? (0, node_path_1.join)('{workspaceRoot}', (0, node_path_1.join)(projectRoot, relativePath))
408
- : (0, node_path_1.join)('{projectRoot}', relativePath);
422
+ return classifyResolvedPath(presetModule, (0, node_path_1.resolve)(workspaceRoot, projectRoot), workspaceRoot);
409
423
  }
410
424
  // Adapted from here https://github.com/jestjs/jest/blob/c13bca3/packages/jest-config/src/utils.ts#L57-L69
411
425
  function replaceRootDirInPath(rootDir, filePath) {
@@ -414,6 +428,79 @@ function replaceRootDirInPath(rootDir, filePath) {
414
428
  }
415
429
  return (0, node_path_1.resolve)(rootDir, (0, node_path_1.normalize)(`./${filePath.slice('<rootDir>'.length)}`));
416
430
  }
431
+ function classifyResolvedPath(absolutePath, absoluteProjectRoot, workspaceRoot) {
432
+ const relToWorkspace = (0, devkit_1.normalizePath)((0, node_path_1.relative)(workspaceRoot, absolutePath));
433
+ if (relToWorkspace.includes('node_modules/')) {
434
+ const nmIndex = relToWorkspace.lastIndexOf('node_modules/');
435
+ const afterNm = relToWorkspace.slice(nmIndex + 'node_modules/'.length);
436
+ return { externalDependencies: [extractPackageName(afterNm)] };
437
+ }
438
+ const relToProject = (0, devkit_1.normalizePath)((0, node_path_1.relative)(absoluteProjectRoot, absolutePath));
439
+ if (relToProject.startsWith('..')) {
440
+ return (0, devkit_1.joinPathFragments)('{workspaceRoot}', relToWorkspace);
441
+ }
442
+ return (0, devkit_1.joinPathFragments)('{projectRoot}', relToProject);
443
+ }
444
+ function extractPackageName(value) {
445
+ const parts = value.split('/');
446
+ return value.startsWith('@') ? `${parts[0]}/${parts[1]}` : parts[0];
447
+ }
448
+ function createFilePathResolverWithoutJest(rootDir, projectRoot, workspaceRoot) {
449
+ const absoluteProjectRoot = (0, node_path_1.resolve)(workspaceRoot, projectRoot);
450
+ return (filePath) => {
451
+ const resolvedPath = replaceRootDirInPath(rootDir, filePath);
452
+ if (looksLikePackageName(filePath, resolvedPath)) {
453
+ return { externalDependencies: [extractPackageName(filePath)] };
454
+ }
455
+ return classifyResolvedPath((0, node_path_1.resolve)(rootDir, resolvedPath), absoluteProjectRoot, workspaceRoot);
456
+ };
457
+ }
458
+ function resolveWithPrefixFallback(filePath, prefix, resolver) {
459
+ if (!filePath.startsWith('.') &&
460
+ !filePath.startsWith('<rootDir>') &&
461
+ !(0, node_path_1.isAbsolute)(filePath) &&
462
+ !filePath.startsWith(prefix)) {
463
+ const prefixed = resolver(`${prefix}${filePath}`);
464
+ if (prefixed)
465
+ return prefixed;
466
+ }
467
+ return resolver(filePath);
468
+ }
469
+ function looksLikePackageName(filePath, resolvedPath) {
470
+ return (!filePath.startsWith('.') &&
471
+ !filePath.startsWith('<rootDir>') &&
472
+ !(0, node_path_1.isAbsolute)(resolvedPath));
473
+ }
474
+ function createJestResolveFilePathResolver(rootDir, projectRoot, workspaceRoot, jestResolve, moduleDirectories, modulePaths) {
475
+ const absoluteProjectRoot = (0, node_path_1.resolve)(workspaceRoot, projectRoot);
476
+ const cache = new Map();
477
+ return (filePath) => {
478
+ if (cache.has(filePath)) {
479
+ return cache.get(filePath);
480
+ }
481
+ const resolvedPath = replaceRootDirInPath(rootDir, filePath);
482
+ let result;
483
+ const absolutePath = jestResolve.findNodeModule(resolvedPath, {
484
+ basedir: rootDir,
485
+ extensions: ['.js', '.json', '.cjs', '.mjs', '.mts', '.cts', '.node'],
486
+ moduleDirectory: moduleDirectories,
487
+ paths: modulePaths,
488
+ });
489
+ if (!absolutePath) {
490
+ if (looksLikePackageName(filePath, resolvedPath)) {
491
+ result = { externalDependencies: [extractPackageName(filePath)] };
492
+ }
493
+ else {
494
+ result = null;
495
+ }
496
+ }
497
+ else {
498
+ result = classifyResolvedPath(absolutePath, absoluteProjectRoot, workspaceRoot);
499
+ }
500
+ cache.set(filePath, result);
501
+ return result;
502
+ };
503
+ }
417
504
  function getOutputs(projectRoot, coverageDirectory, outputFile, context) {
418
505
  function getOutput(path) {
419
506
  const relativePath = (0, node_path_1.relative)((0, node_path_1.join)(context.workspaceRoot, projectRoot), path);
@@ -465,14 +552,14 @@ function requireJestUtil(packageName, projectRoot, workspaceRoot) {
465
552
  paths: [(0, node_path_1.dirname)(resolvedJestCorePaths[jestPath])],
466
553
  }));
467
554
  }
468
- async function getTestPaths(projectRoot, rawConfig, absConfigFilePath, context, presetCache) {
469
- const testMatch = await getJestOption(rawConfig, absConfigFilePath, 'testMatch', presetCache);
555
+ async function getTestPaths(projectRoot, rawConfig, rootDir, context, presetCache) {
556
+ const testMatch = await getJestOption(rawConfig, rootDir, 'testMatch', presetCache);
470
557
  let paths = await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, (testMatch || [
471
558
  // Default copied from https://github.com/jestjs/jest/blob/d1a2ed7/packages/jest-config/src/Defaults.ts#L84
472
559
  '**/__tests__/**/*.?([mc])[jt]s?(x)',
473
560
  '**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
474
561
  ]).map((pattern) => (0, node_path_1.join)(projectRoot, pattern)), []);
475
- const testRegex = await getJestOption(rawConfig, absConfigFilePath, 'testRegex', presetCache);
562
+ const testRegex = await getJestOption(rawConfig, rootDir, 'testRegex', presetCache);
476
563
  if (testRegex) {
477
564
  const testRegexes = Array.isArray(rawConfig.testRegex)
478
565
  ? rawConfig.testRegex.map((r) => new RegExp(r))
@@ -481,27 +568,151 @@ async function getTestPaths(projectRoot, rawConfig, absConfigFilePath, context,
481
568
  }
482
569
  return { specs: paths, testMatch };
483
570
  }
484
- async function getJestOption(rawConfig, absConfigFilePath, optionName, presetCache) {
485
- if (rawConfig[optionName])
486
- return rawConfig[optionName];
487
- if (rawConfig.preset) {
488
- const dir = (0, node_path_1.dirname)(absConfigFilePath);
489
- const presetPath = (0, node_path_1.resolve)(dir, rawConfig.preset);
571
+ async function loadPresetConfig(rawConfig, rootDir, presetCache) {
572
+ if (!rawConfig.preset)
573
+ return null;
574
+ const presetValue = replaceRootDirInPath(rootDir, rawConfig.preset);
575
+ let presetPath;
576
+ if (presetValue.startsWith('.') || (0, node_path_1.isAbsolute)(presetValue)) {
577
+ presetPath = (0, node_path_1.resolve)(rootDir, presetValue);
578
+ }
579
+ else {
490
580
  try {
491
- let preset = presetCache[presetPath];
492
- if (!preset) {
493
- preset = await (0, config_utils_1.loadConfigFile)(presetPath);
494
- presetCache[presetPath] = preset;
495
- }
496
- if (preset[optionName])
497
- return preset[optionName];
581
+ presetPath = require.resolve((0, node_path_1.join)(presetValue, 'jest-preset'), {
582
+ paths: [rootDir],
583
+ });
498
584
  }
499
585
  catch {
500
- // If preset fails to load, ignore the error and continue.
501
- // This is safe and less jarring for users. They will need to fix the
502
- // preset for Jest to run, and at that point we can read in the correct
503
- // value.
586
+ return null;
587
+ }
588
+ }
589
+ try {
590
+ if (!presetCache[presetPath]) {
591
+ presetCache[presetPath] = (0, config_utils_1.loadConfigFile)(presetPath);
504
592
  }
593
+ return (await presetCache[presetPath]);
594
+ }
595
+ catch {
596
+ // If preset fails to load, ignore the error and continue.
597
+ // This is safe and less jarring for users. They will need to fix the
598
+ // preset for Jest to run, and at that point we can read in the correct
599
+ // value.
600
+ return null;
505
601
  }
602
+ }
603
+ async function getConfigFileInputs(rawConfig, rootDir, presetCache, resolveFilePath) {
604
+ const fileInputs = new Set();
605
+ const externalDeps = new Set();
606
+ const preset = await loadPresetConfig(rawConfig, rootDir, presetCache);
607
+ function addInput(input) {
608
+ if (!input)
609
+ return;
610
+ if (typeof input === 'string') {
611
+ fileInputs.add(input);
612
+ }
613
+ else {
614
+ input.externalDependencies.forEach((d) => externalDeps.add(d));
615
+ }
616
+ }
617
+ // Replaced properties: rawConfig[prop] wins over preset[prop]
618
+ for (const prop of [
619
+ 'resolver',
620
+ 'globalSetup',
621
+ 'globalTeardown',
622
+ 'snapshotResolver',
623
+ 'testResultsProcessor',
624
+ ]) {
625
+ const value = rawConfig[prop] ?? preset?.[prop];
626
+ if (typeof value === 'string') {
627
+ addInput(resolveFilePath(value));
628
+ }
629
+ }
630
+ // runner uses jest-runner- prefix resolution
631
+ const runner = rawConfig.runner ?? preset?.runner;
632
+ if (typeof runner === 'string') {
633
+ addInput(resolveWithPrefixFallback(runner, 'jest-runner-', resolveFilePath));
634
+ }
635
+ // Concatenated properties: preset values + config values
636
+ for (const prop of ['setupFiles', 'setupFilesAfterEnv']) {
637
+ const values = [
638
+ ...(preset?.[prop] ?? []),
639
+ ...(rawConfig[prop] ?? []),
640
+ ];
641
+ for (const value of values) {
642
+ if (typeof value === 'string') {
643
+ addInput(resolveFilePath(value));
644
+ }
645
+ }
646
+ }
647
+ // Merged: moduleNameMapper — config keys win (skip values with backreferences like $1)
648
+ const moduleNameMapper = {
649
+ ...(preset?.moduleNameMapper ?? {}),
650
+ ...(rawConfig.moduleNameMapper ?? {}),
651
+ };
652
+ for (const value of Object.values(moduleNameMapper)) {
653
+ const values = Array.isArray(value) ? value : [value];
654
+ for (const v of values) {
655
+ if (typeof v !== 'string')
656
+ continue;
657
+ if (/\$\d/.test(v))
658
+ continue;
659
+ addInput(resolveFilePath(v));
660
+ }
661
+ }
662
+ // Merged: transform — config keys win
663
+ const transform = {
664
+ ...(preset?.transform ?? {}),
665
+ ...(rawConfig.transform ?? {}),
666
+ };
667
+ for (const value of Object.values(transform)) {
668
+ let transformPath;
669
+ if (Array.isArray(value)) {
670
+ transformPath = value[0];
671
+ }
672
+ else if (typeof value === 'string') {
673
+ transformPath = value;
674
+ }
675
+ else {
676
+ continue;
677
+ }
678
+ addInput(resolveFilePath(transformPath));
679
+ }
680
+ // Replaced: snapshotSerializers, reporters, watchPlugins
681
+ const snapshotSerializers = rawConfig.snapshotSerializers ??
682
+ preset?.snapshotSerializers ??
683
+ [];
684
+ for (const value of snapshotSerializers) {
685
+ if (typeof value === 'string') {
686
+ addInput(resolveFilePath(value));
687
+ }
688
+ }
689
+ const reporters = rawConfig.reporters ?? preset?.reporters ?? [];
690
+ for (const entry of reporters) {
691
+ const name = Array.isArray(entry) ? entry[0] : entry;
692
+ if (typeof name !== 'string')
693
+ continue;
694
+ if (REPORTER_BUILTINS.has(name))
695
+ continue;
696
+ addInput(resolveFilePath(name));
697
+ }
698
+ // watchPlugins uses jest-watch- prefix resolution
699
+ const watchPlugins = rawConfig.watchPlugins ?? preset?.watchPlugins ?? [];
700
+ for (const entry of watchPlugins) {
701
+ const name = Array.isArray(entry) ? entry[0] : entry;
702
+ if (typeof name !== 'string')
703
+ continue;
704
+ addInput(resolveWithPrefixFallback(name, 'jest-watch-', resolveFilePath));
705
+ }
706
+ return {
707
+ fileInputs: [...fileInputs],
708
+ externalDeps: [...externalDeps],
709
+ };
710
+ }
711
+ async function getJestOption(rawConfig, rootDir, optionName, presetCache) {
712
+ if (rawConfig[optionName])
713
+ return rawConfig[optionName];
714
+ const preset = await loadPresetConfig(rawConfig, rootDir, presetCache);
715
+ if (preset?.[optionName])
716
+ return preset[optionName];
506
717
  return undefined;
507
718
  }