@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.
Files changed (39) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/index.js +6 -1
  3. package/dist/cjs/rules/ensure-use-sync-external-store-server-snapshot/index.js +41 -0
  4. package/dist/cjs/rules/import/no-barrel-entry-imports/index.js +475 -67
  5. package/dist/cjs/rules/import/no-barrel-entry-jest-mock/index.js +387 -112
  6. package/dist/cjs/rules/import/no-jest-mock-barrel-files/index.js +3 -2
  7. package/dist/cjs/rules/import/no-relative-barrel-file-imports/index.js +7 -3
  8. package/dist/cjs/rules/import/shared/jest-utils.js +62 -9
  9. package/dist/cjs/rules/import/shared/package-resolution.js +156 -23
  10. package/dist/cjs/rules/visit-example-type-import-required/index.js +409 -0
  11. package/dist/es2019/index.js +6 -1
  12. package/dist/es2019/rules/ensure-use-sync-external-store-server-snapshot/index.js +43 -0
  13. package/dist/es2019/rules/import/no-barrel-entry-imports/index.js +372 -15
  14. package/dist/es2019/rules/import/no-barrel-entry-jest-mock/index.js +245 -17
  15. package/dist/es2019/rules/import/no-jest-mock-barrel-files/index.js +3 -2
  16. package/dist/es2019/rules/import/no-relative-barrel-file-imports/index.js +7 -3
  17. package/dist/es2019/rules/import/shared/jest-utils.js +44 -0
  18. package/dist/es2019/rules/import/shared/package-resolution.js +97 -5
  19. package/dist/es2019/rules/visit-example-type-import-required/index.js +375 -0
  20. package/dist/esm/index.js +6 -1
  21. package/dist/esm/rules/ensure-use-sync-external-store-server-snapshot/index.js +35 -0
  22. package/dist/esm/rules/import/no-barrel-entry-imports/index.js +475 -67
  23. package/dist/esm/rules/import/no-barrel-entry-jest-mock/index.js +388 -113
  24. package/dist/esm/rules/import/no-jest-mock-barrel-files/index.js +3 -2
  25. package/dist/esm/rules/import/no-relative-barrel-file-imports/index.js +7 -3
  26. package/dist/esm/rules/import/shared/jest-utils.js +61 -9
  27. package/dist/esm/rules/import/shared/package-resolution.js +156 -25
  28. package/dist/esm/rules/visit-example-type-import-required/index.js +402 -0
  29. package/dist/types/index.d.ts +12 -0
  30. package/dist/types/rules/ensure-use-sync-external-store-server-snapshot/index.d.ts +3 -0
  31. package/dist/types/rules/import/shared/jest-utils.d.ts +8 -0
  32. package/dist/types/rules/import/shared/package-resolution.d.ts +22 -2
  33. package/dist/types/rules/visit-example-type-import-required/index.d.ts +4 -0
  34. package/dist/types-ts4.5/index.d.ts +12 -0
  35. package/dist/types-ts4.5/rules/ensure-use-sync-external-store-server-snapshot/index.d.ts +3 -0
  36. package/dist/types-ts4.5/rules/import/shared/jest-utils.d.ts +8 -0
  37. package/dist/types-ts4.5/rules/import/shared/package-resolution.d.ts +22 -2
  38. package/dist/types-ts4.5/rules/visit-example-type-import-required/index.d.ts +4 -0
  39. 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');
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;
@@ -34,6 +34,8 @@ declare const rules: {
34
34
  'no-jest-mock-barrel-files': import("eslint").Rule.RuleModule;
35
35
  'no-relative-barrel-file-imports': import("eslint").Rule.RuleModule;
36
36
  'no-conversation-assistant-barrel-imports': import("eslint").Rule.RuleModule;
37
+ 'visit-example-type-import-required': import("eslint").Rule.RuleModule;
38
+ 'ensure-use-sync-external-store-server-snapshot': import("eslint").Rule.RuleModule;
37
39
  };
