@atlaskit/eslint-plugin-platform 2.7.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/index.js +17 -9
  3. package/dist/cjs/rules/constants.js +1 -1
  4. package/dist/cjs/rules/ensure-critical-dependency-resolutions/index.js +5 -5
  5. package/dist/cjs/rules/ensure-no-private-dependencies/index.js +48 -66
  6. package/dist/cjs/rules/feature-gating/inline-usage/index.js +14 -3
  7. package/dist/cjs/rules/feature-gating/no-alias/index.js +1 -1
  8. package/dist/cjs/rules/feature-gating/no-module-level-eval/index.js +1 -1
  9. package/dist/cjs/rules/feature-gating/no-module-level-eval-nav4/index.js +1 -1
  10. package/dist/cjs/rules/feature-gating/no-preconditioning/index.js +4 -1
  11. package/dist/cjs/rules/feature-gating/prefer-fg/index.js +1 -1
  12. package/dist/cjs/rules/feature-gating/static-feature-flags/index.js +2 -2
  13. package/dist/cjs/rules/feature-gating/use-recommended-utils/index.js +1 -1
  14. package/dist/cjs/rules/feature-gating/valid-gate-name/index.js +60 -0
  15. package/dist/cjs/rules/import/no-barrel-entry-imports/index.js +871 -0
  16. package/dist/cjs/rules/import/no-barrel-entry-jest-mock/index.js +1384 -0
  17. package/dist/cjs/rules/import/no-conversation-assistant-barrel-imports/index.js +43 -0
  18. package/dist/cjs/rules/import/no-jest-mock-barrel-files/index.js +1401 -0
  19. package/dist/cjs/rules/import/no-relative-barrel-file-imports/index.js +777 -0
  20. package/dist/cjs/rules/import/shared/barrel-parsing.js +511 -0
  21. package/dist/cjs/rules/import/shared/file-system.js +186 -0
  22. package/dist/cjs/rules/import/shared/jest-utils.js +191 -0
  23. package/dist/cjs/rules/import/shared/package-registry.js +263 -0
  24. package/dist/cjs/rules/import/shared/package-resolution.js +185 -0
  25. package/dist/cjs/rules/import/shared/perf.js +89 -0
  26. package/dist/cjs/rules/import/shared/types.js +67 -0
  27. package/dist/cjs/rules/no-invalid-storybook-decorator-usage/index.js +1 -1
  28. package/dist/cjs/rules/no-sparse-checkout/index.js +1 -1
  29. package/dist/cjs/rules/prefer-crypto-random-uuid/index.js +87 -0
  30. package/dist/cjs/rules/use-entrypoints-in-examples/index.js +1 -1
  31. package/dist/es2019/index.js +17 -9
  32. package/dist/es2019/rules/constants.js +1 -1
  33. package/dist/es2019/rules/ensure-critical-dependency-resolutions/index.js +5 -5
  34. package/dist/es2019/rules/ensure-no-private-dependencies/index.js +10 -9
  35. package/dist/es2019/rules/feature-gating/inline-usage/index.js +14 -3
  36. package/dist/es2019/rules/feature-gating/no-alias/index.js +1 -1
  37. package/dist/es2019/rules/feature-gating/no-module-level-eval/index.js +1 -1
  38. package/dist/es2019/rules/feature-gating/no-module-level-eval-nav4/index.js +1 -1
  39. package/dist/es2019/rules/feature-gating/no-preconditioning/index.js +4 -1
  40. package/dist/es2019/rules/feature-gating/prefer-fg/index.js +1 -1
  41. package/dist/es2019/rules/feature-gating/static-feature-flags/index.js +2 -2
  42. package/dist/es2019/rules/feature-gating/use-recommended-utils/index.js +1 -1
  43. package/dist/es2019/rules/feature-gating/valid-gate-name/index.js +52 -0
  44. package/dist/es2019/rules/import/no-barrel-entry-imports/index.js +801 -0
  45. package/dist/es2019/rules/import/no-barrel-entry-jest-mock/index.js +1113 -0
  46. package/dist/es2019/rules/import/no-conversation-assistant-barrel-imports/index.js +37 -0
  47. package/dist/es2019/rules/import/no-jest-mock-barrel-files/index.js +1179 -0
  48. package/dist/es2019/rules/import/no-relative-barrel-file-imports/index.js +738 -0
  49. package/dist/es2019/rules/import/shared/barrel-parsing.js +433 -0
  50. package/dist/es2019/rules/import/shared/file-system.js +174 -0
  51. package/dist/es2019/rules/import/shared/jest-utils.js +159 -0
  52. package/dist/es2019/rules/import/shared/package-registry.js +240 -0
  53. package/dist/es2019/rules/import/shared/package-resolution.js +161 -0
  54. package/dist/es2019/rules/import/shared/perf.js +83 -0
  55. package/dist/es2019/rules/import/shared/types.js +57 -0
  56. package/dist/es2019/rules/no-invalid-storybook-decorator-usage/index.js +1 -1
  57. package/dist/es2019/rules/no-sparse-checkout/index.js +1 -1
  58. package/dist/es2019/rules/prefer-crypto-random-uuid/index.js +81 -0
  59. package/dist/es2019/rules/use-entrypoints-in-examples/index.js +1 -1
  60. package/dist/esm/index.js +17 -9
  61. package/dist/esm/rules/constants.js +1 -1
  62. package/dist/esm/rules/ensure-critical-dependency-resolutions/index.js +5 -5
  63. package/dist/esm/rules/ensure-no-private-dependencies/index.js +48 -65
  64. package/dist/esm/rules/feature-gating/inline-usage/index.js +14 -3
  65. package/dist/esm/rules/feature-gating/no-alias/index.js +1 -1
  66. package/dist/esm/rules/feature-gating/no-module-level-eval/index.js +1 -1
  67. package/dist/esm/rules/feature-gating/no-module-level-eval-nav4/index.js +1 -1
  68. package/dist/esm/rules/feature-gating/no-preconditioning/index.js +4 -1
  69. package/dist/esm/rules/feature-gating/prefer-fg/index.js +1 -1
  70. package/dist/esm/rules/feature-gating/static-feature-flags/index.js +2 -2
  71. package/dist/esm/rules/feature-gating/use-recommended-utils/index.js +1 -1
  72. package/dist/esm/rules/feature-gating/valid-gate-name/index.js +53 -0
  73. package/dist/esm/rules/import/no-barrel-entry-imports/index.js +864 -0
  74. package/dist/esm/rules/import/no-barrel-entry-jest-mock/index.js +1375 -0
  75. package/dist/esm/rules/import/no-conversation-assistant-barrel-imports/index.js +37 -0
  76. package/dist/esm/rules/import/no-jest-mock-barrel-files/index.js +1391 -0
  77. package/dist/esm/rules/import/no-relative-barrel-file-imports/index.js +770 -0
  78. package/dist/esm/rules/import/shared/barrel-parsing.js +500 -0
  79. package/dist/esm/rules/import/shared/file-system.js +176 -0
  80. package/dist/esm/rules/import/shared/jest-utils.js +179 -0
  81. package/dist/esm/rules/import/shared/package-registry.js +256 -0
  82. package/dist/esm/rules/import/shared/package-resolution.js +175 -0
  83. package/dist/esm/rules/import/shared/perf.js +80 -0
  84. package/dist/esm/rules/import/shared/types.js +61 -0
  85. package/dist/esm/rules/no-invalid-storybook-decorator-usage/index.js +1 -1
  86. package/dist/esm/rules/no-sparse-checkout/index.js +1 -1
  87. package/dist/esm/rules/prefer-crypto-random-uuid/index.js +81 -0
  88. package/dist/esm/rules/use-entrypoints-in-examples/index.js +1 -1
  89. package/dist/types/index.d.ts +18 -16
  90. package/dist/types/rules/import/no-barrel-entry-imports/index.d.ts +9 -0
  91. package/dist/types/rules/import/no-barrel-entry-jest-mock/index.d.ts +9 -0
  92. package/dist/types/rules/import/no-conversation-assistant-barrel-imports/index.d.ts +3 -0
  93. package/dist/types/rules/import/no-jest-mock-barrel-files/index.d.ts +22 -0
  94. package/dist/types/rules/import/no-relative-barrel-file-imports/index.d.ts +5 -0
  95. package/dist/types/rules/import/shared/barrel-parsing.d.ts +30 -0
  96. package/dist/types/rules/import/shared/file-system.d.ts +38 -0
  97. package/dist/types/rules/import/shared/jest-utils.d.ts +47 -0
  98. package/dist/types/rules/import/shared/package-registry.d.ts +26 -0
  99. package/dist/types/rules/import/shared/package-resolution.d.ts +38 -0
  100. package/dist/types/rules/import/shared/perf.d.ts +13 -0
  101. package/dist/types/rules/import/shared/types.d.ts +131 -0
  102. package/dist/types/rules/prefer-crypto-random-uuid/index.d.ts +3 -0
  103. package/dist/types-ts4.5/index.d.ts +18 -28
  104. package/dist/types-ts4.5/rules/import/no-barrel-entry-imports/index.d.ts +9 -0
  105. package/dist/types-ts4.5/rules/import/no-barrel-entry-jest-mock/index.d.ts +9 -0
  106. package/dist/types-ts4.5/rules/import/no-jest-mock-barrel-files/index.d.ts +22 -0
  107. package/dist/types-ts4.5/rules/import/no-relative-barrel-file-imports/index.d.ts +5 -0
  108. package/dist/types-ts4.5/rules/import/shared/barrel-parsing.d.ts +30 -0
  109. package/dist/types-ts4.5/rules/import/shared/file-system.d.ts +38 -0
  110. package/dist/types-ts4.5/rules/import/shared/jest-utils.d.ts +47 -0
  111. package/dist/types-ts4.5/rules/import/shared/package-registry.d.ts +26 -0
  112. package/dist/types-ts4.5/rules/import/shared/package-resolution.d.ts +38 -0
  113. package/dist/types-ts4.5/rules/import/shared/perf.d.ts +13 -0
  114. package/dist/types-ts4.5/rules/import/shared/types.d.ts +131 -0
  115. package/package.json +4 -5
  116. package/dist/cjs/rules/ensure-feature-flag-prefix/index.js +0 -75
  117. package/dist/cjs/rules/ensure-native-and-af-exports-synced/index.js +0 -158
  118. package/dist/es2019/rules/ensure-feature-flag-prefix/index.js +0 -65
  119. package/dist/es2019/rules/ensure-native-and-af-exports-synced/index.js +0 -146
  120. package/dist/esm/rules/ensure-feature-flag-prefix/index.js +0 -69
  121. package/dist/esm/rules/ensure-native-and-af-exports-synced/index.js +0 -151
  122. /package/dist/types/rules/{ensure-native-and-af-exports-synced → feature-gating/valid-gate-name}/index.d.ts +0 -0
  123. /package/dist/types-ts4.5/rules/{ensure-feature-flag-prefix → feature-gating/valid-gate-name}/index.d.ts +0 -0
  124. /package/dist/types-ts4.5/rules/{ensure-native-and-af-exports-synced → import/no-conversation-assistant-barrel-imports}/index.d.ts +0 -0
  125. /package/dist/{types/rules/ensure-feature-flag-prefix → types-ts4.5/rules/prefer-crypto-random-uuid}/index.d.ts +0 -0
