@atlaskit/eslint-plugin-platform 2.8.0 → 2.9.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.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/rules/ensure-use-sync-external-store-server-snapshot/index.js +41 -0
- package/dist/cjs/rules/import/no-barrel-entry-imports/index.js +475 -67
- package/dist/cjs/rules/import/no-barrel-entry-jest-mock/index.js +387 -112
- package/dist/cjs/rules/import/no-jest-mock-barrel-files/index.js +3 -2
- package/dist/cjs/rules/import/no-relative-barrel-file-imports/index.js +7 -3
- package/dist/cjs/rules/import/shared/jest-utils.js +62 -9
- package/dist/cjs/rules/import/shared/package-resolution.js +156 -23
- package/dist/cjs/rules/visit-example-type-import-required/index.js +409 -0
- package/dist/es2019/index.js +6 -1
- package/dist/es2019/rules/ensure-use-sync-external-store-server-snapshot/index.js +43 -0
- package/dist/es2019/rules/import/no-barrel-entry-imports/index.js +372 -15
- package/dist/es2019/rules/import/no-barrel-entry-jest-mock/index.js +245 -17
- package/dist/es2019/rules/import/no-jest-mock-barrel-files/index.js +3 -2
- package/dist/es2019/rules/import/no-relative-barrel-file-imports/index.js +7 -3
- package/dist/es2019/rules/import/shared/jest-utils.js +44 -0
- package/dist/es2019/rules/import/shared/package-resolution.js +97 -5
- package/dist/es2019/rules/visit-example-type-import-required/index.js +375 -0
- package/dist/esm/index.js +6 -1
- package/dist/esm/rules/ensure-use-sync-external-store-server-snapshot/index.js +35 -0
- package/dist/esm/rules/import/no-barrel-entry-imports/index.js +475 -67
- package/dist/esm/rules/import/no-barrel-entry-jest-mock/index.js +388 -113
- package/dist/esm/rules/import/no-jest-mock-barrel-files/index.js +3 -2
- package/dist/esm/rules/import/no-relative-barrel-file-imports/index.js +7 -3
- package/dist/esm/rules/import/shared/jest-utils.js +61 -9
- package/dist/esm/rules/import/shared/package-resolution.js +156 -25
- package/dist/esm/rules/visit-example-type-import-required/index.js +402 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/rules/ensure-use-sync-external-store-server-snapshot/index.d.ts +3 -0
- package/dist/types/rules/import/shared/jest-utils.d.ts +8 -0
- package/dist/types/rules/import/shared/package-resolution.d.ts +22 -2
- package/dist/types/rules/visit-example-type-import-required/index.d.ts +4 -0
- package/dist/types-ts4.5/index.d.ts +12 -0
- package/dist/types-ts4.5/rules/ensure-use-sync-external-store-server-snapshot/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/import/shared/jest-utils.d.ts +8 -0
- package/dist/types-ts4.5/rules/import/shared/package-resolution.d.ts +22 -2
- package/dist/types-ts4.5/rules/visit-example-type-import-required/index.d.ts +4 -0
- package/package.json +3 -1
|
@@ -8,7 +8,7 @@ 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
13
|
import { findExportForSourceFile, parsePackageExports } from '../shared/package-resolution';
|
|
14
14
|
import { realFileSystem } from '../shared/types';
|
|
@@ -670,6 +670,7 @@ function traceSymbolsToExports(_ref10) {
|
|
|
670
670
|
_step13;
|
|
671
671
|
try {
|
|
672
672
|
for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
|
|
673
|
+
var _findExportForSourceF, _findExportForSourceF2;
|
|
673
674
|
var symbolName = _step13.value;
|
|
674
675
|
var exportInfo = exportMap.get(symbolName);
|
|
675
676
|
if (!exportInfo) {
|
|
@@ -694,10 +695,10 @@ function traceSymbolsToExports(_ref10) {
|
|
|
694
695
|
}
|
|
695
696
|
|
|
696
697
|
// First try to find an export that directly exposes the source file
|
|
697
|
-
var targetExportPath = findExportForSourceFile({
|
|
698
|
+
var targetExportPath = (_findExportForSourceF = (_findExportForSourceF2 = findExportForSourceFile({
|
|
698
699
|
sourceFilePath: exportInfo.path,
|
|
699
700
|
exportsMap: exportsMap
|
|
700
|
-
});
|
|
701
|
+
})) === null || _findExportForSourceF2 === void 0 ? void 0 : _findExportForSourceF2.exportPath) !== null && _findExportForSourceF !== void 0 ? _findExportForSourceF : null;
|
|
701
702
|
|
|
702
703
|
// If no direct match, check which export can provide this symbol
|
|
703
704
|
// (handles nested barrels where the symbol is re-exported through intermediate files)
|
|
@@ -757,16 +758,80 @@ function escapeRegExp(str) {
|
|
|
757
758
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
758
759
|
}
|
|
759
760
|
|
|
761
|
+
/** Mock object keys that are module interop metadata, not package exports. */
|
|
762
|
+
var ESM_INTEROP_MOCK_KEYS = new Set(['__esModule']);
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* If a preamble line is `const|let actual = jest.requireActual('<barrel>')`, rewrite the specifier to
|
|
766
|
+
* `targetImportPathForThisMock` when every `binding.<prop>` read in this split mock's implementation
|
|
767
|
+
* resolves to that same path via `symbolToNewImportPath`. Otherwise leave unchanged (e.g. mixed paths
|
|
768
|
+
* still need the barrel module).
|
|
769
|
+
*/
|
|
770
|
+
function rewritePreambleLineBarrelRequireActual(_ref12) {
|
|
771
|
+
var lineText = _ref12.lineText,
|
|
772
|
+
oldBarrelPath = _ref12.oldBarrelPath,
|
|
773
|
+
targetImportPathForThisMock = _ref12.targetImportPathForThisMock,
|
|
774
|
+
mockImplementationTextForGroup = _ref12.mockImplementationTextForGroup,
|
|
775
|
+
symbolToNewImportPath = _ref12.symbolToNewImportPath;
|
|
776
|
+
var requireActualRe = /jest\.requireActual(?:<[^>]*>)?\((['"])([^'"]+)\1\)/;
|
|
777
|
+
var requireMatch = requireActualRe.exec(lineText);
|
|
778
|
+
if (!requireMatch || requireMatch[2] !== oldBarrelPath) {
|
|
779
|
+
return lineText;
|
|
780
|
+
}
|
|
781
|
+
var quote = requireMatch[1];
|
|
782
|
+
var bindingMatch = /^\s*(?:const|let)\s+(\w+)\s*=/m.exec(lineText);
|
|
783
|
+
if (!bindingMatch) {
|
|
784
|
+
return lineText;
|
|
785
|
+
}
|
|
786
|
+
var binding = bindingMatch[1];
|
|
787
|
+
var propAccessRe = new RegExp("\\b".concat(escapeRegExp(binding), "\\.(\\w+)"), 'g');
|
|
788
|
+
var accessedProps = new Set();
|
|
789
|
+
var propMatch;
|
|
790
|
+
while ((propMatch = propAccessRe.exec(mockImplementationTextForGroup)) !== null) {
|
|
791
|
+
accessedProps.add(propMatch[1]);
|
|
792
|
+
}
|
|
793
|
+
if (accessedProps.size === 0) {
|
|
794
|
+
return lineText;
|
|
795
|
+
}
|
|
796
|
+
var resolvedPaths = [];
|
|
797
|
+
var _iterator14 = _createForOfIteratorHelper(accessedProps),
|
|
798
|
+
_step14;
|
|
799
|
+
try {
|
|
800
|
+
for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
|
|
801
|
+
var prop = _step14.value;
|
|
802
|
+
var mapped = symbolToNewImportPath.get(prop);
|
|
803
|
+
if (mapped) {
|
|
804
|
+
resolvedPaths.push(mapped);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
} catch (err) {
|
|
808
|
+
_iterator14.e(err);
|
|
809
|
+
} finally {
|
|
810
|
+
_iterator14.f();
|
|
811
|
+
}
|
|
812
|
+
if (resolvedPaths.length === 0) {
|
|
813
|
+
return lineText;
|
|
814
|
+
}
|
|
815
|
+
var uniquePaths = new Set(resolvedPaths);
|
|
816
|
+
if (uniquePaths.size !== 1 || !uniquePaths.has(targetImportPathForThisMock)) {
|
|
817
|
+
return lineText;
|
|
818
|
+
}
|
|
819
|
+
return lineText.replace("jest.requireActual(".concat(quote).concat(oldBarrelPath).concat(quote, ")"), "jest.requireActual(".concat(quote).concat(targetImportPathForThisMock).concat(quote, ")"));
|
|
820
|
+
}
|
|
821
|
+
|
|
760
822
|
/**
|
|
761
823
|
* Generate fix text for multiple jest.mock calls
|
|
762
824
|
*/
|
|
763
|
-
function generateMockFixes(
|
|
764
|
-
var groups =
|
|
765
|
-
crossPackageGroups =
|
|
766
|
-
packageName =
|
|
767
|
-
mockProperties =
|
|
768
|
-
quote =
|
|
769
|
-
preambleStatements =
|
|
825
|
+
function generateMockFixes(_ref13) {
|
|
826
|
+
var groups = _ref13.groups,
|
|
827
|
+
crossPackageGroups = _ref13.crossPackageGroups,
|
|
828
|
+
packageName = _ref13.packageName,
|
|
829
|
+
mockProperties = _ref13.mockProperties,
|
|
830
|
+
quote = _ref13.quote,
|
|
831
|
+
preambleStatements = _ref13.preambleStatements,
|
|
832
|
+
propagateEsModuleFromOriginalMock = _ref13.propagateEsModuleFromOriginalMock,
|
|
833
|
+
oldBarrelImportPath = _ref13.oldBarrelImportPath,
|
|
834
|
+
symbolToNewImportPath = _ref13.symbolToNewImportPath;
|
|
770
835
|
var mockCalls = [];
|
|
771
836
|
|
|
772
837
|
// Helper to generate a single mock call
|
|
@@ -774,15 +839,15 @@ function generateMockFixes(_ref12) {
|
|
|
774
839
|
var propTexts = [];
|
|
775
840
|
propTexts.push("...jest.requireActual(".concat(quote).concat(fullImportPath).concat(quote, ")"));
|
|
776
841
|
|
|
777
|
-
// Add __esModule: true when mocking default exports
|
|
778
|
-
if (group.hasDefaultExport) {
|
|
842
|
+
// Add __esModule: true when mocking default exports, or when the original mock already used __esModule (apply to every split).
|
|
843
|
+
if (group.hasDefaultExport || propagateEsModuleFromOriginalMock) {
|
|
779
844
|
propTexts.push('__esModule: true');
|
|
780
845
|
}
|
|
781
|
-
var
|
|
782
|
-
|
|
846
|
+
var _iterator15 = _createForOfIteratorHelper(group.propertyNames),
|
|
847
|
+
_step15;
|
|
783
848
|
try {
|
|
784
|
-
for (
|
|
785
|
-
var propName =
|
|
849
|
+
for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
|
|
850
|
+
var propName = _step15.value;
|
|
786
851
|
// First try to get from group's propertyTexts (used for merged mocks)
|
|
787
852
|
var groupPropText = group.propertyTexts.get(propName);
|
|
788
853
|
if (groupPropText) {
|
|
@@ -816,21 +881,34 @@ function generateMockFixes(_ref12) {
|
|
|
816
881
|
}
|
|
817
882
|
}
|
|
818
883
|
}
|
|
819
|
-
|
|
820
|
-
// Determine if we need preamble for this group
|
|
821
884
|
} catch (err) {
|
|
822
|
-
|
|
885
|
+
_iterator15.e(err);
|
|
823
886
|
} finally {
|
|
824
|
-
|
|
887
|
+
_iterator15.f();
|
|
825
888
|
}
|
|
889
|
+
var combinedGroupImplText = group.propertyNames.map(function (name) {
|
|
890
|
+
var _ref14, _group$propertyTexts$, _mockProperties$get;
|
|
891
|
+
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 : '';
|
|
892
|
+
}).join('\n');
|
|
893
|
+
|
|
894
|
+
// Determine if we need preamble for this group
|
|
826
895
|
var neededPreamble = getNeededPreamble({
|
|
827
896
|
propertyTexts: propTexts,
|
|
828
897
|
allPreamble: preambleStatements
|
|
829
898
|
});
|
|
899
|
+
var rewrittenPreamble = neededPreamble.map(function (p) {
|
|
900
|
+
return rewritePreambleLineBarrelRequireActual({
|
|
901
|
+
lineText: p.text,
|
|
902
|
+
oldBarrelPath: oldBarrelImportPath,
|
|
903
|
+
targetImportPathForThisMock: fullImportPath,
|
|
904
|
+
mockImplementationTextForGroup: combinedGroupImplText,
|
|
905
|
+
symbolToNewImportPath: symbolToNewImportPath
|
|
906
|
+
});
|
|
907
|
+
});
|
|
830
908
|
if (neededPreamble.length > 0) {
|
|
831
909
|
// Generate block body arrow function with preamble
|
|
832
|
-
var preambleLines =
|
|
833
|
-
return "\t".concat(
|
|
910
|
+
var preambleLines = rewrittenPreamble.map(function (text) {
|
|
911
|
+
return "\t".concat(text);
|
|
834
912
|
}).join('\n');
|
|
835
913
|
var formattedProps = propTexts.map(function (p) {
|
|
836
914
|
return "\t\t".concat(p, ",");
|
|
@@ -846,34 +924,34 @@ function generateMockFixes(_ref12) {
|
|
|
846
924
|
};
|
|
847
925
|
|
|
848
926
|
// Generate mocks for cross-package groups first
|
|
849
|
-
var
|
|
850
|
-
|
|
927
|
+
var _iterator16 = _createForOfIteratorHelper(crossPackageGroups),
|
|
928
|
+
_step16;
|
|
851
929
|
try {
|
|
852
|
-
for (
|
|
853
|
-
var group =
|
|
930
|
+
for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
|
|
931
|
+
var group = _step16.value;
|
|
854
932
|
mockCalls.push(generateMockCall(group, group.importPath));
|
|
855
933
|
}
|
|
856
934
|
|
|
857
935
|
// Generate mocks for same-package groups
|
|
858
936
|
} catch (err) {
|
|
859
|
-
|
|
937
|
+
_iterator16.e(err);
|
|
860
938
|
} finally {
|
|
861
|
-
|
|
939
|
+
_iterator16.f();
|
|
862
940
|
}
|
|
863
|
-
var
|
|
864
|
-
|
|
941
|
+
var _iterator17 = _createForOfIteratorHelper(groups),
|
|
942
|
+
_step17;
|
|
865
943
|
try {
|
|
866
|
-
for (
|
|
867
|
-
var _group =
|
|
944
|
+
for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
|
|
945
|
+
var _group = _step17.value;
|
|
868
946
|
var fullImportPath = "".concat(packageName).concat(_group.exportPath.slice(1));
|
|
869
947
|
mockCalls.push(generateMockCall(_group, fullImportPath));
|
|
870
948
|
}
|
|
871
949
|
|
|
872
950
|
// Join with semicolons but don't add trailing semicolon
|
|
873
951
|
} catch (err) {
|
|
874
|
-
|
|
952
|
+
_iterator17.e(err);
|
|
875
953
|
} finally {
|
|
876
|
-
|
|
954
|
+
_iterator17.f();
|
|
877
955
|
}
|
|
878
956
|
return mockCalls.join(';\n');
|
|
879
957
|
}
|
|
@@ -886,11 +964,11 @@ function generateMockFixes(_ref12) {
|
|
|
886
964
|
* Resolves jest.mock context for barrel file analysis.
|
|
887
965
|
* Returns null if the mock should not be processed.
|
|
888
966
|
*/
|
|
889
|
-
function resolveJestMockContext(
|
|
890
|
-
var importPath =
|
|
891
|
-
workspaceRoot =
|
|
892
|
-
fs =
|
|
893
|
-
applyToImportsFrom =
|
|
967
|
+
function resolveJestMockContext(_ref15) {
|
|
968
|
+
var importPath = _ref15.importPath,
|
|
969
|
+
workspaceRoot = _ref15.workspaceRoot,
|
|
970
|
+
fs = _ref15.fs,
|
|
971
|
+
applyToImportsFrom = _ref15.applyToImportsFrom;
|
|
894
972
|
if (isRelativeImport(importPath)) {
|
|
895
973
|
return null;
|
|
896
974
|
}
|
|
@@ -953,9 +1031,9 @@ function resolveJestMockContext(_ref13) {
|
|
|
953
1031
|
/**
|
|
954
1032
|
* Check if the entry file is a barrel file (re-exports from other files)
|
|
955
1033
|
*/
|
|
956
|
-
function isBarrelFile(
|
|
957
|
-
var exportMap =
|
|
958
|
-
entryFilePath =
|
|
1034
|
+
function isBarrelFile(_ref16) {
|
|
1035
|
+
var exportMap = _ref16.exportMap,
|
|
1036
|
+
entryFilePath = _ref16.entryFilePath;
|
|
959
1037
|
return hasReExportsFromOtherFiles({
|
|
960
1038
|
exportMap: exportMap,
|
|
961
1039
|
sourceFilePath: entryFilePath
|
|
@@ -987,7 +1065,8 @@ var ruleMeta = {
|
|
|
987
1065
|
additionalProperties: false
|
|
988
1066
|
}],
|
|
989
1067
|
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."
|
|
1068
|
+
barrelEntryMock: "jest.mock('{{path}}') is mocking a barrel file entry point. Split into separate mocks for each source file using package.json exports.",
|
|
1069
|
+
barrelEntryRequireActual: "jest.requireActual('{{path}}') references a barrel file entry point. Use a specific package.json export path instead."
|
|
991
1070
|
}
|
|
992
1071
|
};
|
|
993
1072
|
|
|
@@ -1010,6 +1089,134 @@ export function createRule(fs) {
|
|
|
1010
1089
|
return {
|
|
1011
1090
|
CallExpression: function CallExpression(rawNode) {
|
|
1012
1091
|
var node = rawNode;
|
|
1092
|
+
|
|
1093
|
+
// Handle standalone jest.requireActual() calls that reference barrel entries.
|
|
1094
|
+
// e.g. jest.requireActual('@atlaskit/pkg').Foo or const { Foo } = jest.requireActual('@atlaskit/pkg')
|
|
1095
|
+
if (isJestRequireActual(node)) {
|
|
1096
|
+
var raImportPath = extractImportPath(node);
|
|
1097
|
+
if (!raImportPath) {
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
var raContext = resolveJestMockContext({
|
|
1101
|
+
importPath: raImportPath,
|
|
1102
|
+
workspaceRoot: workspaceRoot,
|
|
1103
|
+
fs: fs,
|
|
1104
|
+
applyToImportsFrom: applyToImportsFrom
|
|
1105
|
+
});
|
|
1106
|
+
if (!raContext) {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
if (!isBarrelFile({
|
|
1110
|
+
exportMap: raContext.exportMap,
|
|
1111
|
+
entryFilePath: raContext.entryFilePath
|
|
1112
|
+
})) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// `jest.requireActual('<barrel>')` inside `jest.mock('<barrel>')` is handled by the mock
|
|
1117
|
+
// rule's fix (preamble retargeting + `jest.requireActual('barrel').x` rewriting), including
|
|
1118
|
+
// `const actual = jest.requireActual('<barrel>')` with no member access on the call.
|
|
1119
|
+
// Skip standalone handling here to avoid duplicate diagnostics.
|
|
1120
|
+
var ancestor = node.parent;
|
|
1121
|
+
while (ancestor) {
|
|
1122
|
+
if (ancestor.type === 'CallExpression' && isJestMockCall(ancestor)) {
|
|
1123
|
+
var ancestorPath = extractImportPath(ancestor);
|
|
1124
|
+
if (ancestorPath) {
|
|
1125
|
+
var ancestorCtx = resolveJestMockContext({
|
|
1126
|
+
importPath: ancestorPath,
|
|
1127
|
+
workspaceRoot: workspaceRoot,
|
|
1128
|
+
fs: fs,
|
|
1129
|
+
applyToImportsFrom: applyToImportsFrom
|
|
1130
|
+
});
|
|
1131
|
+
if (ancestorCtx && isBarrelFile({
|
|
1132
|
+
exportMap: ancestorCtx.exportMap,
|
|
1133
|
+
entryFilePath: ancestorCtx.entryFilePath
|
|
1134
|
+
})) {
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
ancestor = ancestor.parent;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
// Determine which symbols are accessed from the barrel
|
|
1143
|
+
var parent = node.parent;
|
|
1144
|
+
var accessedSymbols = [];
|
|
1145
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'MemberExpression' && parent.property.type === 'Identifier') {
|
|
1146
|
+
accessedSymbols.push(parent.property.name);
|
|
1147
|
+
} else if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'VariableDeclarator' && parent.id.type === 'ObjectPattern') {
|
|
1148
|
+
var _iterator18 = _createForOfIteratorHelper(parent.id.properties),
|
|
1149
|
+
_step18;
|
|
1150
|
+
try {
|
|
1151
|
+
for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
|
|
1152
|
+
var prop = _step18.value;
|
|
1153
|
+
if (prop.type === 'Property' && prop.key.type === 'Identifier') {
|
|
1154
|
+
accessedSymbols.push(prop.key.name);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
} catch (err) {
|
|
1158
|
+
_iterator18.e(err);
|
|
1159
|
+
} finally {
|
|
1160
|
+
_iterator18.f();
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
if (accessedSymbols.length === 0) {
|
|
1164
|
+
context.report({
|
|
1165
|
+
node: node,
|
|
1166
|
+
messageId: 'barrelEntryRequireActual',
|
|
1167
|
+
data: {
|
|
1168
|
+
path: raImportPath
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
var _traceSymbolsToExport = traceSymbolsToExports({
|
|
1174
|
+
symbolNames: accessedSymbols,
|
|
1175
|
+
exportMap: raContext.exportMap,
|
|
1176
|
+
exportsMap: raContext.exportsMap,
|
|
1177
|
+
currentExportPath: raContext.currentExportPath,
|
|
1178
|
+
fs: fs
|
|
1179
|
+
}),
|
|
1180
|
+
_groupedByExport = _traceSymbolsToExport.groupedByExport,
|
|
1181
|
+
_crossPackageGroups = _traceSymbolsToExport.crossPackageGroups;
|
|
1182
|
+
var newPath = null;
|
|
1183
|
+
if (_groupedByExport.size === 1 && _crossPackageGroups.size === 0) {
|
|
1184
|
+
var _groupedByExport$keys = _groupedByExport.keys(),
|
|
1185
|
+
_groupedByExport$keys2 = _slicedToArray(_groupedByExport$keys, 1),
|
|
1186
|
+
exportPath = _groupedByExport$keys2[0];
|
|
1187
|
+
newPath = "".concat(raContext.packageName).concat(exportPath.slice(1));
|
|
1188
|
+
} else if (_crossPackageGroups.size === 1 && _groupedByExport.size === 0) {
|
|
1189
|
+
var _crossPackageGroups$k = _crossPackageGroups.keys(),
|
|
1190
|
+
_crossPackageGroups$k2 = _slicedToArray(_crossPackageGroups$k, 1),
|
|
1191
|
+
cpImportPath = _crossPackageGroups$k2[0];
|
|
1192
|
+
newPath = cpImportPath;
|
|
1193
|
+
}
|
|
1194
|
+
var _sourceCode = context.getSourceCode();
|
|
1195
|
+
if (newPath) {
|
|
1196
|
+
var resolvedNewPath = newPath;
|
|
1197
|
+
context.report({
|
|
1198
|
+
node: node,
|
|
1199
|
+
messageId: 'barrelEntryRequireActual',
|
|
1200
|
+
data: {
|
|
1201
|
+
path: raImportPath
|
|
1202
|
+
},
|
|
1203
|
+
fix: function fix(fixer) {
|
|
1204
|
+
var firstArg = node.arguments[0];
|
|
1205
|
+
var quote = _sourceCode.getText(firstArg)[0];
|
|
1206
|
+
return fixer.replaceText(firstArg, "".concat(quote).concat(resolvedNewPath).concat(quote));
|
|
1207
|
+
}
|
|
1208
|
+
});
|
|
1209
|
+
} else {
|
|
1210
|
+
context.report({
|
|
1211
|
+
node: node,
|
|
1212
|
+
messageId: 'barrelEntryRequireActual',
|
|
1213
|
+
data: {
|
|
1214
|
+
path: raImportPath
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1013
1220
|
if (!isJestMockCall(node)) {
|
|
1014
1221
|
return;
|
|
1015
1222
|
}
|
|
@@ -1056,17 +1263,20 @@ export function createRule(fs) {
|
|
|
1056
1263
|
if (mockProperties.size === 0) {
|
|
1057
1264
|
return;
|
|
1058
1265
|
}
|
|
1059
|
-
var
|
|
1060
|
-
var
|
|
1266
|
+
var originalMockHadEsModule = mockProperties.has('__esModule');
|
|
1267
|
+
var symbolNames = Array.from(mockProperties.keys()).filter(function (name) {
|
|
1268
|
+
return !ESM_INTEROP_MOCK_KEYS.has(name);
|
|
1269
|
+
});
|
|
1270
|
+
var _traceSymbolsToExport2 = traceSymbolsToExports({
|
|
1061
1271
|
symbolNames: symbolNames,
|
|
1062
1272
|
exportMap: mockContext.exportMap,
|
|
1063
1273
|
exportsMap: mockContext.exportsMap,
|
|
1064
1274
|
currentExportPath: mockContext.currentExportPath,
|
|
1065
1275
|
fs: fs
|
|
1066
1276
|
}),
|
|
1067
|
-
groupedByExport =
|
|
1068
|
-
crossPackageGroups =
|
|
1069
|
-
unmappedSymbols =
|
|
1277
|
+
groupedByExport = _traceSymbolsToExport2.groupedByExport,
|
|
1278
|
+
crossPackageGroups = _traceSymbolsToExport2.crossPackageGroups,
|
|
1279
|
+
unmappedSymbols = _traceSymbolsToExport2.unmappedSymbols;
|
|
1070
1280
|
|
|
1071
1281
|
// If no symbols can be mapped to specific exports or cross-package sources,
|
|
1072
1282
|
// there's nothing to fix so don't report an error
|
|
@@ -1074,20 +1284,20 @@ export function createRule(fs) {
|
|
|
1074
1284
|
return;
|
|
1075
1285
|
}
|
|
1076
1286
|
var groups = [];
|
|
1077
|
-
var
|
|
1078
|
-
|
|
1287
|
+
var _iterator19 = _createForOfIteratorHelper(groupedByExport),
|
|
1288
|
+
_step19;
|
|
1079
1289
|
try {
|
|
1080
|
-
for (
|
|
1081
|
-
var
|
|
1082
|
-
|
|
1083
|
-
symbols =
|
|
1290
|
+
for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
|
|
1291
|
+
var _step19$value = _slicedToArray(_step19.value, 2),
|
|
1292
|
+
_exportPath = _step19$value[0],
|
|
1293
|
+
symbols = _step19$value[1];
|
|
1084
1294
|
// Build name mapping for aliased exports
|
|
1085
1295
|
var nameMapping = new Map();
|
|
1086
|
-
var
|
|
1087
|
-
|
|
1296
|
+
var _iterator25 = _createForOfIteratorHelper(symbols),
|
|
1297
|
+
_step25;
|
|
1088
1298
|
try {
|
|
1089
|
-
for (
|
|
1090
|
-
var s =
|
|
1299
|
+
for (_iterator25.s(); !(_step25 = _iterator25.n()).done;) {
|
|
1300
|
+
var s = _step25.value;
|
|
1091
1301
|
if (s.originalName) {
|
|
1092
1302
|
nameMapping.set(s.symbolName, s.originalName);
|
|
1093
1303
|
}
|
|
@@ -1095,16 +1305,16 @@ export function createRule(fs) {
|
|
|
1095
1305
|
|
|
1096
1306
|
// Check if any symbol in this group is a default export
|
|
1097
1307
|
} catch (err) {
|
|
1098
|
-
|
|
1308
|
+
_iterator25.e(err);
|
|
1099
1309
|
} finally {
|
|
1100
|
-
|
|
1310
|
+
_iterator25.f();
|
|
1101
1311
|
}
|
|
1102
1312
|
var hasDefaultExport = symbols.some(function (s) {
|
|
1103
1313
|
return s.originalName === 'default';
|
|
1104
1314
|
});
|
|
1105
1315
|
groups.push({
|
|
1106
|
-
exportPath:
|
|
1107
|
-
importPath: "".concat(mockContext.packageName).concat(
|
|
1316
|
+
exportPath: _exportPath,
|
|
1317
|
+
importPath: "".concat(mockContext.packageName).concat(_exportPath.slice(1)),
|
|
1108
1318
|
propertyNames: symbols.map(function (s) {
|
|
1109
1319
|
return s.symbolName;
|
|
1110
1320
|
}),
|
|
@@ -1118,25 +1328,25 @@ export function createRule(fs) {
|
|
|
1118
1328
|
|
|
1119
1329
|
// Build cross-package groups
|
|
1120
1330
|
} catch (err) {
|
|
1121
|
-
|
|
1331
|
+
_iterator19.e(err);
|
|
1122
1332
|
} finally {
|
|
1123
|
-
|
|
1333
|
+
_iterator19.f();
|
|
1124
1334
|
}
|
|
1125
1335
|
var crossPackageMockGroups = [];
|
|
1126
|
-
var
|
|
1127
|
-
|
|
1336
|
+
var _iterator20 = _createForOfIteratorHelper(crossPackageGroups),
|
|
1337
|
+
_step20;
|
|
1128
1338
|
try {
|
|
1129
|
-
for (
|
|
1130
|
-
var
|
|
1131
|
-
_importPath =
|
|
1132
|
-
_symbols =
|
|
1339
|
+
for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
|
|
1340
|
+
var _step20$value = _slicedToArray(_step20.value, 2),
|
|
1341
|
+
_importPath = _step20$value[0],
|
|
1342
|
+
_symbols = _step20$value[1];
|
|
1133
1343
|
// Build name mapping for aliased exports
|
|
1134
1344
|
var _nameMapping = new Map();
|
|
1135
|
-
var
|
|
1136
|
-
|
|
1345
|
+
var _iterator26 = _createForOfIteratorHelper(_symbols),
|
|
1346
|
+
_step26;
|
|
1137
1347
|
try {
|
|
1138
|
-
for (
|
|
1139
|
-
var _s =
|
|
1348
|
+
for (_iterator26.s(); !(_step26 = _iterator26.n()).done;) {
|
|
1349
|
+
var _s = _step26.value;
|
|
1140
1350
|
if (_s.originalName) {
|
|
1141
1351
|
_nameMapping.set(_s.symbolName, _s.originalName);
|
|
1142
1352
|
}
|
|
@@ -1144,9 +1354,9 @@ export function createRule(fs) {
|
|
|
1144
1354
|
|
|
1145
1355
|
// Check if any symbol in this group is a default export
|
|
1146
1356
|
} catch (err) {
|
|
1147
|
-
|
|
1357
|
+
_iterator26.e(err);
|
|
1148
1358
|
} finally {
|
|
1149
|
-
|
|
1359
|
+
_iterator26.f();
|
|
1150
1360
|
}
|
|
1151
1361
|
var _hasDefaultExport = _symbols.some(function (s) {
|
|
1152
1362
|
return s.originalName === 'default';
|
|
@@ -1168,9 +1378,9 @@ export function createRule(fs) {
|
|
|
1168
1378
|
});
|
|
1169
1379
|
}
|
|
1170
1380
|
} catch (err) {
|
|
1171
|
-
|
|
1381
|
+
_iterator20.e(err);
|
|
1172
1382
|
} finally {
|
|
1173
|
-
|
|
1383
|
+
_iterator20.f();
|
|
1174
1384
|
}
|
|
1175
1385
|
if (unmappedSymbols.length > 0) {
|
|
1176
1386
|
groups.push({
|
|
@@ -1212,11 +1422,11 @@ export function createRule(fs) {
|
|
|
1212
1422
|
if (existingMock && existingMock.node !== node) {
|
|
1213
1423
|
// Merge properties from existing mock with new properties
|
|
1214
1424
|
var newPropertiesMap = new Map();
|
|
1215
|
-
var
|
|
1216
|
-
|
|
1425
|
+
var _iterator21 = _createForOfIteratorHelper(group.propertyNames),
|
|
1426
|
+
_step21;
|
|
1217
1427
|
try {
|
|
1218
|
-
for (
|
|
1219
|
-
var propName =
|
|
1428
|
+
for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
|
|
1429
|
+
var propName = _step21.value;
|
|
1220
1430
|
var propInfo = mockProperties.get(propName);
|
|
1221
1431
|
if (propInfo) {
|
|
1222
1432
|
// Check if this property needs to be renamed (aliased export)
|
|
@@ -1237,9 +1447,9 @@ export function createRule(fs) {
|
|
|
1237
1447
|
}
|
|
1238
1448
|
}
|
|
1239
1449
|
} catch (err) {
|
|
1240
|
-
|
|
1450
|
+
_iterator21.e(err);
|
|
1241
1451
|
} finally {
|
|
1242
|
-
|
|
1452
|
+
_iterator21.f();
|
|
1243
1453
|
}
|
|
1244
1454
|
var mergedProperties = mergeMockProperties({
|
|
1245
1455
|
existingProperties: existingMock.properties,
|
|
@@ -1251,10 +1461,10 @@ export function createRule(fs) {
|
|
|
1251
1461
|
exportPath: group.exportPath,
|
|
1252
1462
|
importPath: group.importPath,
|
|
1253
1463
|
propertyNames: Array.from(mergedProperties.keys()),
|
|
1254
|
-
propertyTexts: new Map(Array.from(mergedProperties.entries()).map(function (
|
|
1255
|
-
var
|
|
1256
|
-
k =
|
|
1257
|
-
v =
|
|
1464
|
+
propertyTexts: new Map(Array.from(mergedProperties.entries()).map(function (_ref17) {
|
|
1465
|
+
var _ref18 = _slicedToArray(_ref17, 2),
|
|
1466
|
+
k = _ref18[0],
|
|
1467
|
+
v = _ref18[1];
|
|
1258
1468
|
return [k, v.text];
|
|
1259
1469
|
})),
|
|
1260
1470
|
nameMapping: new Map(),
|
|
@@ -1269,32 +1479,46 @@ export function createRule(fs) {
|
|
|
1269
1479
|
mergedGroups.push(group);
|
|
1270
1480
|
}
|
|
1271
1481
|
}
|
|
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
1482
|
var symbolToNewImportPath = new Map();
|
|
1283
1483
|
for (var _i4 = 0, _arr = [].concat(mergedGroups, crossPackageMockGroups); _i4 < _arr.length; _i4++) {
|
|
1284
1484
|
var _group2 = _arr[_i4];
|
|
1285
|
-
var
|
|
1286
|
-
|
|
1485
|
+
var _iterator22 = _createForOfIteratorHelper(_group2.propertyNames),
|
|
1486
|
+
_step22;
|
|
1287
1487
|
try {
|
|
1288
|
-
for (
|
|
1289
|
-
var _propName =
|
|
1488
|
+
for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
|
|
1489
|
+
var _propName = _step22.value;
|
|
1290
1490
|
symbolToNewImportPath.set(_propName, _group2.importPath);
|
|
1291
1491
|
}
|
|
1292
1492
|
} catch (err) {
|
|
1293
|
-
|
|
1493
|
+
_iterator22.e(err);
|
|
1294
1494
|
} finally {
|
|
1295
|
-
|
|
1495
|
+
_iterator22.f();
|
|
1296
1496
|
}
|
|
1297
1497
|
}
|
|
1498
|
+
var fixText = generateMockFixes({
|
|
1499
|
+
groups: mergedGroups,
|
|
1500
|
+
crossPackageGroups: crossPackageMockGroups,
|
|
1501
|
+
packageName: mockContext.packageName,
|
|
1502
|
+
mockProperties: mockProperties,
|
|
1503
|
+
quote: quote,
|
|
1504
|
+
preambleStatements: preambleStatements,
|
|
1505
|
+
propagateEsModuleFromOriginalMock: originalMockHadEsModule,
|
|
1506
|
+
oldBarrelImportPath: oldImportPath,
|
|
1507
|
+
symbolToNewImportPath: symbolToNewImportPath
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
// Post-process fixText to update jest.requireActual('barrel').Symbol
|
|
1511
|
+
// references embedded in property texts (e.g. inside jest.fn callbacks)
|
|
1512
|
+
fixText = fixText.replace(/jest\.requireActual(?:<[^>]*>)?\((['"])([^'"]+)\1\)\.(\w+)/g, function (match, _q, path, symbol) {
|
|
1513
|
+
if (path !== oldImportPath) {
|
|
1514
|
+
return match;
|
|
1515
|
+
}
|
|
1516
|
+
var newPath = symbolToNewImportPath.get(symbol);
|
|
1517
|
+
if (newPath && newPath !== path) {
|
|
1518
|
+
return match.replace(path, newPath);
|
|
1519
|
+
}
|
|
1520
|
+
return match;
|
|
1521
|
+
});
|
|
1298
1522
|
|
|
1299
1523
|
// Sort nodes by position
|
|
1300
1524
|
var sortedNodesToRemove = nodesToRemove.sort(function (a, b) {
|
|
@@ -1341,27 +1565,78 @@ export function createRule(fs) {
|
|
|
1341
1565
|
return candidatePath === oldImportPath;
|
|
1342
1566
|
}
|
|
1343
1567
|
});
|
|
1344
|
-
var
|
|
1345
|
-
|
|
1568
|
+
var _iterator23 = _createForOfIteratorHelper(requireMockCalls),
|
|
1569
|
+
_step23;
|
|
1346
1570
|
try {
|
|
1347
|
-
for (
|
|
1348
|
-
var requireMockNode =
|
|
1571
|
+
for (_iterator23.s(); !(_step23 = _iterator23.n()).done;) {
|
|
1572
|
+
var requireMockNode = _step23.value;
|
|
1349
1573
|
var requireMockArg = requireMockNode.arguments[0];
|
|
1350
1574
|
if (!requireMockArg) {
|
|
1351
1575
|
continue;
|
|
1352
1576
|
}
|
|
1353
|
-
var
|
|
1577
|
+
var _newPath = resolveNewPathForRequireMock({
|
|
1354
1578
|
requireMockNode: requireMockNode,
|
|
1355
1579
|
symbolToNewPath: symbolToNewImportPath
|
|
1356
1580
|
});
|
|
1357
|
-
if (
|
|
1358
|
-
fixes.push(fixer.replaceText(requireMockArg, "".concat(quote).concat(
|
|
1581
|
+
if (_newPath) {
|
|
1582
|
+
fixes.push(fixer.replaceText(requireMockArg, "".concat(quote).concat(_newPath).concat(quote)));
|
|
1359
1583
|
}
|
|
1360
1584
|
}
|
|
1585
|
+
|
|
1586
|
+
// Fix jest.requireActual() calls that reference the old barrel path.
|
|
1587
|
+
// Only fix calls OUTSIDE the replaced jest.mock node range
|
|
1588
|
+
// (calls inside it are handled via fixText string replacement below).
|
|
1589
|
+
} catch (err) {
|
|
1590
|
+
_iterator23.e(err);
|
|
1591
|
+
} finally {
|
|
1592
|
+
_iterator23.f();
|
|
1593
|
+
}
|
|
1594
|
+
var replacedRanges = sortedNodesToRemove.map(function (n) {
|
|
1595
|
+
return n.range;
|
|
1596
|
+
});
|
|
1597
|
+
var requireActualCalls = findJestRequireActualCalls({
|
|
1598
|
+
ast: ast,
|
|
1599
|
+
matchPath: function matchPath(candidatePath) {
|
|
1600
|
+
return candidatePath === oldImportPath;
|
|
1601
|
+
}
|
|
1602
|
+
});
|
|
1603
|
+
var _iterator24 = _createForOfIteratorHelper(requireActualCalls),
|
|
1604
|
+
_step24;
|
|
1605
|
+
try {
|
|
1606
|
+
var _loop = function _loop() {
|
|
1607
|
+
var raNode = _step24.value;
|
|
1608
|
+
var raArg = raNode.arguments[0];
|
|
1609
|
+
if (!raArg || !raNode.range) {
|
|
1610
|
+
return 0; // continue
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
// Skip calls inside any node being replaced (ranges overlap)
|
|
1614
|
+
var insideReplacedNode = replacedRanges.some(function (_ref19) {
|
|
1615
|
+
var _ref20 = _slicedToArray(_ref19, 2),
|
|
1616
|
+
start = _ref20[0],
|
|
1617
|
+
end = _ref20[1];
|
|
1618
|
+
return raNode.range[0] >= start && raNode.range[1] <= end;
|
|
1619
|
+
});
|
|
1620
|
+
if (insideReplacedNode) {
|
|
1621
|
+
return 0; // continue
|
|
1622
|
+
}
|
|
1623
|
+
var newPath = resolveNewPathForRequireMock({
|
|
1624
|
+
requireMockNode: raNode,
|
|
1625
|
+
symbolToNewPath: symbolToNewImportPath
|
|
1626
|
+
});
|
|
1627
|
+
if (newPath) {
|
|
1628
|
+
fixes.push(fixer.replaceText(raArg, "".concat(quote).concat(newPath).concat(quote)));
|
|
1629
|
+
}
|
|
1630
|
+
},
|
|
1631
|
+
_ret;
|
|
1632
|
+
for (_iterator24.s(); !(_step24 = _iterator24.n()).done;) {
|
|
1633
|
+
_ret = _loop();
|
|
1634
|
+
if (_ret === 0) continue;
|
|
1635
|
+
}
|
|
1361
1636
|
} catch (err) {
|
|
1362
|
-
|
|
1637
|
+
_iterator24.e(err);
|
|
1363
1638
|
} finally {
|
|
1364
|
-
|
|
1639
|
+
_iterator24.f();
|
|
1365
1640
|
}
|
|
1366
1641
|
return fixes;
|
|
1367
1642
|
}
|