@atlaskit/eslint-plugin-platform 2.8.0 → 2.9.1

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 (47) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/index.js +8 -1
  3. package/dist/cjs/rules/ensure-critical-dependency-resolutions/index.js +0 -1
  4. package/dist/cjs/rules/ensure-use-sync-external-store-server-snapshot/index.js +41 -0
  5. package/dist/cjs/rules/import/no-barrel-entry-imports/index.js +534 -74
  6. package/dist/cjs/rules/import/no-barrel-entry-jest-mock/index.js +428 -119
  7. package/dist/cjs/rules/import/no-jest-mock-barrel-files/index.js +3 -2
  8. package/dist/cjs/rules/import/no-relative-barrel-file-imports/index.js +7 -3
  9. package/dist/cjs/rules/import/shared/jest-utils.js +62 -9
  10. package/dist/cjs/rules/import/shared/package-resolution.js +300 -22
  11. package/dist/cjs/rules/no-restricted-fedramp-imports/index.js +65 -0
  12. package/dist/cjs/rules/visit-example-type-import-required/index.js +409 -0
  13. package/dist/es2019/index.js +8 -1
  14. package/dist/es2019/rules/ensure-critical-dependency-resolutions/index.js +0 -1
  15. package/dist/es2019/rules/ensure-use-sync-external-store-server-snapshot/index.js +43 -0
  16. package/dist/es2019/rules/import/no-barrel-entry-imports/index.js +431 -25
  17. package/dist/es2019/rules/import/no-barrel-entry-jest-mock/index.js +287 -25
  18. package/dist/es2019/rules/import/no-jest-mock-barrel-files/index.js +3 -2
  19. package/dist/es2019/rules/import/no-relative-barrel-file-imports/index.js +7 -3
  20. package/dist/es2019/rules/import/shared/jest-utils.js +44 -0
  21. package/dist/es2019/rules/import/shared/package-resolution.js +211 -4
  22. package/dist/es2019/rules/no-restricted-fedramp-imports/index.js +47 -0
  23. package/dist/es2019/rules/visit-example-type-import-required/index.js +375 -0
  24. package/dist/esm/index.js +8 -1
  25. package/dist/esm/rules/ensure-critical-dependency-resolutions/index.js +0 -1
  26. package/dist/esm/rules/ensure-use-sync-external-store-server-snapshot/index.js +35 -0
  27. package/dist/esm/rules/import/no-barrel-entry-imports/index.js +535 -75
  28. package/dist/esm/rules/import/no-barrel-entry-jest-mock/index.js +430 -121
  29. package/dist/esm/rules/import/no-jest-mock-barrel-files/index.js +3 -2
  30. package/dist/esm/rules/import/no-relative-barrel-file-imports/index.js +7 -3
  31. package/dist/esm/rules/import/shared/jest-utils.js +61 -9
  32. package/dist/esm/rules/import/shared/package-resolution.js +298 -24
  33. package/dist/esm/rules/no-restricted-fedramp-imports/index.js +59 -0
  34. package/dist/esm/rules/visit-example-type-import-required/index.js +402 -0
  35. package/dist/types/index.d.ts +14 -0
  36. package/dist/types/rules/ensure-use-sync-external-store-server-snapshot/index.d.ts +3 -0
  37. package/dist/types/rules/import/shared/jest-utils.d.ts +8 -0
  38. package/dist/types/rules/import/shared/package-resolution.d.ts +47 -2
  39. package/dist/types/rules/no-restricted-fedramp-imports/index.d.ts +3 -0
  40. package/dist/types/rules/visit-example-type-import-required/index.d.ts +4 -0
  41. package/dist/types-ts4.5/index.d.ts +14 -0
  42. package/dist/types-ts4.5/rules/ensure-use-sync-external-store-server-snapshot/index.d.ts +3 -0
  43. package/dist/types-ts4.5/rules/import/shared/jest-utils.d.ts +8 -0
  44. package/dist/types-ts4.5/rules/import/shared/package-resolution.d.ts +47 -2
  45. package/dist/types-ts4.5/rules/no-restricted-fedramp-imports/index.d.ts +3 -0
  46. package/dist/types-ts4.5/rules/visit-example-type-import-required/index.d.ts +4 -0
  47. package/package.json +3 -1
@@ -8,9 +8,9 @@ import { dirname } from 'path';
8
8
  import * as ts from 'typescript';
9
9
  import { hasReExportsFromOtherFiles, parseBarrelExports } from '../shared/barrel-parsing';
10
10
  import { DEFAULT_TARGET_FOLDERS, findWorkspaceRoot, isRelativeImport, readFileContent, resolveImportPath } from '../shared/file-system';
11
- import { extractImportPath, findJestRequireMockCalls, isJestMockCall, isJestRequireActual, resolveNewPathForRequireMock } from '../shared/jest-utils';
11
+ import { extractImportPath, findJestRequireActualCalls, findJestRequireMockCalls, isJestMockCall, isJestRequireActual, resolveNewPathForRequireMock } from '../shared/jest-utils';
12
12
  import { findPackageInRegistry, isPackageInApplyToImportsFrom } from '../shared/package-registry';
13
- import { findExportForSourceFile, parsePackageExports } from '../shared/package-resolution';
13
+ import { findCrossPackageBridgeExportPath, findExportForSourceFile, parsePackageExports } from '../shared/package-resolution';
14
14
  import { realFileSystem } from '../shared/types';
15
15
 