@@ -0,0 +1,500 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
6
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
7
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
8
+ import { dirname } from 'path';
9
+ import * as ts from 'typescript';
10
+ import { isRelativeImport, readFileContent, resolveImportPath } from './file-system';
11
+ import { resolveCrossPackageImport } from './package-resolution';
12
+ import { perfInc, perfTime } from './perf';
13
+ /**
14
+ * Maximum depth to traverse when looking for source files in barrel exports.
15
+ * Can be adjusted based on project structure needs.
16
+ */
17
+ var MAX_BARREL_DEPTH = 10;
18
+
19
+ /**
20
+ * Get all named exports from a file.
21
+ * This extracts what names are exported from a file for star exports.
22
+ */
23
+ export function getNamedExportsFromFile(_ref) {
24
+ var filePath = _ref.filePath,
25
+ fs = _ref.fs;
26
+ var names = new Set();
27
+ var content = readFileContent({
28
+ filePath: filePath,
29
+ fs: fs
30
+ });
31
+ if (!content) {
32
+ return names;
33
+ }
34
+ try {
35
+ var sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
36
+ ts.forEachChild(sourceFile, function (node) {
37
+ if (ts.isExportDeclaration(node)) {
38
+ if (node.exportClause && ts.isNamedExports(node.exportClause)) {
39
+ node.exportClause.elements.forEach(function (e) {
40
+ return names.add(e.name.text);
41
+ });
42
+ }
43
+ } else if (ts.isExportAssignment(node)) {
44
+ names.add('default');
45
+ } else if (ts.isVariableStatement(node)) {
46
+ if (node.modifiers && node.modifiers.some(function (m) {
47
+ return m.kind === ts.SyntaxKind.ExportKeyword;
48
+ })) {
49
+ node.declarationList.declarations.forEach(function (d) {
50
+ if (ts.isIdentifier(d.name)) {
51
+ names.add(d.name.text);
52
+ }
53
+ });
54
+ }
55
+ } else if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node)) {
56
+ if (node.modifiers && node.modifiers.some(function (m) {
57
+ return m.kind === ts.SyntaxKind.ExportKeyword;
58
+ })) {
59
+ if (node.name && ts.isIdentifier(node.name)) {
60
+ names.add(node.name.text);
61
+ }
62
+ }
63
+ }
64
+ });
65
+ } catch (_unused) {
66
+ // Ignore parsing errors
67
+ }
68
+ return names;
69
+ }
70
+
71
+ /**
72
+ * Check if an export map represents a barrel file (has re-exports from other files)
73
+ */
74
+ export function hasReExportsFromOtherFiles(_ref2) {
75
+ var exportMap = _ref2.exportMap,
76
+ sourceFilePath = _ref2.sourceFilePath;
77
+ return Array.from(exportMap.values()).some(function (info) {
78
+ return info.path !== sourceFilePath;
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Process a named export element with cross-package support and add it to the exports map
84
+ */
85
+ function processNamedExportElementWithCrossPackage(_ref3) {
86
+ var element = _ref3.element,
87
+ resolvedSource = _ref3.resolvedSource,
88
+ nestedExports = _ref3.nestedExports,
89
+ isStatementTypeOnly = _ref3.isStatementTypeOnly,
90
+ exports = _ref3.exports,
91
+ crossPackageSource = _ref3.crossPackageSource;
92
+ var localName = element.name.text;
93
+ var propertyName = element.propertyName ? element.propertyName.text : localName;
94
+ var isElementTypeOnly = isStatementTypeOnly || element.isTypeOnly;
95
+ var isDefaultExport = propertyName === 'default';
96
+ // Track if this export is aliased (exported name differs from source name)
97
+ var isAliased = element.propertyName !== undefined && localName !== propertyName;
98
+ if (nestedExports) {
99
+ var deepSource = nestedExports.get(propertyName);
100
+ if (deepSource) {
101
+ var _deepSource$originalN;
102
+ exports.set(localName, {
103
+ path: deepSource.path,
104
+ isTypeOnly: isElementTypeOnly || deepSource.isTypeOnly,
105
+ isDefaultExport: deepSource.isDefaultExport,
106
+ // Use deep source's original name if available, otherwise use propertyName if aliased
107
+ originalName: (_deepSource$originalN = deepSource.originalName) !== null && _deepSource$originalN !== void 0 ? _deepSource$originalN : isAliased ? propertyName : undefined,
108
+ // Preserve existing crossPackageSource from nested exports, or use the one from this level
109
+ crossPackageSource: deepSource.crossPackageSource || crossPackageSource
110
+ });
111
+ } else {
112
+ exports.set(localName, {
113
+ path: resolvedSource,
114
+ isTypeOnly: isElementTypeOnly,
115
+ isDefaultExport: isDefaultExport,
116
+ originalName: isAliased ? propertyName : undefined,
117
+ crossPackageSource: crossPackageSource
118
+ });
119
+ }
120
+ } else {
121
+ exports.set(localName, {
122
+ path: resolvedSource,
123
+ isTypeOnly: isElementTypeOnly,
124
+ isDefaultExport: isDefaultExport,
125
+ originalName: isAliased ? propertyName : undefined,
126
+ crossPackageSource: crossPackageSource
127
+ });
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Handle star exports with cross-package support (export * from '...')
133
+ */
134
+ function processStarExportWithCrossPackage(_ref4) {
135
+ var resolvedSource = _ref4.resolvedSource,
136
+ nestedExports = _ref4.nestedExports,
137
+ exports = _ref4.exports,
138
+ fs = _ref4.fs,
139
+ crossPackageSource = _ref4.crossPackageSource;
140
+ if (nestedExports) {
141
+ var _iterator = _createForOfIteratorHelper(nestedExports),
142
+ _step;
143
+ try {
144
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
145
+ var _step$value = _slicedToArray(_step.value, 2),
146
+ name = _step$value[0],
147
+ info = _step$value[1];
148
+ if (name !== 'default') {
149
+ // Preserve existing crossPackageSource from nested exports, or use the one from this level
150
+ exports.set(name, _objectSpread(_objectSpread({}, info), {}, {
151
+ crossPackageSource: info.crossPackageSource || crossPackageSource
152
+ }));
153
+ }
154
+ }
155
+ } catch (err) {
156
+ _iterator.e(err);
157
+ } finally {
158
+ _iterator.f();
159
+ }
160
+ } else {
161
+ var nonBarrelExports = getNamedExportsFromFile({
162
+ filePath: resolvedSource,
163
+ fs: fs
164
+ });
165
+ var _iterator2 = _createForOfIteratorHelper(nonBarrelExports),
166
+ _step2;
167
+ try {
168
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
169
+ var _name = _step2.value;
170
+ if (_name !== 'default') {
171
+ exports.set(_name, {
172
+ path: resolvedSource,
173
+ isTypeOnly: false,
174
+ crossPackageSource: crossPackageSource
175
+ });
176
+ }
177
+ }
178
+ } catch (err) {
179
+ _iterator2.e(err);
180
+ } finally {
181
+ _iterator2.f();
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Process export declarations that have module specifiers (export ... from '...')
188
+ */
189
+ function processExportWithModuleSpecifier(_ref5) {
190
+ var statement = _ref5.statement,
191
+ resolveModule = _ref5.resolveModule,
192
+ depth = _ref5.depth,
193
+ exports = _ref5.exports,
194
+ fs = _ref5.fs,
195
+ workspaceRoot = _ref5.workspaceRoot,
196
+ visitedPackages = _ref5.visitedPackages;
197
+ if (!statement.moduleSpecifier || !ts.isStringLiteral(statement.moduleSpecifier)) {
198
+ return;
199
+ }
200
+ var modulePath = statement.moduleSpecifier.text;
201
+
202
+ // Try relative resolution first (existing behavior)
203
+ var resolvedSource = resolveModule(modulePath);
204
+ var crossPackageSource;
205
+
206
+ // If not a relative import, try cross-package resolution
207
+ if (!resolvedSource && !isRelativeImport(modulePath) && workspaceRoot) {
208
+ var crossPackageInfo = resolveCrossPackageImport({
209
+ moduleSpecifier: modulePath,
210
+ workspaceRoot: workspaceRoot,
211
+ fs: fs
212
+ });
213
+ if (crossPackageInfo) {
214
+ // Check for circular dependencies
215
+ if (visitedPackages !== null && visitedPackages !== void 0 && visitedPackages.has(crossPackageInfo.packageName)) {
216
+ return;
217
+ }
218
+ resolvedSource = crossPackageInfo.entryFilePath;
219
+ crossPackageSource = {
220
+ packageName: crossPackageInfo.packageName,
221
+ exportPath: crossPackageInfo.exportPath
222
+ };
223
+ }
224
+ }
225
+ if (!resolvedSource) {
226
+ return;
227
+ }
228
+ var isStatementTypeOnly = statement.isTypeOnly;
229
+
230
+ // For cross-package imports, track visited packages to prevent circular deps
231
+ var newVisitedPackages = visitedPackages ? new Set(visitedPackages) : new Set();
232
+ if (crossPackageSource) {
233
+ newVisitedPackages.add(crossPackageSource.packageName);
234
+ }
235
+
236
+ // Always trace through nested barrels and cross-package exports to find the ultimate source
237
+ var potentialNestedExports = parseBarrelExports({
238
+ barrelFilePath: resolvedSource,
239
+ depth: depth + 1,
240
+ fs: fs,
241
+ workspaceRoot: workspaceRoot,
242
+ visitedPackages: newVisitedPackages
243
+ });
244
+ var nestedExports = hasReExportsFromOtherFiles({
245
+ exportMap: potentialNestedExports,
246
+ sourceFilePath: resolvedSource
247
+ }) ? potentialNestedExports : null;
248
+ if (statement.exportClause) {
249
+ if (ts.isNamedExports(statement.exportClause)) {
250
+ var _iterator3 = _createForOfIteratorHelper(statement.exportClause.elements),
251
+ _step3;
252
+ try {
253
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
254
+ var element = _step3.value;
255
+ processNamedExportElementWithCrossPackage({
256
+ element: element,
257
+ resolvedSource: resolvedSource,
258
+ nestedExports: nestedExports,
259
+ isStatementTypeOnly: isStatementTypeOnly,
260
+ exports: exports,
261
+ crossPackageSource: crossPackageSource
262
+ });
263
+ }
264
+ } catch (err) {
265
+ _iterator3.e(err);
266
+ } finally {
267
+ _iterator3.f();
268
+ }
269
+ } else if (ts.isNamespaceExport(statement.exportClause)) {
270
+ var name = statement.exportClause.name.text;
271
+ exports.set(name, {
272
+ path: resolvedSource,
273
+ isTypeOnly: isStatementTypeOnly,
274
+ crossPackageSource: crossPackageSource
275
+ });
276
+ }
277
+ } else {
278
+ processStarExportWithCrossPackage({
279
+ resolvedSource: resolvedSource,
280
+ nestedExports: nestedExports,
281
+ exports: exports,
282
+ fs: fs,
283
+ crossPackageSource: crossPackageSource
284
+ });
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Process local export statements (no module specifier)
290
+ */
291
+ function processLocalExportDeclaration(_ref6) {
292
+ var statement = _ref6.statement,
293
+ barrelFilePath = _ref6.barrelFilePath,
294
+ exports = _ref6.exports;
295
+ if (!statement.exportClause || !ts.isNamedExports(statement.exportClause)) {
296
+ return;
297
+ }
298
+ var isStatementTypeOnly = statement.isTypeOnly;
299
+ var _iterator4 = _createForOfIteratorHelper(statement.exportClause.elements),
300
+ _step4;
301
+ try {
302
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
303
+ var element = _step4.value;
304
+ var isElementTypeOnly = isStatementTypeOnly || element.isTypeOnly;
305
+ exports.set(element.name.text, {
306
+ path: barrelFilePath,
307
+ isTypeOnly: isElementTypeOnly
308
+ });
309
+ }
310
+ } catch (err) {
311
+ _iterator4.e(err);
312
+ } finally {
313
+ _iterator4.f();
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Process various declaration statements with export modifiers
319
+ */
320
+ function processExportedDeclaration(_ref7) {
321
+ var statement = _ref7.statement,
322
+ barrelFilePath = _ref7.barrelFilePath,
323
+ exports = _ref7.exports;
324
+ if (ts.isExportAssignment(statement)) {
325
+ exports.set('default', {
326
+ path: barrelFilePath,
327
+ isTypeOnly: false
328
+ });
329
+ return;
330
+ }
331
+ var hasExportModifier = 'modifiers' in statement && Array.isArray(statement.modifiers) && statement.modifiers.some(function (m) {
332
+ return m.kind === ts.SyntaxKind.ExportKeyword;
333
+ });
334
+ if (!hasExportModifier) {
335
+ return;
336
+ }
337
+ if (ts.isVariableStatement(statement)) {
338
+ var _iterator5 = _createForOfIteratorHelper(statement.declarationList.declarations),
339
+ _step5;
340
+ try {
341
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
342
+ var decl = _step5.value;
343
+ if (ts.isIdentifier(decl.name)) {
344
+ exports.set(decl.name.text, {
345
+ path: barrelFilePath,
346
+ isTypeOnly: false
347
+ });
348
+ }
349
+ }
350
+ } catch (err) {
351
+ _iterator5.e(err);
352
+ } finally {
353
+ _iterator5.f();
354
+ }
355
+ } else if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) {
356
+ if (statement.name && ts.isIdentifier(statement.name)) {
357
+ exports.set(statement.name.text, {
358
+ path: barrelFilePath,
359
+ isTypeOnly: false
360
+ });
361
+ }
362
+ } else if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) {
363
+ if (statement.name && ts.isIdentifier(statement.name)) {
364
+ exports.set(statement.name.text, {
365
+ path: barrelFilePath,
366
+ isTypeOnly: true
367
+ });
368
+ }
369
+ } else if (ts.isEnumDeclaration(statement)) {
370
+ if (statement.name && ts.isIdentifier(statement.name)) {
371
+ exports.set(statement.name.text, {
372
+ path: barrelFilePath,
373
+ isTypeOnly: false
374
+ });
375
+ }
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Parse export statements from a file to find where each export comes from.
381
+ * Returns a map of export name -> ExportInfo.
382
+ *
383
+ * This function recursively traces through nested barrels and cross-package re-exports
384
+ * to find the ultimate source file for each export.
385
+ */
386
+ export function parseBarrelExports(_ref8) {
387
+ var barrelFilePath = _ref8.barrelFilePath,
388
+ _ref8$depth = _ref8.depth,
389
+ depth = _ref8$depth === void 0 ? 0 : _ref8$depth,
390
+ fs = _ref8.fs,
391
+ workspaceRoot = _ref8.workspaceRoot,
392
+ visitedPackages = _ref8.visitedPackages;
393
+ perfInc({
394
+ fs: fs,
395
+ key: 'parseBarrelExports.calls'
396
+ });
397
+ return perfTime({
398
+ fs: fs,
399
+ key: 'parseBarrelExports.totalMs',
400
+ fn: function fn() {
401
+ if (depth > MAX_BARREL_DEPTH) {
402
+ return new Map();
403
+ }
404
+ if (!fs.cache.barrelExportsByPath) {
405
+ fs.cache.barrelExportsByPath = new Map();
406
+ }
407
+ var currentMtimeMs = 0;
408
+ try {
409
+ var _fs$statSync$mtimeMs;
410
+ currentMtimeMs = (_fs$statSync$mtimeMs = fs.statSync(barrelFilePath).mtimeMs) !== null && _fs$statSync$mtimeMs !== void 0 ? _fs$statSync$mtimeMs : 0;
411
+ } catch (_unused2) {
412
+ currentMtimeMs = 0;
413
+ }
414
+ var cached = fs.cache.barrelExportsByPath.get(barrelFilePath);
415
+ if (cached && cached.mtimeMs === currentMtimeMs) {
416
+ perfInc({
417
+ fs: fs,
418
+ key: 'parseBarrelExports.cacheHit'
419
+ });
420
+ return cached.exports;
421
+ }
422
+ perfInc({
423
+ fs: fs,
424
+ key: 'parseBarrelExports.cacheMiss'
425
+ });
426
+ var exports = new Map();
427
+ var content = readFileContent({
428
+ filePath: barrelFilePath,
429
+ fs: fs
430
+ });
431
+ if (!content) {
432
+ return exports;
433
+ }
434
+ var sourceFile;
435
+ try {
436
+ sourceFile = perfTime({
437
+ fs: fs,
438
+ key: 'parseBarrelExports.tsCreateSourceFileMs',
439
+ fn: function fn() {
440
+ return ts.createSourceFile(barrelFilePath, content, ts.ScriptTarget.Latest, true);
441
+ }
442
+ });
443
+ } catch (_unused3) {
444
+ return exports;
445
+ }
446
+ var barrelDir = dirname(barrelFilePath);
447
+ var resolveModule = function resolveModule(moduleSpecifier) {
448
+ if (!isRelativeImport(moduleSpecifier)) {
449
+ return null;
450
+ }
451
+ return resolveImportPath({
452
+ basedir: barrelDir,
453
+ importPath: moduleSpecifier,
454
+ fs: fs
455
+ });
456
+ };
457
+ var _iterator6 = _createForOfIteratorHelper(sourceFile.statements),
458
+ _step6;
459
+ try {
460
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
461
+ var statement = _step6.value;
462
+ if (ts.isExportDeclaration(statement)) {
463
+ if (statement.moduleSpecifier) {
464
+ processExportWithModuleSpecifier({
465
+ statement: statement,
466
+ resolveModule: resolveModule,
467
+ depth: depth,
468
+ exports: exports,
469
+ fs: fs,
470
+ workspaceRoot: workspaceRoot,
471
+ visitedPackages: visitedPackages
472
+ });
473
+ } else {
474
+ processLocalExportDeclaration({
475
+ statement: statement,
476
+ barrelFilePath: barrelFilePath,
477
+ exports: exports
478
+ });
479
+ }
480
+ } else {
481
+ processExportedDeclaration({
482
+ statement: statement,
483
+ barrelFilePath: barrelFilePath,
484
+ exports: exports
485
+ });
486
+ }
487
+ }
488
+ } catch (err) {
489
+ _iterator6.e(err);
490
+ } finally {
491
+ _iterator6.f();
492
+ }
493
+ fs.cache.barrelExportsByPath.set(barrelFilePath, {
494
+ mtimeMs: currentMtimeMs,
495
+ exports: exports
496
+ });
497
+ return exports;
498
+ }
499
+ });
500
+ }
@@ -0,0 +1,176 @@
1
+ import { dirname, join, resolve } from 'path';
2
+ /**
3
+ * The default folder paths that barrel import rules apply to.
4
+ * Only imports from packages within these folders will be checked.
5
+ * This can be overridden via lint rule options.
6
+ */
7
+ export var DEFAULT_TARGET_FOLDERS = ['platform/packages/ai-mate', 'platform/packages/search'];
8
+
9
+ /**
10
+ * Try to read file contents with error handling.
11
+ * Returns null if file cannot be read.
12
+ */
13
+ export function readFileContent(_ref) {
14
+ var filePath = _ref.filePath,
15
+ fs = _ref.fs;
16
+ if (!fs.cache.fileContentByPath) {
17
+ fs.cache.fileContentByPath = new Map();
18
+ }
19
+ try {
20
+ if (!fs.existsSync(filePath)) {
21
+ return null;
22
+ }
23
+ var currentMtimeMs = null;
24
+ try {
25
+ var _fs$statSync$mtimeMs;
26
+ currentMtimeMs = (_fs$statSync$mtimeMs = fs.statSync(filePath).mtimeMs) !== null && _fs$statSync$mtimeMs !== void 0 ? _fs$statSync$mtimeMs : null;
27
+ } catch (_unused) {
28
+ // If stat fails, use null to force a re-read (don't use cached value)
29
+ currentMtimeMs = null;
30
+ }
31
+ var cached = fs.cache.fileContentByPath.get(filePath);
32
+ // Only use cache if we have a valid mtime and it matches
33
+ if (cached && currentMtimeMs !== null && cached.mtimeMs === currentMtimeMs) {
34
+ return cached.content;
35
+ }
36
+ var content = fs.readFileSync(filePath, 'utf-8');
37
+ fs.cache.fileContentByPath.set(filePath, {
38
+ mtimeMs: currentMtimeMs,
39
+ content: content
40
+ });
41
+ return content;
42
+ } catch (_unused2) {
43
+ // Silently fail if file cannot be read
44
+ }
45
+ return null;
46
+ }
47
+
48
+ /**
49
+ * Check if a path is a relative import (starts with ./ or ../)
50
+ */
51
+ export function isRelativeImport(importPath) {
52
+ return importPath.startsWith('./') || importPath.startsWith('../');
53
+ }
54
+
55
+ /**
56
+ * Resolve the actual file path from an import path.
57
+ * Handles extension inference and index file resolution.
58
+ */
59
+ export function resolveImportPath(_ref2) {
60
+ var basedir = _ref2.basedir,
61
+ importPath = _ref2.importPath,
62
+ fs = _ref2.fs;
63
+ if (!fs.cache.resolvedImportPathByKey) {
64
+ fs.cache.resolvedImportPathByKey = new Map();
65
+ }
66
+ var cacheKey = "".concat(basedir, "::").concat(importPath);
67
+ if (fs.cache.resolvedImportPathByKey.has(cacheKey)) {
68
+ var _fs$cache$resolvedImp;
69
+ return (_fs$cache$resolvedImp = fs.cache.resolvedImportPathByKey.get(cacheKey)) !== null && _fs$cache$resolvedImp !== void 0 ? _fs$cache$resolvedImp : null;
70
+ }
71
+ var possibleExtensions = ['.ts', '.tsx', '.js', '.jsx'];
72
+ var absolutePath = resolve(basedir, importPath);
73
+
74
+ // Check exact path first (for explicit extensions)
75
+ if (fs.existsSync(absolutePath)) {
76
+ try {
77
+ var stats = fs.statSync(absolutePath);
78
+ if (stats.isFile()) {
79
+ var resolvedPath = fs.realpathSync(absolutePath);
80
+ fs.cache.resolvedImportPathByKey.set(cacheKey, resolvedPath);
81
+ return resolvedPath;
82
+ }
83
+ } catch (_unused3) {
84
+ // Ignore errors
85
+ }
86
+ }
87
+
88
+ // Try with extensions
89
+ for (var _i = 0, _possibleExtensions = possibleExtensions; _i < _possibleExtensions.length; _i++) {
90
+ var ext = _possibleExtensions[_i];
91
+ var pathWithExt = absolutePath + ext;
92
+ if (fs.existsSync(pathWithExt)) {
93
+ try {
94
+ var _resolvedPath = fs.realpathSync(pathWithExt);
95
+ fs.cache.resolvedImportPathByKey.set(cacheKey, _resolvedPath);
96
+ return _resolvedPath;
97
+ } catch (_unused4) {
98
+ fs.cache.resolvedImportPathByKey.set(cacheKey, pathWithExt);
99
+ return pathWithExt;
100
+ }
101
+ }
102
+ }
103
+
104
+ // Try as directory with index
105
+ for (var _i2 = 0, _possibleExtensions2 = possibleExtensions; _i2 < _possibleExtensions2.length; _i2++) {
106
+ var _ext = _possibleExtensions2[_i2];
107
+ var indexPath = join(absolutePath, "index".concat(_ext));
108
+ if (fs.existsSync(indexPath)) {
109
+ try {
110
+ var _resolvedPath2 = fs.realpathSync(indexPath);
111
+ fs.cache.resolvedImportPathByKey.set(cacheKey, _resolvedPath2);
112
+ return _resolvedPath2;
113
+ } catch (_unused5) {
114
+ fs.cache.resolvedImportPathByKey.set(cacheKey, indexPath);
115
+ return indexPath;
116
+ }
117
+ }
118
+ }
119
+ fs.cache.resolvedImportPathByKey.set(cacheKey, null);
120
+ return null;
121
+ }
122
+
123
+ /**
124
+ * Find the workspace root using git rev-parse --show-toplevel.
125
+ * The result is cached on fs.cache.gitRepoRoot to avoid repeated shell calls.
126
+ * Falls back to directory traversal if git command fails.
127
+ */
128
+ export function findWorkspaceRoot(_ref3) {
129
+ var startPath = _ref3.startPath,
130
+ fs = _ref3.fs,
131
+ _ref3$applyToImportsF = _ref3.applyToImportsFrom,
132
+ applyToImportsFrom = _ref3$applyToImportsF === void 0 ? DEFAULT_TARGET_FOLDERS : _ref3$applyToImportsF;
133
+ // Return cached value if available
134
+ if (fs.cache.gitRepoRoot) {
135
+ return fs.cache.gitRepoRoot;
136
+ }
137
+
138
+ // Try to get the git repository root
139
+ var gitRoot = fs.execSync('git rev-parse --show-toplevel', {
140
+ cwd: startPath
141
+ });
142
+ if (gitRoot) {
143
+ fs.cache.gitRepoRoot = gitRoot;
144
+ return gitRoot;
145
+ }
146
+
147
+ // Fallback: traverse up looking for workspace markers
148
+ var current = startPath;
149
+ var maxDepth = 20;
150
+ var depth = 0;
151
+ while (depth < maxDepth) {
152
+ // Check if we've found the platform folder (which contains the target folders)
153
+ if (applyToImportsFrom.some(function (folder) {
154
+ return fs.existsSync(join(current, folder));
155
+ })) {
156
+ fs.cache.gitRepoRoot = current;
157
+ return current;
158
+ }
159
+
160
+ // Check for root-level indicators
161
+ var hasRootPackageJson = fs.existsSync(join(current, 'package.json'));
162
+ var hasYarnLock = fs.existsSync(join(current, 'yarn.lock'));
163
+ if (hasRootPackageJson && hasYarnLock) {
164
+ fs.cache.gitRepoRoot = current;
165
+ return current;
166
+ }
167
+ var parent = dirname(current);
168
+ if (parent === current) {
169
+ // Reached filesystem root
170
+ return startPath;
171
+ }
172
+ current = parent;
173
+ depth++;
174
+ }
175
+ return startPath;
176
+ }