38
40
  declare const plugin: {
39
41
  meta: {
@@ -75,6 +77,8 @@ declare const plugin: {
75
77
  'no-jest-mock-barrel-files': import("eslint").Rule.RuleModule;
76
78
  'no-relative-barrel-file-imports': import("eslint").Rule.RuleModule;
77
79
  'no-conversation-assistant-barrel-imports': import("eslint").Rule.RuleModule;
80
+ 'visit-example-type-import-required': import("eslint").Rule.RuleModule;
81
+ 'ensure-use-sync-external-store-server-snapshot': import("eslint").Rule.RuleModule;
78
82
  };
79
83
  configs: {
80
84
  recommended: {
@@ -90,6 +94,7 @@ declare const plugin: {
90
94
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
91
95
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
92
96
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
97
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
93
98
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
94
99
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
95
100
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -122,6 +127,7 @@ declare const plugin: {
122
127
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
123
128
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
124
129
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
130
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
125
131
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
126
132
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
127
133
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -143,6 +149,7 @@ declare const plugin: {
143
149
  rules: {
144
150
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
145
151
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
152
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
146
153
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
147
154
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
148
155
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -167,6 +174,7 @@ declare const plugin: {
167
174
  rules: {
168
175
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
169
176
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
177
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
170
178
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
171
179
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
172
180
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -203,6 +211,7 @@ declare const configs: {
203
211
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
204
212
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
205
213
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
214
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
206
215
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
207
216
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
208
217
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -235,6 +244,7 @@ declare const configs: {
235
244
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
236
245
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
237
246
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
247
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
238
248
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
239
249
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
240
250
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -256,6 +266,7 @@ declare const configs: {
256
266
  rules: {
257
267
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
258
268
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
269
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
259
270
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
260
271
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
261
272
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -280,6 +291,7 @@ declare const configs: {
280
291
  rules: {
281
292
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
282
293
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
294
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
283
295
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
284
296
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
285
297
  '@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,34 @@ 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
+ }
9
19
  /**
10
20
  * Find a matching export entry for a given source file path.
11
21
  * Returns the export path (e.g., "./controllers/analytics") or null if not found.
22
+ *
23
+ * When `fs` is provided, also checks entry-point wrapper files. If an export resolves
24
+ * to a file inside a recognized entry-points folder (entry-points, entrypoints, etc.),
25
+ * the wrapper is parsed to see if it re-exports from `sourceFilePath`.
26
+ *
27
+ * `sourceExportName` is the name under which the symbol is exported from the source file
28
+ * (e.g. `'default'`). Used to look up the corresponding entry-point export name so the
29
+ * caller can generate the correct import style.
12
30
  */
13
- export declare function findExportForSourceFile({ sourceFilePath, exportsMap, }: {
31
+ export declare function findExportForSourceFile({ sourceFilePath, exportsMap, fs, sourceExportName, }: {
14
32
  sourceFilePath: string;
15
33
  exportsMap: Map<string, string>;
16
- }): string | null;
34
+ fs?: FileSystem;
35
+ sourceExportName?: string;
36
+ }): ExportMatchResult | null;
17
37
  /**
18
38
  * Extract the package name and subpath from an import specifier.
19
39
  * Returns null if the import is not a scoped package import.
@@ -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;
@@ -34,6 +34,8 @@ declare const rules: {
34
34
  'no-jest-mock-barrel-files': import("eslint").Rule.RuleModule;
35
35
  'no-relative-barrel-file-imports': import("eslint").Rule.RuleModule;
36
36
  'no-conversation-assistant-barrel-imports': import("eslint").Rule.RuleModule;
37
+ 'visit-example-type-import-required': import("eslint").Rule.RuleModule;
38
+ 'ensure-use-sync-external-store-server-snapshot': import("eslint").Rule.RuleModule;
37
39
  };
38
40
  declare const plugin: {
39
41
  meta: {
@@ -75,6 +77,8 @@ declare const plugin: {
75
77
  'no-jest-mock-barrel-files': import("eslint").Rule.RuleModule;
76
78
  'no-relative-barrel-file-imports': import("eslint").Rule.RuleModule;
77
79
  'no-conversation-assistant-barrel-imports': import("eslint").Rule.RuleModule;
80
+ 'visit-example-type-import-required': import("eslint").Rule.RuleModule;
81
+ 'ensure-use-sync-external-store-server-snapshot': import("eslint").Rule.RuleModule;
78
82
  };
79
83
  configs: {
80
84
  recommended: {
@@ -90,6 +94,7 @@ declare const plugin: {
90
94
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
91
95
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
92
96
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
97
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
93
98
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
94
99
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
95
100
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -125,6 +130,7 @@ declare const plugin: {
125
130
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
126
131
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
127
132
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
133
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
128
134
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
129
135
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
130
136
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -149,6 +155,7 @@ declare const plugin: {
149
155
  rules: {
150
156
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
151
157
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
158
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
152
159
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
153
160
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
154
161
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -176,6 +183,7 @@ declare const plugin: {
176
183
  rules: {
177
184
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
178
185
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
186
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
179
187
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
180
188
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
181
189
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -215,6 +223,7 @@ declare const configs: {
215
223
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
216
224
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
217
225
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
226
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
218
227
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
219
228
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
220
229
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -250,6 +259,7 @@ declare const configs: {
250
259
  '@atlaskit/platform/ensure-feature-flag-registration': "error";
251
260
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
252
261
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
262
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
253
263
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
254
264
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
255
265
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -274,6 +284,7 @@ declare const configs: {
274
284
  rules: {
275
285
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
276
286
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
287
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
277
288
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
278
289
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
279
290
  '@atlaskit/platform/ensure-atlassian-team': "error";
@@ -301,6 +312,7 @@ declare const configs: {
301
312
  rules: {
302
313
  '@atlaskit/platform/ensure-test-runner-arguments': "error";
303
314
  '@atlaskit/platform/ensure-test-runner-nested-count': "warn";
315
+ '@atlaskit/platform/ensure-use-sync-external-store-server-snapshot': "error";
304
316
  '@atlaskit/platform/no-invalid-feature-flag-usage': "error";
305
317
  '@atlaskit/platform/no-invalid-storybook-decorator-usage': "error";
306
318
  '@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.