@arcgis/eslint-config 5.2.0-next.6 → 5.2.0-next.61

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.
@@ -7,9 +7,12 @@ import { globalIgnores } from "eslint/config";
7
7
  import markdown from "@eslint/markdown";
8
8
  import packageJson from "eslint-plugin-package-json";
9
9
  import { importX } from "eslint-plugin-import-x";
10
+ import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
10
11
  const packageJsonSortableCollections = packageJson.rules["sort-collections"].meta.defaultOptions[0].filter(
11
12
  (collection) => !["scripts", "exports"].includes(collection)
12
13
  ) ?? [];
14
+ const importXTypeScriptSettings = { ...importX.flatConfigs.typescript.settings };
15
+ delete importXTypeScriptSettings["import-x/resolver"];
13
16
  const config = [
14
17
  globalIgnores(["**/www", "**/dist", "**/assets", "**/coverage", "**/.docs"]),
15
18
  {
@@ -24,7 +27,13 @@ const config = [
24
27
  ...webgisPlugin.configs.recommended,
25
28
  files: ["**/*.ts", "**/*.tsx"]
26
29
  },
27
- importX.flatConfigs.typescript,
30
+ {
31
+ ...importX.flatConfigs.typescript,
32
+ settings: {
33
+ ...importXTypeScriptSettings,
34
+ "import-x/resolver-next": [createTypeScriptImportResolver()]
35
+ }
36
+ },
28
37
  {
29
38
  files: ["**/*.ts", "**/*.tsx"],
30
39
  linterOptions: {
@@ -145,8 +154,10 @@ const config = [
145
154
  * consider refactoring to less confusing syntax instead
146
155
  *
147
156
  */
148
- // Might be intentional, so only a warning
149
- "no-await-in-loop": "warn",
157
+ // Too many false positives. Some cases require sequential execution of
158
+ // async code for correctness, cleaner output, or to avoid performance
159
+ // constraints
160
+ "no-await-in-loop": "off",
150
161
  "no-constructor-return": "warn",
151
162
  "no-fallthrough": ["error", { reportUnusedFallthroughComment: true }],
152
163
  // This mis-fires for anonymous functions when not wrapped in {}
@@ -181,11 +192,11 @@ const config = [
181
192
  "index",
182
193
  {
183
194
  name: "isNaN",
184
- message: "Use Number.isNaN instead as it has more predictable behavior. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN#description"
195
+ message: "Use Number.isNaN instead as it has more predictable behavior. See https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/isNaN#description"
185
196
  },
186
197
  {
187
198
  name: "isFinite",
188
- message: "Use Number.isFinite instead as it has more predictable behavior. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN#description (same applies to isFinite)"
199
+ message: "Use Number.isFinite instead as it has more predictable behavior. See https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/isNaN#description (same applies to isFinite)"
189
200
  },
190
201
  {
191
202
  name: "parseInt",
@@ -464,7 +475,10 @@ const config = [
464
475
  // rule - give it more time to catch the bug cases. Also, this rule
465
476
  // changes runtime behavior, and may lead to breaking changes.
466
477
  "@typescript-eslint/no-useless-default-assignment": "off",
467
- "@typescript-eslint/no-unnecessary-type-assertion": ["warn"],
478
+ // Since https://devtopia.esri.com/WebGIS/arcgis-web-components/pull/17821,
479
+ // this rule has more true positives, but also many more false positives.
480
+ // The autofix often causes TypeScript errors, and new ESLint errors
481
+ "@typescript-eslint/no-unnecessary-type-assertion": "off",
468
482
  "@typescript-eslint/prefer-includes": ["warn"],
469
483
  "@typescript-eslint/prefer-reduce-type-parameter": ["warn"],
470
484
  "@typescript-eslint/prefer-return-this-type": ["warn"],
@@ -1,10 +1,11 @@
1
1
  import { ESLintUtils } from "@typescript-eslint/utils";
2
- const version = "5.2.0-next.6";
2
+ const version = "5.2.0-next.61";
3
3
  const packageJson = {
4
4
  version
5
5
  };
6
6
  function makeEslintPlugin(pluginName, urlCreator) {
7
7
  const rules = [];
8
+ const typeCheckedRules = /* @__PURE__ */ new Set();
8
9
  const creator = ESLintUtils.RuleCreator(urlCreator);
9
10
  return {
10
11
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -13,6 +14,9 @@ function makeEslintPlugin(pluginName, urlCreator) {
13
14
  const docs = { ...meta.docs, name };
14
15
  const ruleModule = creator({ ...rest, meta: { ...meta, docs }, name });
15
16
  rules.push(ruleModule);
17
+ if (meta.docs.isTypeChecked) {
18
+ typeCheckedRules.add(`${pluginName}/${name}`);
19
+ }
16
20
  return ruleModule;
17
21
  },
18
22
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -23,7 +27,7 @@ function makeEslintPlugin(pluginName, urlCreator) {
23
27
  )
24
28
  };
25
29
  const plugin = {
26
- meta: { name: `@arcgis/eslint-plugin-${pluginName}`, version: packageJson.version },
30
+ meta: { name: `@arcgis/eslint-plugin-${pluginName}`, version: packageJson.version, typeCheckedRules },
27
31
  configs: {
28
32
  recommended: config
29
33
  },
@@ -1,7 +1,9 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-CsjR4Cb9.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-DJHigCQF.js";
2
2
  import { AST_NODE_TYPES, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
3
3
  import { generateDifferences, showInvisibles } from "prettier-linter-helpers";
4
4
  import path, { relative, win32, posix, normalize } from "path";
5
+ import { dirname, join } from "node:path";
6
+ import { existsSync } from "node:fs";
5
7
  import { execSync } from "child_process";
6
8
  const plugin = makeEslintPlugin(
7
9
  "core",
@@ -12,7 +14,8 @@ plugin.createRule({
12
14
  meta: {
13
15
  docs: {
14
16
  description: "Checks that glsl tagged template strings don't have extra whitespace.",
15
- defaultLevel: "error"
17
+ defaultLevel: "error",
18
+ isTypeChecked: false
16
19
  },
17
20
  messages: {
18
21
  delete: "Delete `{{ deleteText }}`",
@@ -93,20 +96,26 @@ function removeLeadingBlankLines(text) {
93
96
  function removeTrailingBlankLines(text) {
94
97
  return text.replace(/(\r?\n)(\r?\n)*([ \t]*)`$/gu, "$1$3`");
95
98
  }
99
+ const projectMarker = "/src/";
100
+ let projectRoot = void 0;
96
101
  function findProjectRoot(filename) {
97
102
  const normalized = filename.replaceAll("\\", "/");
98
- let minimumIndex = Number.POSITIVE_INFINITY;
99
- for (const marker of ["src/", "tests/", "test-apps/", "esri/"]) {
100
- const index = normalized.indexOf(marker);
101
- if (index === 0) {
102
- return ".";
103
- } else if (index > 0 && normalized.charCodeAt(index - 1) === slashCharCode) {
104
- minimumIndex = Math.min(minimumIndex, index);
103
+ const isProjectFile = normalized.includes(projectMarker);
104
+ if (isProjectFile && projectRoot) {
105
+ return projectRoot;
106
+ }
107
+ const fileToFind = "package.json";
108
+ for (let root = dirname(filename), previousRoot = filename; root !== previousRoot; previousRoot = root, root = dirname(root)) {
109
+ const filepath = join(root, fileToFind);
110
+ if (existsSync(filepath)) {
111
+ if (isProjectFile) {
112
+ projectRoot = root;
113
+ }
114
+ return root;
105
115
  }
106
116
  }
107
- return minimumIndex === Number.POSITIVE_INFINITY ? void 0 : normalized.slice(0, minimumIndex);
117
+ return;
108
118
  }
109
- const slashCharCode = 47;
110
119
  const isWindows = process.platform === "win32";
111
120
  const collator = new Intl.Collator("en-US");
112
121
  plugin.createRule({
@@ -114,7 +123,8 @@ plugin.createRule({
114
123
  meta: {
115
124
  docs: {
116
125
  description: "Checks that imports are sorted and grouped",
117
- defaultLevel: "error"
126
+ defaultLevel: "error",
127
+ isTypeChecked: false
118
128
  },
119
129
  messages: {
120
130
  importFormat: "Imports are incorrectly sorted and/or grouped",
@@ -226,7 +236,7 @@ function groupImportsByPath(imports, absImportPath, basePath) {
226
236
  });
227
237
  }
228
238
  function importStatementPathName(importStatement, absImportPath, basePath) {
229
- return importPathName(importStatementPathString(importStatement), absImportPath, basePath);
239
+ return normalizeImportPath(importPathName(importStatementPathString(importStatement), absImportPath, basePath));
230
240
  }
231
241
  function importStatementPathString(importStatement) {
232
242
  return importStatement.source.value;
@@ -248,10 +258,25 @@ function importPathName(importPath, absImportPath, basePath) {
248
258
  return path.dirname(relative(basePath, importPath));
249
259
  }
250
260
  function formatGroupedImports(sourceCode, groupedImports, newLine) {
251
- const importHeader = `// ${groupedImports.path.replace(/[\\/]/gu, ".")}`;
261
+ const importHeader = `// ${formatImportHeaderPath(groupedImports.path)}`;
252
262
  const imports = groupedImports.imports.map((importDeclaration) => sourceCode.getText(importDeclaration).trim()).join(newLine).trim();
253
263
  return `${importHeader}${newLine}${imports}`;
254
264
  }
265
+ function formatImportHeaderPath(importPath) {
266
+ return normalizeImportPath(importPath).replace(/[\\/]/gu, ".");
267
+ }
268
+ function normalizeImportPath(importPath) {
269
+ const parts = importPath.split(/[\\/]/gu);
270
+ if (parts[0] === "src") {
271
+ parts[0] = "esri";
272
+ } else if (parts[0] === "tests") {
273
+ const srcPart = parts.indexOf("src");
274
+ if (srcPart !== -1) {
275
+ parts[srcPart] = "esri";
276
+ }
277
+ }
278
+ return parts.join(path.sep);
279
+ }
255
280
  function getAttachedCommentStart(sourceCode, statement) {
256
281
  const comments = sourceCode.getCommentsBefore(statement);
257
282
  let start = statement.range[0];
@@ -326,7 +351,8 @@ plugin.createRule({
326
351
  meta: {
327
352
  docs: {
328
353
  description: "Checks for duplicate comments before the first import declaration.",
329
- defaultLevel: "error"
354
+ defaultLevel: "error",
355
+ isTypeChecked: false
330
356
  },
331
357
  messages: { duplicate: "Delete duplicate comment" },
332
358
  schema: [],
@@ -368,7 +394,8 @@ plugin.createRule({
368
394
  meta: {
369
395
  docs: {
370
396
  description: "Checks for `todo` JSDoc tags with missing descriptions.",
371
- defaultLevel: "error"
397
+ defaultLevel: "error",
398
+ isTypeChecked: false
372
399
  },
373
400
  messages: { empty: "JSDoc `todo` tag description required" },
374
401
  schema: [],
@@ -393,7 +420,8 @@ plugin.createRule({
393
420
  meta: {
394
421
  docs: {
395
422
  description: "Enforces the declared class name passed to the @subclass() decorator",
396
- defaultLevel: "error"
423
+ defaultLevel: "error",
424
+ isTypeChecked: false
397
425
  },
398
426
  messages: {
399
427
  invalidPath: "Invalid path passed to @subclass(). It should be a string literal matching the file path, without the extension and with path separators replaced with `.`"
@@ -452,7 +480,7 @@ function getDeclaredClass(filename) {
452
480
  if (!root) {
453
481
  return;
454
482
  }
455
- const relativePath = relative(root, filename).replaceAll(win32.sep, ".").replaceAll(posix.sep, ".").replace(/\.[^/.]+$/u, "");
483
+ const relativePath = relative(root, filename).replaceAll(win32.sep, ".").replaceAll(posix.sep, ".").replace(/^src\./u, "esri.").replace(/\.[^/.]+$/u, "");
456
484
  return relativePath;
457
485
  }
458
486
  const tsRe = /\.tsx?$/u;
@@ -476,7 +504,8 @@ plugin.createRule({
476
504
  meta: {
477
505
  docs: {
478
506
  description: "Checks that files redundant to TypeScript implementation files are not checked in.",
479
- defaultLevel: "error"
507
+ defaultLevel: "error",
508
+ isTypeChecked: false
480
509
  },
481
510
  messages: {
482
511
  js: "Redundant JavaScript file detected. Please `git rm -f {{file}}`",
@@ -492,16 +521,16 @@ plugin.createRule({
492
521
  return {
493
522
  Program(node) {
494
523
  if (!filePath.endsWith(".d.ts") && tsRe.test(filePath)) {
495
- const projectRoot = findProjectRoot(filePath);
496
- if (!projectRoot) {
524
+ const projectRoot2 = findProjectRoot(filePath);
525
+ if (!projectRoot2) {
497
526
  context.report({ node, messageId: "missingProjectRoot" });
498
527
  return;
499
528
  }
500
- const gitIndexFiles2 = getGitIndexFiles(projectRoot);
529
+ const gitIndexFiles2 = getGitIndexFiles(projectRoot2);
501
530
  if (!gitIndexFiles2) {
502
531
  return;
503
532
  }
504
- filePath = relative(projectRoot, filePath);
533
+ filePath = relative(projectRoot2, filePath);
505
534
  const jsFilename = filePath.replace(tsRe, ".js");
506
535
  if (gitIndexFiles2.has(jsFilename)) {
507
536
  context.report({ node, messageId: "js", data: { file: jsFilename } });
@@ -520,7 +549,8 @@ plugin.createRule({
520
549
  meta: {
521
550
  docs: {
522
551
  description: "Checks that whenever possible import and export paths are relative instead of absolute.",
523
- defaultLevel: "error"
552
+ defaultLevel: "error",
553
+ isTypeChecked: false
524
554
  },
525
555
  messages: {
526
556
  importFormat: 'Prefer relative ("{{relPath}}") over absolute path',
@@ -562,8 +592,15 @@ plugin.createRule({
562
592
  }
563
593
  });
564
594
  function pathRoot(p) {
565
- const dirName = path.dirname(p);
566
- return dirName === "." ? p : pathRoot(dirName);
595
+ const pathImplementation = win32.isAbsolute(p) && !posix.isAbsolute(p) ? win32 : path;
596
+ let root = p;
597
+ while (true) {
598
+ const parent = pathImplementation.dirname(root);
599
+ if (parent === "." || parent === root) {
600
+ return root;
601
+ }
602
+ root = parent;
603
+ }
567
604
  }
568
605
  function verifyRelativeImport(context, node, absImportPath, basePath, importRoot) {
569
606
  const modulePath = node.value;
@@ -591,7 +628,8 @@ plugin.createRule({
591
628
  meta: {
592
629
  docs: {
593
630
  description: "Checks that the corresponding calcite component import exists for each calcite component tag used. It also checks that there are no extra unnecessary imports.",
594
- defaultLevel: "error"
631
+ defaultLevel: "error",
632
+ isTypeChecked: false
595
633
  },
596
634
  messages: {
597
635
  missingImport: 'Import missing: import("@esri/calcite-components/dist/components/{{tag}}")',
@@ -640,7 +678,8 @@ plugin.createRule({
640
678
  meta: {
641
679
  docs: {
642
680
  description: "Enforce filenames to be part of spec (test) top-level suites.",
643
- defaultLevel: "error"
681
+ defaultLevel: "error",
682
+ isTypeChecked: false
644
683
  },
645
684
  messages: {
646
685
  name: "Suite name must be the name of the spec file",
@@ -694,7 +733,7 @@ function getToplevelSuiteName(filename) {
694
733
  return;
695
734
  }
696
735
  const relativePath = relative(root, filename).replaceAll(win32.sep, posix.sep);
697
- return relativePath.replace(/^tests\/(.*)\.spec\.ts/u, "$1");
736
+ return relativePath.replace(/^tests\/(.*)\.spec\.ts/u, "$1").replace("src/", "esri/");
698
737
  }
699
738
  const corePlugin = plugin.finalize();
700
739
  export {
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-CsjR4Cb9.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-DJHigCQF.js";
2
2
  import { AST_NODE_TYPES, ESLintUtils, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
3
3
  import { l as luminaJsxExportName, a as luminaEntrypointName, b as luminaTestEntrypointName, s as sourceCodeDeclaresComponent, p as parsePropertyDecorator, c as getProperty, i as isGetterWithoutSetter, e as extractDeclareElementsInterface, d as isCreateEvent, h as hasDecorator, f as getName, j as checkForLuminaJsx, k as isBindThisCallee, g as getComponentDeclaration, u as unwrapExpression } from "../../estree-CDc-die8.js";
4
4
  import ts from "typescript";
@@ -14,7 +14,8 @@ plugin.createRule({
14
14
  meta: {
15
15
  docs: {
16
16
  description: description$m,
17
- defaultLevel: "error"
17
+ defaultLevel: "error",
18
+ isTypeChecked: false
18
19
  },
19
20
  messages: {
20
21
  addMissingJsxImport: description$m
@@ -80,7 +81,8 @@ plugin.createRule({
80
81
  meta: {
81
82
  docs: {
82
83
  description: description$l,
83
- defaultLevel: "warn"
84
+ defaultLevel: "warn",
85
+ isTypeChecked: true
84
86
  },
85
87
  messages: {
86
88
  addType: `This property is of {{ type }} type, yet the type is not trivially inferrable from the AST without type-checking. Such properties require a { type: {{ type }} } annotation.
@@ -249,7 +251,8 @@ plugin.createRule({
249
251
  meta: {
250
252
  docs: {
251
253
  description: "This rule helps ban or warn against listened event types",
252
- defaultLevel: "off"
254
+ defaultLevel: "off",
255
+ isTypeChecked: false
253
256
  },
254
257
  messages: {
255
258
  default: "{{message}}"
@@ -319,7 +322,8 @@ plugin.createRule({
319
322
  meta: {
320
323
  docs: {
321
324
  description: description$k,
322
- defaultLevel: "error"
325
+ defaultLevel: "error",
326
+ isTypeChecked: false
323
327
  },
324
328
  messages: {
325
329
  fileFolderNameMismatch: "Lumina component must be declared in a file whose name (without extension) matches the parent folder name.\n\nCreating components in nested folders is supported as long as the file name matches the immediate parent folder name.",
@@ -369,7 +373,8 @@ plugin.createRule({
369
373
  meta: {
370
374
  docs: {
371
375
  description: description$j,
372
- defaultLevel: "warn"
376
+ defaultLevel: "warn",
377
+ isTypeChecked: false
373
378
  },
374
379
  messages: {
375
380
  eventNamespaceError: `Custom event name must start with one of the following prefixes: {{ prefixes }}.
@@ -476,7 +481,8 @@ plugin.createRule({
476
481
  docs: {
477
482
  description: description$i,
478
483
  // TODO: enable this by default
479
- defaultLevel: "off"
484
+ defaultLevel: "off",
485
+ isTypeChecked: false
480
486
  },
481
487
  messages: {
482
488
  consistentNullabilityError: `For consistency, use {{propertyName}}?:{{newType}} to denote property as optional, rather than {{propertyName}}:{{oldType}}.`,
@@ -556,7 +562,8 @@ plugin.createRule({
556
562
  meta: {
557
563
  docs: {
558
564
  description: description$h,
559
- defaultLevel: "error"
565
+ defaultLevel: "error",
566
+ isTypeChecked: false
560
567
  },
561
568
  messages: {
562
569
  publicApiMustBePublic: `@property(), @method() and createEvent() members must not have private or protected modifier.
@@ -664,7 +671,8 @@ plugin.createRule({
664
671
  meta: {
665
672
  docs: {
666
673
  description: description$g,
667
- defaultLevel: "error"
674
+ defaultLevel: "error",
675
+ isTypeChecked: true
668
676
  },
669
677
  messages: {
670
678
  explicitSetterType: description$g,
@@ -1051,7 +1059,8 @@ plugin.createRule({
1051
1059
  meta: {
1052
1060
  docs: {
1053
1061
  description: baseDescription$2,
1054
- defaultLevel: "warn"
1062
+ defaultLevel: "warn",
1063
+ isTypeChecked: false
1055
1064
  },
1056
1065
  messages: {
1057
1066
  memberOrdering: "Component member ordering is not consistent. Run ESLint autofix to sort members.",
@@ -1173,7 +1182,8 @@ plugin.createRule({
1173
1182
  meta: {
1174
1183
  docs: {
1175
1184
  description: "This rule ensures that components are not created with `document.createElement()` to ensure imports are tracked by the compiler.",
1176
- defaultLevel: "error"
1185
+ defaultLevel: "error",
1186
+ isTypeChecked: false
1177
1187
  },
1178
1188
  fixable: "code",
1179
1189
  messages: {
@@ -1219,7 +1229,8 @@ plugin.createRule({
1219
1229
  meta: {
1220
1230
  docs: {
1221
1231
  description: description$f,
1222
- defaultLevel: "error"
1232
+ defaultLevel: "error",
1233
+ isTypeChecked: false
1223
1234
  },
1224
1235
  messages: {
1225
1236
  noIgnoreJsDocTag: description$f
@@ -1257,7 +1268,8 @@ plugin.createRule({
1257
1268
  meta: {
1258
1269
  docs: {
1259
1270
  description: description$e,
1260
- defaultLevel: "error"
1271
+ defaultLevel: "error",
1272
+ isTypeChecked: true
1261
1273
  },
1262
1274
  messages: {
1263
1275
  incorrectDynamicTagName: `This is using incorrect dynamic tag name syntax. See documentation on how to use dynamic tag in Lumina's JSX: https://webgis.esri.com/references/lumina/jsx#dynamic-tag-name`
@@ -1307,7 +1319,8 @@ plugin.createRule({
1307
1319
  meta: {
1308
1320
  docs: {
1309
1321
  description: description$d,
1310
- defaultLevel: "warn"
1322
+ defaultLevel: "warn",
1323
+ isTypeChecked: false
1311
1324
  },
1312
1325
  messages: {
1313
1326
  errorInlineArrow: description$d
@@ -1342,7 +1355,8 @@ plugin.createRule({
1342
1355
  meta: {
1343
1356
  docs: {
1344
1357
  description: description$c,
1345
- defaultLevel: "error"
1358
+ defaultLevel: "error",
1359
+ isTypeChecked: false
1346
1360
  },
1347
1361
  messages: {
1348
1362
  inlineExposure: description$c
@@ -1387,7 +1401,8 @@ plugin.createRule({
1387
1401
  meta: {
1388
1402
  docs: {
1389
1403
  description: description$b,
1390
- defaultLevel: "error"
1404
+ defaultLevel: "error",
1405
+ isTypeChecked: false
1391
1406
  },
1392
1407
  messages: {
1393
1408
  noJsDocXrefLinks: description$b
@@ -1430,7 +1445,8 @@ plugin.createRule({
1430
1445
  meta: {
1431
1446
  docs: {
1432
1447
  description: description$a,
1433
- defaultLevel: "error"
1448
+ defaultLevel: "error",
1449
+ isTypeChecked: false
1434
1450
  },
1435
1451
  messages: {
1436
1452
  noInvalidDirectivesProp: description$a
@@ -1476,7 +1492,8 @@ plugin.createRule({
1476
1492
  meta: {
1477
1493
  docs: {
1478
1494
  description: description$9,
1479
- defaultLevel: "error"
1495
+ defaultLevel: "error",
1496
+ isTypeChecked: false
1480
1497
  },
1481
1498
  messages: {
1482
1499
  noJsxSpread: description$9
@@ -1521,7 +1538,8 @@ plugin.createRule({
1521
1538
  meta: {
1522
1539
  docs: {
1523
1540
  description: baseDescription$1,
1524
- defaultLevel: "error"
1541
+ defaultLevel: "error",
1542
+ isTypeChecked: false
1525
1543
  },
1526
1544
  messages: {
1527
1545
  errorListenInConnectedCallback: description$8
@@ -1565,7 +1583,8 @@ plugin.createRule({
1565
1583
  meta: {
1566
1584
  docs: {
1567
1585
  description: description$7,
1568
- defaultLevel: "warn"
1586
+ defaultLevel: "warn",
1587
+ isTypeChecked: false
1569
1588
  },
1570
1589
  messages: {
1571
1590
  noNonComponentExports: description$7,
@@ -1654,7 +1673,8 @@ plugin.createRule({
1654
1673
  meta: {
1655
1674
  docs: {
1656
1675
  description: description$6,
1657
- defaultLevel: "error"
1676
+ defaultLevel: "error",
1677
+ isTypeChecked: false
1658
1678
  },
1659
1679
  messages: {
1660
1680
  noPropertyNameStartWithOn: description$6
@@ -1699,7 +1719,8 @@ plugin.createRule({
1699
1719
  meta: {
1700
1720
  docs: {
1701
1721
  description: baseDescription,
1702
- defaultLevel: "warn"
1722
+ defaultLevel: "warn",
1723
+ isTypeChecked: true
1703
1724
  },
1704
1725
  messages: {
1705
1726
  errorFalseRendered: description$5
@@ -1750,7 +1771,8 @@ plugin.createRule({
1750
1771
  meta: {
1751
1772
  docs: {
1752
1773
  description: description$4,
1753
- defaultLevel: "warn"
1774
+ defaultLevel: "warn",
1775
+ isTypeChecked: false
1754
1776
  },
1755
1777
  messages: {
1756
1778
  needlessInlineJsxEventTypeAnnotation: "There is no need for this type annotation as JSX types already define event types.",
@@ -1840,7 +1862,8 @@ plugin.createRule({
1840
1862
  meta: {
1841
1863
  docs: {
1842
1864
  description: description$3,
1843
- defaultLevel: "warn"
1865
+ defaultLevel: "warn",
1866
+ isTypeChecked: false
1844
1867
  },
1845
1868
  messages: {
1846
1869
  noUnnecessaryAttributeName: description$3
@@ -1893,7 +1916,8 @@ plugin.createRule({
1893
1916
  meta: {
1894
1917
  docs: {
1895
1918
  description: description$2,
1896
- defaultLevel: "warn"
1919
+ defaultLevel: "warn",
1920
+ isTypeChecked: false
1897
1921
  },
1898
1922
  messages: {
1899
1923
  noUnnecessaryBindThis: description$2
@@ -1956,7 +1980,8 @@ plugin.createRule({
1956
1980
  meta: {
1957
1981
  docs: {
1958
1982
  description: description$1,
1959
- defaultLevel: "warn"
1983
+ defaultLevel: "warn",
1984
+ isTypeChecked: false
1960
1985
  },
1961
1986
  messages: {
1962
1987
  noUnnecessaryKey: description$1
@@ -2022,7 +2047,8 @@ plugin.createRule({
2022
2047
  meta: {
2023
2048
  docs: {
2024
2049
  description,
2025
- defaultLevel: "error"
2050
+ defaultLevel: "error",
2051
+ isTypeChecked: false
2026
2052
  },
2027
2053
  messages: {
2028
2054
  requireNamespace: "Custom element tag names in this project must start with one of the following namespaces: {{namespaces}}",
@@ -2,10 +2,22 @@ import type { RuleModule } from "@typescript-eslint/utils/ts-eslint";
2
2
  import type { TSESLint } from "@typescript-eslint/utils";
3
3
 
4
4
  export interface EslintPlugin extends TSESLint.FlatConfig.Plugin {
5
+ meta: EslintPluginMeta;
5
6
  configs: { recommended: TSESLint.FlatConfig.Config; };
6
7
  rules: Record<string, RuleModule<string, readonly unknown[], CommonDocs>>;
7
8
  }
8
9
 
10
+ export interface EslintPluginMeta extends TSESLint.FlatConfig.PluginMeta {
11
+ /**
12
+ * A set of rule names from current plugin that require type information.
13
+ *
14
+ * Generally, type checked rules are much slower as they need type checking.
15
+ * But once the first typed rule does the type checking, the other type
16
+ * checked rules don't add as much overhead.
17
+ */
18
+ typeCheckedRules: ReadonlySet<string>;
19
+ }
20
+
9
21
  export type CommonDocs = {
10
22
  /** Rule description */
11
23
  description: string;
@@ -13,4 +25,9 @@ export type CommonDocs = {
13
25
  defaultLevel: "error" | "off" | "warn";
14
26
  /** Short rule name - inherited from the createRule`s name property */
15
27
  name: string;
28
+ /**
29
+ * Whether the rule needs type information (whether it calls
30
+ * ESLintUtils.getParserServices).
31
+ */
32
+ isTypeChecked: boolean;
16
33
  };