@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
@@ -0,0 +1,402 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
+ 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; } } }; }
4
+ 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; } }
5
+ 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; }
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
9
+ import { simpleTraverse } from '@typescript-eslint/typescript-estree';
10
+ export var RULE_NAME = 'visit-example-type-import-required';
11
+ var messages = {
12
+ missingTypeofImport: 'visitExample must use typeof import(...) generic type parameter. ' + 'Use visitExample<typeof import("path/to/example.tsx")>(groupId, packageId, exampleId).',
13
+ invalidTypeParameter: 'visitExample generic type parameter must be a typeof import(...) expression.',
14
+ pathMismatch: 'The import path "{{ importPath }}" does not match the expected example file for ' + 'visitExample({{ groupId }}, {{ packageId }}, {{ exampleId }}). ' + 'Expected import to resolve to: {{ expectedPath }}',
15
+ noPackageImports: 'Package imports (e.g., @atlaskit/...) are not allowed in visitExample type parameters. Use a relative import path.',
16
+ typeAliasNotInlined: 'Type aliases for typeof import(...) must be inlined directly into the visitExample call. ' + 'Use visitExample<typeof import("...")>(...) instead of defining a type alias.',
17
+ suggestFixPath: 'Update import path to match visitExample arguments'
18
+ };
19
+ function isTargetFile(filename) {
20
+ return filename.endsWith('.spec.tsx') || filename.endsWith('.spec.ts');
21
+ }
22
+
23
+ /**
24
+ * Extracts the import path string from a TSTypeQuery node of the form `typeof import('...')`.
25
+ * Returns null if the node doesn't match that shape.
26
+ */
27
+ function extractImportPathFromTypeQuery(typeQuery) {
28
+ // TSTypeQuery { exprName: TSImportType { argument: TSLiteralType { literal: Literal } } }
29
+ var exprName = typeQuery.exprName;
30
+ if (exprName.type !== AST_NODE_TYPES.TSImportType) {
31
+ return null;
32
+ }
33
+ var argument = exprName.argument;
34
+ if (argument.type === AST_NODE_TYPES.TSLiteralType && argument.literal.type === AST_NODE_TYPES.Literal && typeof argument.literal.value === 'string') {
35
+ return argument.literal.value;
36
+ }
37
+ return null;
38
+ }
39
+ /**
40
+ * Builds a map of all TSTypeAliasDeclaration nodes in the file, keyed by name.
41
+ * Each entry records whether the alias is at the top level of the program (file-level).
42
+ */
43
+ function collectTypeAliases(ast) {
44
+ var result = new Map();
45
+
46
+ // Cast through unknown to work around a version mismatch: @typescript-eslint/utils
47
+ // vendors its own copy of @typescript-eslint/types (v7) while the root node_modules
48
+ // has a different version (v5). The TSESTree types are structurally identical at
49
+ // runtime — the cast is safe.
50
+ simpleTraverse(ast, {
51
+ enter: function enter(node, parent) {
52
+ // A type alias is "file-level" if its immediate parent is the Program,
53
+ // or if it's the declaration of a top-level ExportNamedDeclaration.
54
+ if (node.type === AST_NODE_TYPES.TSTypeAliasDeclaration) {
55
+ var isFileLevel = (parent === null || parent === void 0 ? void 0 : parent.type) === AST_NODE_TYPES.Program || (parent === null || parent === void 0 ? void 0 : parent.type) === AST_NODE_TYPES.ExportNamedDeclaration;
56
+ result.set(node.id.name, {
57
+ node: node,
58
+ isFileLevel: isFileLevel
59
+ });
60
+ }
61
+ }
62
+ });
63
+ return result;
64
+ }
65
+
66
+ /**
67
+ * Resolves a top-level `const foo = 'literal'` declaration to its string value.
68
+ * Returns null for non-const, non-string, or not-found variables.
69
+ */
70
+ function resolveVariableToConstant(programBody, variableName, cache) {
71
+ if (cache.has(variableName)) {
72
+ var _cache$get;
73
+ return (_cache$get = cache.get(variableName)) !== null && _cache$get !== void 0 ? _cache$get : null;
74
+ }
75
+ var _iterator = _createForOfIteratorHelper(programBody),
76
+ _step;
77
+ try {
78
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
79
+ var node = _step.value;
80
+ if (node.type !== AST_NODE_TYPES.VariableDeclaration || node.kind !== 'const') {
81
+ continue;
82
+ }
83
+ var _iterator2 = _createForOfIteratorHelper(node.declarations),
84
+ _step2;
85
+ try {
86
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
87
+ var _declarator$init;
88
+ var declarator = _step2.value;
89
+ if (declarator.id.type === AST_NODE_TYPES.Identifier && declarator.id.name === variableName && ((_declarator$init = declarator.init) === null || _declarator$init === void 0 ? void 0 : _declarator$init.type) === AST_NODE_TYPES.Literal && typeof declarator.init.value === 'string') {
90
+ cache.set(variableName, declarator.init.value);
91
+ return declarator.init.value;
92
+ }
93
+ }
94
+ } catch (err) {
95
+ _iterator2.e(err);
96
+ } finally {
97
+ _iterator2.f();
98
+ }
99
+ }
100
+ } catch (err) {
101
+ _iterator.e(err);
102
+ } finally {
103
+ _iterator.f();
104
+ }
105
+ cache.set(variableName, null);
106
+ return null;
107
+ }
108
+ /**
109
+ * Extracts the (groupId, packageId, exampleId) string arguments from a visitExample call.
110
+ * Each argument may be a string literal or a reference to a top-level const string variable.
111
+ * Returns null for any argument that can't be statically resolved.
112
+ */
113
+ function extractCallArgs(node, programBody, variableCache) {
114
+ if (node.arguments.length < 3) {
115
+ return null;
116
+ }
117
+ function resolveArg(arg) {
118
+ if (arg.type === AST_NODE_TYPES.Literal && typeof arg.value === 'string') {
119
+ return arg.value;
120
+ }
121
+ if (arg.type === AST_NODE_TYPES.Identifier) {
122
+ return resolveVariableToConstant(programBody, arg.name, variableCache);
123
+ }
124
+ return null;
125
+ }
126
+ var groupId = resolveArg(node.arguments[0]);
127
+ var packageId = resolveArg(node.arguments[1]);
128
+ var exampleId = resolveArg(node.arguments[2]);
129
+ if (!groupId || !packageId || !exampleId) {
130
+ return null;
131
+ }
132
+ return {
133
+ groupId: groupId,
134
+ packageId: packageId,
135
+ exampleId: exampleId
136
+ };
137
+ }
138
+ function getPackagesBasePath(testFilePath) {
139
+ var testFileDir = path.dirname(testFilePath);
140
+ var testFileSegments = testFileDir.split(path.sep);
141
+ var packagesIndex = testFileSegments.findIndex(function (seg) {
142
+ return seg === 'packages';
143
+ });
144
+ if (packagesIndex === -1) {
145
+ return null;
146
+ }
147
+ var baseSegments = testFileSegments.slice(0, packagesIndex + 1);
148
+ var basePath = path.isAbsolute(testFilePath) ? path.resolve.apply(path, ['/'].concat(_toConsumableArray(baseSegments))) : path.resolve.apply(path, [process.cwd()].concat(_toConsumableArray(baseSegments)));
149
+ return {
150
+ basePath: basePath,
151
+ packagesIndex: packagesIndex
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Resolves the expected example file path from visitExample arguments.
157
+ *
158
+ * visitExample('groupId', 'packageId', 'exampleId') maps to:
159
+ * packages/{groupId}/{packageId}/examples/{exampleId}.tsx
160
+ *
161
+ * Example files may also have a numeric sort prefix, e.g.:
162
+ * packages/{groupId}/{packageId}/examples/00-{exampleId}.tsx
163
+ *
164
+ * We scan the examples directory once and match against all candidates.
165
+ * Falls back to the bare `{exampleId}.tsx` name when the directory can't
166
+ * be read (e.g. in unit-test environments where the files don't exist).
167
+ */
168
+ function resolveExamplePathFromArgs(groupId, packageId, exampleId, testFilePath) {
169
+ var packagesBase = getPackagesBasePath(testFilePath);
170
+ if (!packagesBase) {
171
+ return null;
172
+ }
173
+ var examplesDir = path.resolve(packagesBase.basePath, groupId, packageId, 'examples');
174
+ var fallback = path.resolve(examplesDir, "".concat(exampleId, ".tsx"));
175
+
176
+ // Match: exact name OR numeric-prefixed variant, with optional `.examples` infix
177
+ var candidateRe = new RegExp("^(?:\\d+-)?".concat(exampleId, "(?:\\.examples?)?\\.tsx$"));
178
+ try {
179
+ var match = fs.readdirSync(examplesDir).find(function (f) {
180
+ return candidateRe.test(f);
181
+ });
182
+ if (match) {
183
+ return path.resolve(examplesDir, match);
184
+ }
185
+ } catch (_unused) {
186
+ // Directory doesn't exist or can't be read (e.g. in test environments)
187
+ }
188
+ return fallback;
189
+ }
190
+
191
+ /**
192
+ * Computes a relative import path from one file to another
193
+ */
194
+ function computeRelativeImportPath(fromFile, toFile) {
195
+ var fromDir = path.dirname(fromFile);
196
+ var relativePath = path.relative(fromDir, toFile);
197
+ // Normalize to forward slashes for import statements (standard in JavaScript/TypeScript)
198
+ relativePath = relativePath.replace(/\\/g, '/');
199
+ // Ensure relative imports start with ./ or ../
200
+ if (!relativePath.startsWith('.') && !relativePath.startsWith('/')) {
201
+ relativePath = "./".concat(relativePath);
202
+ }
203
+ return relativePath;
204
+ }
205
+ /**
206
+ * Extracts the generic type argument from a `visitExample<...>(...)` call expression
207
+ * using the AST directly (no regex on source text).
208
+ *
209
+ * Returns:
210
+ * { type: 'inline', importPath } — for `visitExample<typeof import('...')>(...)`
211
+ * { type: 'alias', name } — for `visitExample<SomeTypeAlias>(...)`
212
+ * null — if no generic type parameter is present
213
+ */
214
+ function extractGenericType(node) {
215
+ var _params, _ref, _node$typeArguments;
216
+ // `typeArguments` is the current property name; `typeParameters` is the deprecated alias.
217
+ // We fall back to `typeParameters` for compatibility with older parser versions.
218
+ var params = (_params = (_ref = (_node$typeArguments = node.typeArguments) !== null && _node$typeArguments !== void 0 ? _node$typeArguments : node.typeParameters) === null || _ref === void 0 ? void 0 : _ref.params) !== null && _params !== void 0 ? _params : [];
219
+ if (params.length === 0) {
220
+ return null;
221
+ }
222
+ var _params2 = _slicedToArray(params, 1),
223
+ typeParam = _params2[0];
224
+
225
+ // `typeof import('...')` → TSTypeQuery { exprName: TSImportType { ... } }
226
+ if (typeParam.type === AST_NODE_TYPES.TSTypeQuery) {
227
+ var importPath = extractImportPathFromTypeQuery(typeParam);
228
+ if (importPath !== null) {
229
+ return {
230
+ type: 'inline',
231
+ importPath: importPath
232
+ };
233
+ }
234
+ }
235
+
236
+ // `SomeTypeAlias` → TSTypeReference { typeName: Identifier { name } }
237
+ if (typeParam.type === AST_NODE_TYPES.TSTypeReference && typeParam.typeName.type === AST_NODE_TYPES.Identifier) {
238
+ return {
239
+ type: 'alias',
240
+ name: typeParam.typeName.name
241
+ };
242
+ }
243
+ return null;
244
+ }
245
+ var rule = {
246
+ meta: {
247
+ type: 'problem',
248
+ docs: {
249
+ description: 'Ensures that visitExample uses a typeof import(...) generic and that the import path matches the example file resolved from the call arguments.'
250
+ },
251
+ fixable: 'code',
252
+ messages: messages,
253
+ schema: []
254
+ },
255
+ create: function create(context) {
256
+ var filename = context.filename;
257
+ var ast = context.sourceCode.ast;
258
+ var programBody = ast.body;
259
+
260
+ // Build the type alias map once per file (lazily on first visitExample call)
261
+ var typeAliases = null;
262
+ function getTypeAliases() {
263
+ if (!typeAliases) {
264
+ typeAliases = collectTypeAliases(ast);
265
+ }
266
+ return typeAliases;
267
+ }
268
+ var variableCache = new Map();
269
+ return {
270
+ CallExpression: function CallExpression(estreeNode) {
271
+ if (!isTargetFile(filename)) {
272
+ return;
273
+ }
274
+ var node = estreeNode;
275
+ // Only handle `<anything>.visitExample(...)` calls
276
+ if (node.callee.type !== AST_NODE_TYPES.MemberExpression || node.callee.property.type !== AST_NODE_TYPES.Identifier || node.callee.property.name !== 'visitExample') {
277
+ return;
278
+ }
279
+
280
+ // Narrow callee — we've confirmed property is an Identifier above
281
+ var callee = node.callee;
282
+ // reportCallee is typed as estree.Node for context.report compatibility
283
+ var reportCallee = estreeNode.callee;
284
+ var genericType = extractGenericType(node);
285
+
286
+ // ── Case 1: No generic type parameter ────────────────────────────────
287
+ if (genericType === null) {
288
+ var _args = extractCallArgs(node, programBody, variableCache);
289
+ context.report({
290
+ node: reportCallee,
291
+ messageId: 'missingTypeofImport',
292
+ fix: function fix(fixer) {
293
+ if (!_args) {
294
+ return null;
295
+ }
296
+ var examplePath = resolveExamplePathFromArgs(_args.groupId, _args.packageId, _args.exampleId, filename);
297
+ if (!examplePath) {
298
+ return null;
299
+ }
300
+ var importPath = computeRelativeImportPath(filename, examplePath);
301
+ var _ref2 = callee.property.range,
302
+ _ref3 = _slicedToArray(_ref2, 2),
303
+ start = _ref3[0],
304
+ end = _ref3[1];
305
+ return fixer.insertTextAfterRange([start, end], "<typeof import('".concat(importPath, "')>"));
306
+ }
307
+ });
308
+ return;
309
+ }
310
+
311
+ // ── Case 2: Generic is a type alias reference (`visitExample<Foo>`) ──
312
+ var importPath;
313
+ if (genericType.type === 'alias') {
314
+ var found = getTypeAliases().get(genericType.name);
315
+ if (!found) {
316
+ // Unknown type alias — not a typeof import
317
+ context.report({
318
+ node: reportCallee,
319
+ messageId: 'missingTypeofImport'
320
+ });
321
+ return;
322
+ }
323
+ if (found.isFileLevel) {
324
+ // Top-level `type Foo = typeof import(...)` is disallowed
325
+ context.report({
326
+ node: reportCallee,
327
+ messageId: 'typeAliasNotInlined'
328
+ });
329
+ return;
330
+ }
331
+ var typeAnnotation = found.node.typeAnnotation;
332
+ if (typeAnnotation.type !== AST_NODE_TYPES.TSTypeQuery) {
333
+ context.report({
334
+ node: reportCallee,
335
+ messageId: 'missingTypeofImport'
336
+ });
337
+ return;
338
+ }
339
+ var resolved = extractImportPathFromTypeQuery(typeAnnotation);
340
+ if (!resolved) {
341
+ context.report({
342
+ node: reportCallee,
343
+ messageId: 'missingTypeofImport'
344
+ });
345
+ return;
346
+ }
347
+ importPath = resolved;
348
+ } else {
349
+ // ── Case 3: Inline `typeof import('...')` ────────────────────────
350
+ importPath = genericType.importPath;
351
+ }
352
+
353
+ // Package-scoped imports (e.g. @atlaskit/foo/examples/...) are not allowed
354
+ if (importPath.startsWith('@')) {
355
+ context.report({
356
+ node: reportCallee,
357
+ messageId: 'noPackageImports'
358
+ });
359
+ return;
360
+ }
361
+
362
+ // Validate that the import path matches the arguments
363
+ var args = extractCallArgs(node, programBody, variableCache);
364
+ if (!args) {
365
+ // Dynamic arguments — can't validate statically
366
+ return;
367
+ }
368
+ var expectedPath = resolveExamplePathFromArgs(args.groupId, args.packageId, args.exampleId, filename);
369
+ if (!expectedPath) {
370
+ return;
371
+ }
372
+ var resolvedImport = path.normalize(path.resolve(path.dirname(filename), importPath));
373
+ var resolvedExpected = path.normalize(expectedPath);
374
+
375
+ // Compare without extensions so `.tsx` vs no extension doesn't matter
376
+ if (resolvedImport.replace(/\.(tsx?|jsx?)$/, '') !== resolvedExpected.replace(/\.(tsx?|jsx?)$/, '')) {
377
+ context.report({
378
+ node: estreeNode.arguments[0],
379
+ messageId: 'pathMismatch',
380
+ data: {
381
+ importPath: importPath,
382
+ groupId: args.groupId,
383
+ packageId: args.packageId,
384
+ exampleId: args.exampleId,
385
+ expectedPath: resolvedExpected
386
+ },
387
+ fix: function fix(fixer) {
388
+ var _node$typeArguments2;
389
+ var correctedPath = computeRelativeImportPath(filename, resolvedExpected);
390
+ var typeParams = (_node$typeArguments2 = node.typeArguments) !== null && _node$typeArguments2 !== void 0 ? _node$typeArguments2 : node.typeParameters;
391
+ if (!(typeParams !== null && typeParams !== void 0 && typeParams.range)) {
392
+ return null;
393
+ }
394
+ return fixer.replaceTextRange(typeParams.range, "<typeof import('".concat(correctedPath, "')>"));
395
+ }
396
+ });
397
+ }
398
+ }
399
+ };
400
+ }
401
+ };
402
+ export default rule;
@@ -29,11 +29,14 @@ declare const rules: {
29
29
  'no-direct-document-usage': import("eslint").Rule.RuleModule;
30
30
  'no-set-immediate': import("eslint").Rule.RuleModule;
31
31
  'prefer-crypto-random-uuid': import("eslint").Rule.RuleModule;
32
+ 'no-restricted-fedramp-imports': import("eslint").Rule.RuleModule;
32
33
  'no-barrel-entry-imports': import("eslint").Rule.RuleModule;
33
34
  'no-barrel-entry-jest-mock': import("eslint").Rule.RuleModule;
34
35
  'no-jest-mock-barrel-files': import("eslint").Rule.RuleModule;
35
36
  'no-relative-barrel-file-imports': import("eslint").Rule.RuleModule;
36
37
  'no-conversation-assistant-barrel-imports': import("eslint").Rule.RuleModule;
38
+ 'visit-example-type-import-required': import("eslint").Rule.RuleModule;
39
+ 'ensure-use-sync-external-store-server-snapshot': import("eslint").Rule.RuleModule;
37
40
  };
38
41
  declare const plugin: {
39
42
  meta: {
@@ -70,11 +73,14 @@ declare const plugin: {
70
73
  'no-direct-document-usage': import("eslint").Rule.RuleModule;
71
74
  'no-set-immediate': import("eslint").Rule.RuleModule;
72
75
  'prefer-crypto-random-uuid': import("eslint").Rule.RuleModule;
76
+ 'no-restricted-fedramp-imports': import("eslint").Rule.RuleModule;
73
77
  'no-barrel-entry-imports': import("eslint").Rule.RuleModule;
74
78
  'no-barrel-entry-jest-mock': import("eslint").Rule.RuleModule;
75
79
  'no-jest-mock-barrel-files': import("eslint").Rule.RuleModule;
76
80
  'no-relative-barrel-file-imports': import("eslint").Rule.RuleModule;
77
81
  'no-conversation-assistant-barrel-imports': import("eslint").Rule.RuleModule;
82
+ 'visit-example-type-import-required': import("eslint").Rule.RuleModule;
83
+ 'ensure-use-sync-external-store-server-snapshot': import("eslint").Rule.RuleModule;
78
84
  };
79
85
  configs: {
80
86
  recommended: {
@@ -90,6 +96,7 @@ declare const plugin: {
90
96
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
91
97
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
92
98
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
99
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
93
100
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
94
101
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
95
102
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -122,6 +129,7 @@ declare const plugin: {
122
129
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
123
130
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
124
131
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
132
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
125
133
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
126
134
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
127
135
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -143,6 +151,7 @@ declare const plugin: {
143
151
  rules: {
144
152
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
145
153
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
154
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
146
155
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
147
156
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
148
157
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -167,6 +176,7 @@ declare const plugin: {
167
176
  rules: {
168
177
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
169
178
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
179
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
170
180
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
171
181
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
172
182
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -203,6 +213,7 @@ declare const configs: {
203
213
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
204
214
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
205
215
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
216
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
206
217
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
207
218
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
208
219
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -235,6 +246,7 @@ declare const configs: {
235
246
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
236
247
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
237
248
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
249
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
238
250
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
239
251
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
240
252
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -256,6 +268,7 @@ declare const configs: {
256
268
  rules: {
257
269
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
258
270
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
271
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
259
272
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
260
273
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
261
274
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -280,6 +293,7 @@ declare const configs: {
280
293
  rules: {
281
294
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
282
295
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
296
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
283
297
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
284
298
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
285
299
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
@@ -33,6 +33,14 @@ export declare function findJestRequireMockCalls({ ast, matchPath, }: {
33
33
  ast: TSESTree.Program;
34
34
  matchPath: (candidatePath: string) => boolean;
35
35
  }): TSESTree.CallExpression[];
36
+ /**
37
+ * Find all jest.requireActual() calls in the AST whose import path matches a given target.
38
+ * Works identically to findJestRequireMockCalls but for requireActual.
39
+ */
40
+ export declare function findJestRequireActualCalls({ ast, matchPath, }: {
41
+ ast: TSESTree.Program;
42
+ matchPath: (candidatePath: string) => boolean;
43
+ }): TSESTree.CallExpression[];
36
44
  /**
37
45
  * Determine the best new import path for a jest.requireMock() call by inspecting
38
46
  * the destructured symbols or property access at the call site.
@@ -6,14 +6,59 @@ export declare function parsePackageExports({ packageDir, fs, }: {
6
6
  packageDir: string;
7
7
  fs: FileSystem;
8
8
  }): Map<string, string>;
9
+ export interface ExportMatchResult {
10
+ exportPath: string;
11
+ /**
12
+ * When resolved through an entry-point wrapper, the name under which
13
+ * the symbol is exported from the entry-point file.
14
+ * Callers use this to override the barrel's `originalName` so the
15
+ * generated import matches the entry-point's export shape.
16
+ */
17
+ entryPointExportName?: string;
18
+ }
19
+ /**
20
+ * Check whether a subpath export key (e.g. `"./checkbox-select"`) is kebab-case.
21
+ *
22
+ * A key is considered kebab-case when the portion after the leading `"./"` prefix
23
+ * consists only of lowercase letters, digits, hyphens, dots, and forward-slash
24
+ * separators — i.e. no uppercase letters, underscores, or camelCase humps.
25
+ */
26
+ export declare function isKebabCaseExportKey(key: string): boolean;
9
27
  /**
10
28
  * Find a matching export entry for a given source file path.
11
29
  * Returns the export path (e.g., "./controllers/analytics") or null if not found.
30
+ *
31
+ * When multiple export paths resolve to the same source file **and** point to an
32
+ * entry-point file, kebab-case keys are preferred over other casing styles.
33
+ *
34
+ * When `fs` is provided, also checks entry-point wrapper files. If an export resolves
35
+ * to a file inside a recognized entry-points folder (entry-points, entrypoints, etc.),
36
+ * the wrapper is parsed to see if it re-exports from `sourceFilePath`.
37
+ *
38
+ * `sourceExportName` is the name under which the symbol is exported from the source file
39
+ * (e.g. `'default'`). Used to look up the corresponding entry-point export name so the
40
+ * caller can generate the correct import style.
12
41
  */
13
- export declare function findExportForSourceFile({ sourceFilePath, exportsMap, }: {
42
+ export declare function findExportForSourceFile({ sourceFilePath, exportsMap, fs, sourceExportName, }: {
14
43
  sourceFilePath: string;
15
44
  exportsMap: Map<string, string>;
16
- }): string | null;
45
+ fs?: FileSystem;
46
+ sourceExportName?: string;
47
+ }): ExportMatchResult | null;
48
+ /**
49
+ * When a symbol reaches the consumer through a barrel package that re-exports from
50
+ * `crossPackageName`, find a `package.json` export subpath of that barrel whose entry
51
+ * file directly re-exports the symbol from `crossPackageName` (named exports only).
52
+ *
53
+ * This enables rewriting imports to `@scope/barrel/subpath` instead of
54
+ * `@scope/cross-package/...` when the barrel exposes such a subpath (e.g. `@atlaskit/select/react-select`).
55
+ */
56
+ export declare function findCrossPackageBridgeExportPath({ exportsMap, crossPackageName, exportedName, fs, }: {
57
+ exportsMap: Map<string, string>;
58
+ crossPackageName: string;
59
+ exportedName: string;
60
+ fs: FileSystem;
61
+ }): ExportMatchResult | null;
17
62
  /**
18
63
  * Extract the package name and subpath from an import specifier.
19
64
  * Returns null if the import is not a scoped package import.
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
@@ -0,0 +1,4 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const RULE_NAME = "visit-example-type-import-required";
3
+ declare const rule: Rule.RuleModule;
4
+ export default rule;