16
16
  /**
@@ -662,7 +662,9 @@ function traceSymbolsToExports(_ref10) {
662
662
  exportMap = _ref10.exportMap,
663
663
  exportsMap = _ref10.exportsMap,
664
664
  currentExportPath = _ref10.currentExportPath,
665
- fs = _ref10.fs;
665
+ fs = _ref10.fs,
666
+ barrelPackageName = _ref10.barrelPackageName,
667
+ preferImportedPackageSubpath = _ref10.preferImportedPackageSubpath;
666
668
  var groupedByExport = new Map();
667
669
  var crossPackageGroups = new Map();
668
670
  var unmappedSymbols = [];
@@ -670,6 +672,7 @@ function traceSymbolsToExports(_ref10) {
670
672
  _step13;
671
673
  try {
672
674
  for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
675
+ var _findExportForSourceF, _findExportForSourceF2;
673
676
  var symbolName = _step13.value;
674
677
  var exportInfo = exportMap.get(symbolName);
675
678
  if (!exportInfo) {
@@ -679,25 +682,47 @@ function traceSymbolsToExports(_ref10) {
679
682
 
680
683
  // Check for cross-package source first
681
684
  if (exportInfo.crossPackageSource) {
682
- var key = "".concat(exportInfo.crossPackageSource.packageName).concat(exportInfo.crossPackageSource.exportPath === '.' ? '' : exportInfo.crossPackageSource.exportPath.slice(1));
685
+ var key = void 0;
686
+ var tracedOriginalName = exportInfo.originalName;
687
+ var barrelBridgeExportPath = void 0;
688
+ if (preferImportedPackageSubpath) {
689
+ var bridge = findCrossPackageBridgeExportPath({
690
+ exportsMap: exportsMap,
691
+ crossPackageName: exportInfo.crossPackageSource.packageName,
692
+ exportedName: symbolName,
693
+ fs: fs
694
+ });
695
+ if (bridge) {
696
+ key = "".concat(barrelPackageName).concat(bridge.exportPath.slice(1));
697
+ barrelBridgeExportPath = bridge.exportPath;
698
+ if (bridge.entryPointExportName !== undefined) {
699
+ tracedOriginalName = bridge.entryPointExportName === symbolName ? undefined : bridge.entryPointExportName;
700
+ }
701
+ } else {
702
+ key = "".concat(exportInfo.crossPackageSource.packageName).concat(exportInfo.crossPackageSource.exportPath === '.' ? '' : exportInfo.crossPackageSource.exportPath.slice(1));
703
+ }
704
+ } else {
705
+ key = "".concat(exportInfo.crossPackageSource.packageName).concat(exportInfo.crossPackageSource.exportPath === '.' ? '' : exportInfo.crossPackageSource.exportPath.slice(1));
706
+ }
683
707
  if (!crossPackageGroups.has(key)) {
684
708
  crossPackageGroups.set(key, []);
685
709
  }
686
710
  crossPackageGroups.get(key).push({
687
711
  symbolName: symbolName,
688
- originalName: exportInfo.originalName,
712
+ originalName: tracedOriginalName,
689
713
  sourceFilePath: exportInfo.path,
690
714
  isTypeOnly: exportInfo.isTypeOnly,
691
- crossPackageSource: exportInfo.crossPackageSource
715
+ crossPackageSource: exportInfo.crossPackageSource,
716
+ barrelBridgeExportPath: barrelBridgeExportPath
692
717
  });
693
718
  continue;
694
719
  }
695
720
 
696
721
  // First try to find an export that directly exposes the source file
697
- var targetExportPath = findExportForSourceFile({
722
+ var targetExportPath = (_findExportForSourceF = (_findExportForSourceF2 = findExportForSourceFile({
698
723
  sourceFilePath: exportInfo.path,
699
724
  exportsMap: exportsMap
700
- });
725
+ })) === null || _findExportForSourceF2 === void 0 ? void 0 : _findExportForSourceF2.exportPath) !== null && _findExportForSourceF !== void 0 ? _findExportForSourceF : null;
701
726
 
702
727
  // If no direct match, check which export can provide this symbol
703
728
  // (handles nested barrels where the symbol is re-exported through intermediate files)
@@ -757,16 +782,80 @@ function escapeRegExp(str) {
757
782
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
758
783
  }
759
784
 
785
+ /** Mock object keys that are module interop metadata, not package exports. */
786
+ var ESM_INTEROP_MOCK_KEYS = new Set(['__esModule']);
787
+
788
+ /**
789
+ * If a preamble line is `const|let actual = jest.requireActual('<barrel>')`, rewrite the specifier to
790
+ * `targetImportPathForThisMock` when every `binding.<prop>` read in this split mock's implementation
791
+ * resolves to that same path via `symbolToNewImportPath`. Otherwise leave unchanged (e.g. mixed paths
792
+ * still need the barrel module).
793
+ */
794
+ function rewritePreambleLineBarrelRequireActual(_ref12) {
795
+ var lineText = _ref12.lineText,
796
+ oldBarrelPath = _ref12.oldBarrelPath,
797
+ targetImportPathForThisMock = _ref12.targetImportPathForThisMock,
798
+ mockImplementationTextForGroup = _ref12.mockImplementationTextForGroup,
799
+ symbolToNewImportPath = _ref12.symbolToNewImportPath;
800
+ var requireActualRe = /jest\.requireActual(?:<[^>]*>)?\((['"])([^'"]+)\1\)/;
801
+ var requireMatch = requireActualRe.exec(lineText);
802
+ if (!requireMatch || requireMatch[2] !== oldBarrelPath) {
803
+ return lineText;
804
+ }
805
+ var quote = requireMatch[1];
806
+ var bindingMatch = /^\s*(?:const|let)\s+(\w+)\s*=/m.exec(lineText);
807
+ if (!bindingMatch) {
808
+ return lineText;
809
+ }
810
+ var binding = bindingMatch[1];
811
+ var propAccessRe = new RegExp("\\b".concat(escapeRegExp(binding), "\\.(\\w+)"), 'g');
812
+ var accessedProps = new Set();
813
+ var propMatch;
814
+ while ((propMatch = propAccessRe.exec(mockImplementationTextForGroup)) !== null) {
815
+ accessedProps.add(propMatch[1]);
816
+ }
817
+ if (accessedProps.size === 0) {
818
+ return lineText;
819
+ }
820
+ var resolvedPaths = [];
821
+ var _iterator14 = _createForOfIteratorHelper(accessedProps),
822
+ _step14;
823
+ try {
824
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
825
+ var prop = _step14.value;
826
+ var mapped = symbolToNewImportPath.get(prop);
827
+ if (mapped) {
828
+ resolvedPaths.push(mapped);
829
+ }
830
+ }
831
+ } catch (err) {
832
+ _iterator14.e(err);
833
+ } finally {
834
+ _iterator14.f();
835
+ }
836
+ if (resolvedPaths.length === 0) {
837
+ return lineText;
838
+ }
839
+ var uniquePaths = new Set(resolvedPaths);
840
+ if (uniquePaths.size !== 1 || !uniquePaths.has(targetImportPathForThisMock)) {
841
+ return lineText;
842
+ }
843
+ return lineText.replace("jest.requireActual(".concat(quote).concat(oldBarrelPath).concat(quote, ")"), "jest.requireActual(".concat(quote).concat(targetImportPathForThisMock).concat(quote, ")"));
844
+ }
845
+
760
846
  /**
761
847
  * Generate fix text for multiple jest.mock calls
762
848
  */
763
- function generateMockFixes(_ref12) {
764
- var groups = _ref12.groups,
765
- crossPackageGroups = _ref12.crossPackageGroups,
766
- packageName = _ref12.packageName,
767
- mockProperties = _ref12.mockProperties,
768
- quote = _ref12.quote,
769
- preambleStatements = _ref12.preambleStatements;
849
+ function generateMockFixes(_ref13) {
850
+ var groups = _ref13.groups,
851
+ crossPackageGroups = _ref13.crossPackageGroups,
852
+ packageName = _ref13.packageName,
853
+ mockProperties = _ref13.mockProperties,
854
+ quote = _ref13.quote,
855
+ preambleStatements = _ref13.preambleStatements,
856
+ propagateEsModuleFromOriginalMock = _ref13.propagateEsModuleFromOriginalMock,
857
+ oldBarrelImportPath = _ref13.oldBarrelImportPath,
858
+ symbolToNewImportPath = _ref13.symbolToNewImportPath;
770
859
  var mockCalls = [];
771
860
 
772
861
  // Helper to generate a single mock call
@@ -774,15 +863,15 @@ function generateMockFixes(_ref12) {
774
863
  var propTexts = [];
775
864
  propTexts.push("...jest.requireActual(".concat(quote).concat(fullImportPath).concat(quote, ")"));
776
865
 
777
- // Add __esModule: true when mocking default exports
778
- if (group.hasDefaultExport) {
866
+ // Add __esModule: true when mocking default exports, or when the original mock already used __esModule (apply to every split).
867
+ if (group.hasDefaultExport || propagateEsModuleFromOriginalMock) {
779
868
  propTexts.push('__esModule: true');
780
869
  }
781
- var _iterator14 = _createForOfIteratorHelper(group.propertyNames),
782
- _step14;
870
+ var _iterator15 = _createForOfIteratorHelper(group.propertyNames),
871
+ _step15;
783
872
  try {
784
- for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
785
- var propName = _step14.value;
873
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
874
+ var propName = _step15.value;
786
875
  // First try to get from group's propertyTexts (used for merged mocks)
787
876
  var groupPropText = group.propertyTexts.get(propName);
788
877
  if (groupPropText) {
@@ -816,21 +905,34 @@ function generateMockFixes(_ref12) {
816
905
  }
817
906
  }
818
907
  }
819
-
820
- // Determine if we need preamble for this group
821
908
  } catch (err) {
822
- _iterator14.e(err);
909
+ _iterator15.e(err);
823
910
  } finally {
824
- _iterator14.f();
911
+ _iterator15.f();
825
912
  }
913
+ var combinedGroupImplText = group.propertyNames.map(function (name) {
914
+ var _ref14, _group$propertyTexts$, _mockProperties$get;
915
+ return (_ref14 = (_group$propertyTexts$ = group.propertyTexts.get(name)) !== null && _group$propertyTexts$ !== void 0 ? _group$propertyTexts$ : (_mockProperties$get = mockProperties.get(name)) === null || _mockProperties$get === void 0 ? void 0 : _mockProperties$get.text) !== null && _ref14 !== void 0 ? _ref14 : '';
916
+ }).join('\n');
917
+
918
+ // Determine if we need preamble for this group
826
919
  var neededPreamble = getNeededPreamble({
827
920
  propertyTexts: propTexts,
828
921
  allPreamble: preambleStatements
829
922
  });
923
+ var rewrittenPreamble = neededPreamble.map(function (p) {
924
+ return rewritePreambleLineBarrelRequireActual({
925
+ lineText: p.text,
926
+ oldBarrelPath: oldBarrelImportPath,
927
+ targetImportPathForThisMock: fullImportPath,
928
+ mockImplementationTextForGroup: combinedGroupImplText,
929
+ symbolToNewImportPath: symbolToNewImportPath
930
+ });
931
+ });
830
932
  if (neededPreamble.length > 0) {
831
933
  // Generate block body arrow function with preamble
832
- var preambleLines = neededPreamble.map(function (p) {
833
- return "\t".concat(p.text);
934
+ var preambleLines = rewrittenPreamble.map(function (text) {
935
+ return "\t".concat(text);
834
936
  }).join('\n');
835
937
  var formattedProps = propTexts.map(function (p) {
836
938
  return "\t\t".concat(p, ",");
@@ -846,34 +948,34 @@ function generateMockFixes(_ref12) {
846
948
  };
847
949
 
848
950
  // Generate mocks for cross-package groups first
849
- var _iterator15 = _createForOfIteratorHelper(crossPackageGroups),
850
- _step15;
951
+ var _iterator16 = _createForOfIteratorHelper(crossPackageGroups),
952
+ _step16;
851
953
  try {
852
- for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
853
- var group = _step15.value;
954
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
955
+ var group = _step16.value;
854
956
  mockCalls.push(generateMockCall(group, group.importPath));
855
957
  }
856
958
 
857
959
  // Generate mocks for same-package groups
858
960
  } catch (err) {
859
- _iterator15.e(err);
961
+ _iterator16.e(err);
860
962
  } finally {
861
- _iterator15.f();
963
+ _iterator16.f();
862
964
  }
863
- var _iterator16 = _createForOfIteratorHelper(groups),
864
- _step16;
965
+ var _iterator17 = _createForOfIteratorHelper(groups),
966
+ _step17;
865
967
  try {
866
- for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
867
- var _group = _step16.value;
968
+ for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
969
+ var _group = _step17.value;
868
970
  var fullImportPath = "".concat(packageName).concat(_group.exportPath.slice(1));
869
971
  mockCalls.push(generateMockCall(_group, fullImportPath));
870
972
  }
871
973
 
872
974
  // Join with semicolons but don't add trailing semicolon
873
975
  } catch (err) {
874
- _iterator16.e(err);
976
+ _iterator17.e(err);
875
977
  } finally {
876
- _iterator16.f();
978
+ _iterator17.f();
877
979
  }
878
980
  return mockCalls.join(';\n');
879
981
  }
@@ -886,11 +988,11 @@ function generateMockFixes(_ref12) {
886
988
  * Resolves jest.mock context for barrel file analysis.
887
989
  * Returns null if the mock should not be processed.
888
990
  */
889
- function resolveJestMockContext(_ref13) {
890
- var importPath = _ref13.importPath,
891
- workspaceRoot = _ref13.workspaceRoot,
892
- fs = _ref13.fs,
893
- applyToImportsFrom = _ref13.applyToImportsFrom;
991
+ function resolveJestMockContext(_ref15) {
992
+ var importPath = _ref15.importPath,
993
+ workspaceRoot = _ref15.workspaceRoot,
994
+ fs = _ref15.fs,
995
+ applyToImportsFrom = _ref15.applyToImportsFrom;
894
996
  if (isRelativeImport(importPath)) {
895
997
  return null;
896
998
  }
@@ -953,9 +1055,9 @@ function resolveJestMockContext(_ref13) {
953
1055
  /**
954
1056
  * Check if the entry file is a barrel file (re-exports from other files)
955
1057
  */
956
- function isBarrelFile(_ref14) {
957
- var exportMap = _ref14.exportMap,
958
- entryFilePath = _ref14.entryFilePath;
1058
+ function isBarrelFile(_ref16) {
1059
+ var exportMap = _ref16.exportMap,
1060
+ entryFilePath = _ref16.entryFilePath;
959
1061
  return hasReExportsFromOtherFiles({
960
1062
  exportMap: exportMap,
961
1063
  sourceFilePath: entryFilePath
@@ -982,12 +1084,17 @@ var ruleMeta = {
982
1084
  type: 'string'
983
1085
  },
984
1086
  description: 'The folder paths (relative to workspace root) containing packages whose imports will be checked and autofixed.'
1087
+ },
1088
+ preferImportedPackageSubpath: {
1089
+ type: 'boolean',
1090
+ description: 'Prefer subpaths on the mocked barrel package when they bridge to the dependency.'
985
1091
  }
986
1092
  },
987
1093
  additionalProperties: false
988
1094
  }],
989
1095
  messages: {
990
- barrelEntryMock: "jest.mock('{{path}}') is mocking a barrel file entry point. Split into separate mocks for each source file using package.json exports."
1096
+ barrelEntryMock: "jest.mock('{{path}}') is mocking a barrel file entry point. Split into separate mocks for each source file using package.json exports.",
1097
+ barrelEntryRequireActual: "jest.requireActual('{{path}}') references a barrel file entry point. Use a specific package.json export path instead."
991
1098
  }
992
1099
  };
993
1100
 
@@ -999,9 +1106,10 @@ export function createRule(fs) {
999
1106
  return {
1000
1107
  meta: ruleMeta,
1001
1108
  create: function create(context) {
1002
- var _options$applyToImpor;
1109
+ var _options$applyToImpor, _options$preferImport;
1003
1110
  var options = context.options[0] || {};
1004
1111
  var applyToImportsFrom = (_options$applyToImpor = options.applyToImportsFrom) !== null && _options$applyToImpor !== void 0 ? _options$applyToImpor : DEFAULT_TARGET_FOLDERS;
1112
+ var preferImportedPackageSubpath = (_options$preferImport = options.preferImportedPackageSubpath) !== null && _options$preferImport !== void 0 ? _options$preferImport : false;
1005
1113
  var workspaceRoot = findWorkspaceRoot({
1006
1114
  startPath: dirname(context.filename),
1007
1115
  fs: fs,
@@ -1010,6 +1118,136 @@ export function createRule(fs) {
1010
1118
  return {
1011
1119
  CallExpression: function CallExpression(rawNode) {
1012
1120
  var node = rawNode;
1121
+
1122
+ // Handle standalone jest.requireActual() calls that reference barrel entries.
1123
+ // e.g. jest.requireActual('@atlaskit/pkg').Foo or const { Foo } = jest.requireActual('@atlaskit/pkg')
1124
+ if (isJestRequireActual(node)) {
1125
+ var raImportPath = extractImportPath(node);
1126
+ if (!raImportPath) {
1127
+ return;
1128
+ }
1129
+ var raContext = resolveJestMockContext({
1130
+ importPath: raImportPath,
1131
+ workspaceRoot: workspaceRoot,
1132
+ fs: fs,
1133
+ applyToImportsFrom: applyToImportsFrom
1134
+ });
1135
+ if (!raContext) {
1136
+ return;
1137
+ }
1138
+ if (!isBarrelFile({
1139
+ exportMap: raContext.exportMap,
1140
+ entryFilePath: raContext.entryFilePath
1141
+ })) {
1142
+ return;
1143
+ }
1144
+
1145
+ // `jest.requireActual('<barrel>')` inside `jest.mock('<barrel>')` is handled by the mock
1146
+ // rule's fix (preamble retargeting + `jest.requireActual('barrel').x` rewriting), including
1147
+ // `const actual = jest.requireActual('<barrel>')` with no member access on the call.
1148
+ // Skip standalone handling here to avoid duplicate diagnostics.
1149
+ var ancestor = node.parent;
1150
+ while (ancestor) {
1151
+ if (ancestor.type === 'CallExpression' && isJestMockCall(ancestor)) {
1152
+ var ancestorPath = extractImportPath(ancestor);
1153
+ if (ancestorPath) {
1154
+ var ancestorCtx = resolveJestMockContext({
1155
+ importPath: ancestorPath,
1156
+ workspaceRoot: workspaceRoot,
1157
+ fs: fs,
1158
+ applyToImportsFrom: applyToImportsFrom
1159
+ });
1160
+ if (ancestorCtx && isBarrelFile({
1161
+ exportMap: ancestorCtx.exportMap,
1162
+ entryFilePath: ancestorCtx.entryFilePath
1163
+ })) {
1164
+ return;
1165
+ }
1166
+ }
1167
+ }
1168
+ ancestor = ancestor.parent;
1169
+ }
1170
+
1171
+ // Determine which symbols are accessed from the barrel
1172
+ var parent = node.parent;
1173
+ var accessedSymbols = [];
1174
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'MemberExpression' && parent.property.type === 'Identifier') {
1175
+ accessedSymbols.push(parent.property.name);
1176
+ } else if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'VariableDeclarator' && parent.id.type === 'ObjectPattern') {
1177
+ var _iterator18 = _createForOfIteratorHelper(parent.id.properties),
1178
+ _step18;
1179
+ try {
1180
+ for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
1181
+ var prop = _step18.value;
1182
+ if (prop.type === 'Property' && prop.key.type === 'Identifier') {
1183
+ accessedSymbols.push(prop.key.name);
1184
+ }
1185
+ }
1186
+ } catch (err) {
1187
+ _iterator18.e(err);
1188
+ } finally {
1189
+ _iterator18.f();
1190
+ }
1191
+ }
1192
+ if (accessedSymbols.length === 0) {
1193
+ context.report({
1194
+ node: node,
1195
+ messageId: 'barrelEntryRequireActual',
1196
+ data: {
1197
+ path: raImportPath
1198
+ }
1199
+ });
1200
+ return;
1201
+ }
1202
+ var _traceSymbolsToExport = traceSymbolsToExports({
1203
+ symbolNames: accessedSymbols,
1204
+ exportMap: raContext.exportMap,
1205
+ exportsMap: raContext.exportsMap,
1206
+ currentExportPath: raContext.currentExportPath,
1207
+ fs: fs,
1208
+ barrelPackageName: raContext.packageName,
1209
+ preferImportedPackageSubpath: preferImportedPackageSubpath
1210
+ }),
1211
+ _groupedByExport = _traceSymbolsToExport.groupedByExport,
1212
+ _crossPackageGroups = _traceSymbolsToExport.crossPackageGroups;
1213
+ var newPath = null;
1214
+ if (_groupedByExport.size === 1 && _crossPackageGroups.size === 0) {
1215
+ var _groupedByExport$keys = _groupedByExport.keys(),
1216
+ _groupedByExport$keys2 = _slicedToArray(_groupedByExport$keys, 1),
1217
+ exportPath = _groupedByExport$keys2[0];
1218
+ newPath = "".concat(raContext.packageName).concat(exportPath.slice(1));
1219
+ } else if (_crossPackageGroups.size === 1 && _groupedByExport.size === 0) {
1220
+ var _crossPackageGroups$k = _crossPackageGroups.keys(),
1221
+ _crossPackageGroups$k2 = _slicedToArray(_crossPackageGroups$k, 1),
1222
+ cpImportPath = _crossPackageGroups$k2[0];
1223
+ newPath = cpImportPath;
1224
+ }
1225
+ var _sourceCode = context.getSourceCode();
1226
+ if (newPath) {
1227
+ var resolvedNewPath = newPath;
1228
+ context.report({
1229
+ node: node,
1230
+ messageId: 'barrelEntryRequireActual',
1231
+ data: {
1232
+ path: raImportPath
1233
+ },
1234
+ fix: function fix(fixer) {
1235
+ var firstArg = node.arguments[0];
1236
+ var quote = _sourceCode.getText(firstArg)[0];
1237
+ return fixer.replaceText(firstArg, "".concat(quote).concat(resolvedNewPath).concat(quote));
1238
+ }
1239
+ });
1240
+ } else {
1241
+ context.report({
1242
+ node: node,
1243
+ messageId: 'barrelEntryRequireActual',
1244
+ data: {
1245
+ path: raImportPath
1246
+ }
1247
+ });
1248
+ }
1249
+ return;
1250
+ }
1013
1251
  if (!isJestMockCall(node)) {
1014
1252
  return;
1015
1253
  }
@@ -1056,17 +1294,22 @@ export function createRule(fs) {
1056
1294
  if (mockProperties.size === 0) {
1057
1295
  return;
1058
1296
  }
1059
- var symbolNames = Array.from(mockProperties.keys());
1060
- var _traceSymbolsToExport = traceSymbolsToExports({
1297
+ var originalMockHadEsModule = mockProperties.has('__esModule');
1298
+ var symbolNames = Array.from(mockProperties.keys()).filter(function (name) {
1299
+ return !ESM_INTEROP_MOCK_KEYS.has(name);
1300
+ });
1301
+ var _traceSymbolsToExport2 = traceSymbolsToExports({
1061
1302
  symbolNames: symbolNames,
1062
1303
  exportMap: mockContext.exportMap,
1063
1304
  exportsMap: mockContext.exportsMap,
1064
1305
  currentExportPath: mockContext.currentExportPath,
1065
- fs: fs
1306
+ fs: fs,
1307
+ barrelPackageName: mockContext.packageName,
1308
+ preferImportedPackageSubpath: preferImportedPackageSubpath
1066
1309
  }),
1067
- groupedByExport = _traceSymbolsToExport.groupedByExport,
1068
- crossPackageGroups = _traceSymbolsToExport.crossPackageGroups,
1069
- unmappedSymbols = _traceSymbolsToExport.unmappedSymbols;
1310
+ groupedByExport = _traceSymbolsToExport2.groupedByExport,
1311
+ crossPackageGroups = _traceSymbolsToExport2.crossPackageGroups,
1312
+ unmappedSymbols = _traceSymbolsToExport2.unmappedSymbols;
1070
1313
 
1071
1314
  // If no symbols can be mapped to specific exports or cross-package sources,
1072
1315
  // there's nothing to fix so don't report an error
@@ -1074,20 +1317,20 @@ export function createRule(fs) {
1074
1317
  return;
1075
1318
  }
1076
1319
  var groups = [];
1077
- var _iterator17 = _createForOfIteratorHelper(groupedByExport),
1078
- _step17;
1320
+ var _iterator19 = _createForOfIteratorHelper(groupedByExport),
1321
+ _step19;
1079
1322
  try {
1080
- for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
1081
- var _step17$value = _slicedToArray(_step17.value, 2),
1082
- exportPath = _step17$value[0],
1083
- symbols = _step17$value[1];
1323
+ for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
1324
+ var _step19$value = _slicedToArray(_step19.value, 2),
1325
+ _exportPath = _step19$value[0],
1326
+ symbols = _step19$value[1];
1084
1327
  // Build name mapping for aliased exports
1085
1328
  var nameMapping = new Map();
1086
- var _iterator22 = _createForOfIteratorHelper(symbols),
1087
- _step22;
1329
+ var _iterator25 = _createForOfIteratorHelper(symbols),
1330
+ _step25;
1088
1331
  try {
1089
- for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
1090
- var s = _step22.value;
1332
+ for (_iterator25.s(); !(_step25 = _iterator25.n()).done;) {
1333
+ var s = _step25.value;
1091
1334
  if (s.originalName) {
1092
1335
  nameMapping.set(s.symbolName, s.originalName);
1093
1336
  }
@@ -1095,16 +1338,16 @@ export function createRule(fs) {
1095
1338
 
1096
1339
  // Check if any symbol in this group is a default export
1097
1340
  } catch (err) {
1098
- _iterator22.e(err);
1341
+ _iterator25.e(err);
1099
1342
  } finally {
1100
- _iterator22.f();
1343
+ _iterator25.f();
1101
1344
  }
1102
1345
  var hasDefaultExport = symbols.some(function (s) {
1103
1346
  return s.originalName === 'default';
1104
1347
  });
1105
1348
  groups.push({
1106
- exportPath: exportPath,
1107
- importPath: "".concat(mockContext.packageName).concat(exportPath.slice(1)),
1349
+ exportPath: _exportPath,
1350
+ importPath: "".concat(mockContext.packageName).concat(_exportPath.slice(1)),
1108
1351
  propertyNames: symbols.map(function (s) {
1109
1352
  return s.symbolName;
1110
1353
  }),
@@ -1118,25 +1361,25 @@ export function createRule(fs) {
1118
1361
 
1119
1362
  // Build cross-package groups
1120
1363
  } catch (err) {
1121
- _iterator17.e(err);
1364
+ _iterator19.e(err);
1122
1365
  } finally {
1123
- _iterator17.f();
1366
+ _iterator19.f();
1124
1367
  }
1125
1368
  var crossPackageMockGroups = [];
1126
- var _iterator18 = _createForOfIteratorHelper(crossPackageGroups),
1127
- _step18;
1369
+ var _iterator20 = _createForOfIteratorHelper(crossPackageGroups),
1370
+ _step20;
1128
1371
  try {
1129
- for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
1130
- var _step18$value = _slicedToArray(_step18.value, 2),
1131
- _importPath = _step18$value[0],
1132
- _symbols = _step18$value[1];
1372
+ for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
1373
+ var _step20$value = _slicedToArray(_step20.value, 2),
1374
+ _importPath = _step20$value[0],
1375
+ _symbols = _step20$value[1];
1133
1376
  // Build name mapping for aliased exports
1134
1377
  var _nameMapping = new Map();
1135
- var _iterator23 = _createForOfIteratorHelper(_symbols),
1136
- _step23;
1378
+ var _iterator26 = _createForOfIteratorHelper(_symbols),
1379
+ _step26;
1137
1380
  try {
1138
- for (_iterator23.s(); !(_step23 = _iterator23.n()).done;) {
1139
- var _s = _step23.value;
1381
+ for (_iterator26.s(); !(_step26 = _iterator26.n()).done;) {
1382
+ var _s = _step26.value;
1140
1383
  if (_s.originalName) {
1141
1384
  _nameMapping.set(_s.symbolName, _s.originalName);
1142
1385
  }
@@ -1144,9 +1387,9 @@ export function createRule(fs) {
1144
1387
 
1145
1388
  // Check if any symbol in this group is a default export
1146
1389
  } catch (err) {
1147
- _iterator23.e(err);
1390
+ _iterator26.e(err);
1148
1391
  } finally {
1149
- _iterator23.f();
1392
+ _iterator26.f();
1150
1393
  }
1151
1394
  var _hasDefaultExport = _symbols.some(function (s) {
1152
1395
  return s.originalName === 'default';
@@ -1154,8 +1397,9 @@ export function createRule(fs) {
1154
1397
 
1155
1398
  // Get cross-package source info from the first symbol (all symbols in same group have same source)
1156
1399
  var crossPackageSource = _symbols[0].crossPackageSource;
1400
+ var bridgeExportPath = _symbols[0].barrelBridgeExportPath;
1157
1401
  crossPackageMockGroups.push({
1158
- exportPath: crossPackageSource.exportPath,
1402
+ exportPath: bridgeExportPath !== null && bridgeExportPath !== void 0 ? bridgeExportPath : crossPackageSource.exportPath,
1159
1403
  importPath: _importPath,
1160
1404
  propertyNames: _symbols.map(function (s) {
1161
1405
  return s.symbolName;
@@ -1168,9 +1412,9 @@ export function createRule(fs) {
1168
1412
  });
1169
1413
  }
1170
1414
  } catch (err) {
1171
- _iterator18.e(err);
1415
+ _iterator20.e(err);
1172
1416
  } finally {
1173
- _iterator18.f();
1417
+ _iterator20.f();
1174
1418
  }
1175
1419
  if (unmappedSymbols.length > 0) {
1176
1420
  groups.push({
@@ -1212,11 +1456,11 @@ export function createRule(fs) {
1212
1456
  if (existingMock && existingMock.node !== node) {
1213
1457
  // Merge properties from existing mock with new properties
1214
1458
  var newPropertiesMap = new Map();
1215
- var _iterator19 = _createForOfIteratorHelper(group.propertyNames),
1216
- _step19;
1459
+ var _iterator21 = _createForOfIteratorHelper(group.propertyNames),
1460
+ _step21;
1217
1461
  try {
1218
- for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
1219
- var propName = _step19.value;
1462
+ for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
1463
+ var propName = _step21.value;
1220
1464
  var propInfo = mockProperties.get(propName);
1221
1465
  if (propInfo) {
1222
1466
  // Check if this property needs to be renamed (aliased export)
@@ -1237,9 +1481,9 @@ export function createRule(fs) {
1237
1481
  }
1238
1482
  }
1239
1483
  } catch (err) {
1240
- _iterator19.e(err);
1484
+ _iterator21.e(err);
1241
1485
  } finally {
1242
- _iterator19.f();
1486
+ _iterator21.f();
1243
1487
  }
1244
1488
  var mergedProperties = mergeMockProperties({
1245
1489
  existingProperties: existingMock.properties,
@@ -1251,10 +1495,10 @@ export function createRule(fs) {
1251
1495
  exportPath: group.exportPath,
1252
1496
  importPath: group.importPath,
1253
1497
  propertyNames: Array.from(mergedProperties.keys()),
1254
- propertyTexts: new Map(Array.from(mergedProperties.entries()).map(function (_ref15) {
1255
- var _ref16 = _slicedToArray(_ref15, 2),
1256
- k = _ref16[0],
1257
- v = _ref16[1];
1498
+ propertyTexts: new Map(Array.from(mergedProperties.entries()).map(function (_ref17) {
1499
+ var _ref18 = _slicedToArray(_ref17, 2),
1500
+ k = _ref18[0],
1501
+ v = _ref18[1];
1258
1502
  return [k, v.text];
1259
1503
  })),
1260
1504
  nameMapping: new Map(),
@@ -1269,32 +1513,46 @@ export function createRule(fs) {
1269
1513
  mergedGroups.push(group);
1270
1514
  }
1271
1515
  }
1272
- var fixText = generateMockFixes({
1273
- groups: mergedGroups,
1274
- crossPackageGroups: crossPackageMockGroups,
1275
- packageName: mockContext.packageName,
1276
- mockProperties: mockProperties,
1277
- quote: quote,
1278
- preambleStatements: preambleStatements
1279
- });
1280
-
1281
- // Build a map of symbol name -> new import path for jest.requireMock() rewriting
1282
1516
  var symbolToNewImportPath = new Map();
1283
1517
  for (var _i4 = 0, _arr = [].concat(mergedGroups, crossPackageMockGroups); _i4 < _arr.length; _i4++) {
1284
1518
  var _group2 = _arr[_i4];
1285
- var _iterator20 = _createForOfIteratorHelper(_group2.propertyNames),
1286
- _step20;
1519
+ var _iterator22 = _createForOfIteratorHelper(_group2.propertyNames),
1520
+ _step22;
1287
1521
  try {
1288
- for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
1289
- var _propName = _step20.value;
1522
+ for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
1523
+ var _propName = _step22.value;
1290
1524
  symbolToNewImportPath.set(_propName, _group2.importPath);
1291
1525
  }
1292
1526
  } catch (err) {
1293
- _iterator20.e(err);
1527
+ _iterator22.e(err);
1294
1528
  } finally {
1295
- _iterator20.f();
1529
+ _iterator22.f();
1296
1530
  }
1297
1531
  }
1532
+ var fixText = generateMockFixes({
1533
+ groups: mergedGroups,
1534
+ crossPackageGroups: crossPackageMockGroups,
1535
+ packageName: mockContext.packageName,
1536
+ mockProperties: mockProperties,
1537
+ quote: quote,
1538
+ preambleStatements: preambleStatements,
1539
+ propagateEsModuleFromOriginalMock: originalMockHadEsModule,
1540
+ oldBarrelImportPath: oldImportPath,
1541
+ symbolToNewImportPath: symbolToNewImportPath
1542
+ });
1543
+
1544
+ // Post-process fixText to update jest.requireActual('barrel').Symbol
1545
+ // references embedded in property texts (e.g. inside jest.fn callbacks)
1546
+ fixText = fixText.replace(/jest\.requireActual(?:<[^>]*>)?\((['"])([^'"]+)\1\)\.(\w+)/g, function (match, _q, path, symbol) {
1547
+ if (path !== oldImportPath) {
1548
+ return match;
1549
+ }
1550
+ var newPath = symbolToNewImportPath.get(symbol);
1551
+ if (newPath && newPath !== path) {
1552
+ return match.replace(path, newPath);
1553
+ }
1554
+ return match;
1555
+ });
1298
1556
 
1299
1557
  // Sort nodes by position
1300
1558
  var sortedNodesToRemove = nodesToRemove.sort(function (a, b) {
@@ -1341,27 +1599,78 @@ export function createRule(fs) {
1341
1599
  return candidatePath === oldImportPath;
1342
1600
  }
1343
1601
  });
1344
- var _iterator21 = _createForOfIteratorHelper(requireMockCalls),
1345
- _step21;
1602
+ var _iterator23 = _createForOfIteratorHelper(requireMockCalls),
1603
+ _step23;
1346
1604
  try {
1347
- for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
1348
- var requireMockNode = _step21.value;
1605
+ for (_iterator23.s(); !(_step23 = _iterator23.n()).done;) {
1606
+ var requireMockNode = _step23.value;
1349
1607
  var requireMockArg = requireMockNode.arguments[0];
1350
1608
  if (!requireMockArg) {
1351
1609
  continue;
1352
1610
  }
1353
- var newPath = resolveNewPathForRequireMock({
1611
+ var _newPath = resolveNewPathForRequireMock({
1354
1612
  requireMockNode: requireMockNode,
1355
1613
  symbolToNewPath: symbolToNewImportPath
1356
1614
  });
1357
- if (newPath) {
1358
- fixes.push(fixer.replaceText(requireMockArg, "".concat(quote).concat(newPath).concat(quote)));
1615
+ if (_newPath) {
1616
+ fixes.push(fixer.replaceText(requireMockArg, "".concat(quote).concat(_newPath).concat(quote)));
1359
1617
  }
1360
1618
  }
1619
+
1620
+ // Fix jest.requireActual() calls that reference the old barrel path.
1621
+ // Only fix calls OUTSIDE the replaced jest.mock node range
1622
+ // (calls inside it are handled via fixText string replacement below).
1623
+ } catch (err) {
1624
+ _iterator23.e(err);
1625
+ } finally {
1626
+ _iterator23.f();
1627
+ }
1628
+ var replacedRanges = sortedNodesToRemove.map(function (n) {
1629
+ return n.range;
1630
+ });
1631
+ var requireActualCalls = findJestRequireActualCalls({
1632
+ ast: ast,
1633
+ matchPath: function matchPath(candidatePath) {
1634
+ return candidatePath === oldImportPath;
1635
+ }
1636
+ });
1637
+ var _iterator24 = _createForOfIteratorHelper(requireActualCalls),
1638
+ _step24;
1639
+ try {
1640
+ var _loop = function _loop() {
1641
+ var raNode = _step24.value;
1642
+ var raArg = raNode.arguments[0];
1643
+ if (!raArg || !raNode.range) {
1644
+ return 0; // continue
1645
+ }
1646
+
1647
+ // Skip calls inside any node being replaced (ranges overlap)
1648
+ var insideReplacedNode = replacedRanges.some(function (_ref19) {
1649
+ var _ref20 = _slicedToArray(_ref19, 2),
1650
+ start = _ref20[0],
1651
+ end = _ref20[1];
1652
+ return raNode.range[0] >= start && raNode.range[1] <= end;
1653
+ });
1654
+ if (insideReplacedNode) {
1655
+ return 0; // continue
1656
+ }
1657
+ var newPath = resolveNewPathForRequireMock({
1658
+ requireMockNode: raNode,
1659
+ symbolToNewPath: symbolToNewImportPath
1660
+ });
1661
+ if (newPath) {
1662
+ fixes.push(fixer.replaceText(raArg, "".concat(quote).concat(newPath).concat(quote)));
1663
+ }
1664
+ },
1665
+ _ret;
1666
+ for (_iterator24.s(); !(_step24 = _iterator24.n()).done;) {
1667
+ _ret = _loop();
1668
+ if (_ret === 0) continue;
1669
+ }
1361
1670
  } catch (err) {
1362
- _iterator21.e(err);
1671
+ _iterator24.e(err);
1363
1672
  } finally {
1364
- _iterator21.f();
1673
+ _iterator24.f();
1365
1674
  }
1366
1675
  return fixes;
1367
1676
  }