@arcgis/eslint-config 5.2.0-next.57 → 5.2.0-next.59

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.
@@ -5,6 +5,7 @@ import reactJsxPlugin from "eslint-plugin-react-jsx";
5
5
  import regexpPlugin from "eslint-plugin-regexp";
6
6
  import unicornPlugin from "eslint-plugin-unicorn";
7
7
  import { join } from "node:path";
8
+ import tsEslint from "typescript-eslint";
8
9
  import { corePlugin } from "../plugins/core/index.js";
9
10
  const noRestrictedSyntax = [
10
11
  "error",
@@ -38,6 +39,20 @@ const noRestrictedSyntax = [
38
39
  const disabledMarkdownRules = Object.fromEntries(
39
40
  Object.keys(markdown.rules).map((ruleName) => [`markdown/${ruleName}`, "off"])
40
41
  );
42
+ const coreTypedRulesIgnoredFiles = [
43
+ // We didn't run typed rules on these files before
44
+ "packages/core-packages/core/*.{ts,tsx}",
45
+ "packages/core-packages/core/{.github,build,scripts,tasks,test-apps,typings}/**/*.{ts,tsx}",
46
+ // This folder runs in node, so uses a separate tsconfig.json
47
+ "packages/core-packages/core/tests/support/vitest/node/**/*.ts"
48
+ ];
49
+ const coreTypeCheckedRuleNames = new Set(Object.keys(tsEslint.configs.disableTypeChecked.rules ?? {})).union(
50
+ corePlugin.meta.typeCheckedRules
51
+ );
52
+ coreTypeCheckedRuleNames.delete("@typescript-eslint/naming-convention");
53
+ const disabledCoreTypeCheckedRules = Object.fromEntries(
54
+ Array.from(coreTypeCheckedRuleNames, (ruleName) => [ruleName, "off"])
55
+ );
41
56
  const eslintConfigCore = [
42
57
  {
43
58
  files: ["packages/core-packages/**/*.{ts,tsx}"],
@@ -516,8 +531,7 @@ const eslintConfigCore = [
516
531
  {
517
532
  // Type-aware rules
518
533
  files: ["packages/core-packages/**/*.{ts,tsx}"],
519
- // This folder runs in node, so uses a separate tsconfig.json
520
- ignores: ["packages/core-packages/core/tests/support/vitest/node/**/*.ts"],
534
+ ignores: [...coreTypedRulesIgnoredFiles],
521
535
  rules: {
522
536
  // Disabled until https://github.com/typescript-eslint/typescript-eslint/pull/11267 is available.
523
537
  "@typescript-eslint/await-thenable": "off",
@@ -534,6 +548,18 @@ const eslintConfigCore = [
534
548
  "@typescript-eslint/return-await": ["error", "error-handling-correctness-only"]
535
549
  }
536
550
  },
551
+ {
552
+ // The base config enables typed rules for all .ts files.
553
+ // Core has .ts files that are not typed rules ready.
554
+ // Disable the typed rules for those.
555
+ files: [...coreTypedRulesIgnoredFiles],
556
+ languageOptions: {
557
+ parserOptions: {
558
+ projectService: false
559
+ }
560
+ },
561
+ rules: disabledCoreTypeCheckedRules
562
+ },
537
563
  {
538
564
  files: ["packages/core-packages/**/*.tsx"],
539
565
  plugins: {
@@ -1,10 +1,11 @@
1
1
  import { ESLintUtils } from "@typescript-eslint/utils";
2
- const version = "5.2.0-next.57";
2
+ const version = "5.2.0-next.59";
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,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-BSUd88DM.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-bHvUvBdT.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";
@@ -14,7 +14,8 @@ plugin.createRule({
14
14
  meta: {
15
15
  docs: {
16
16
  description: "Checks that glsl tagged template strings don't have extra whitespace.",
17
- defaultLevel: "error"
17
+ defaultLevel: "error",
18
+ isTypeChecked: false
18
19
  },
19
20
  messages: {
20
21
  delete: "Delete `{{ deleteText }}`",
@@ -95,30 +96,26 @@ function removeLeadingBlankLines(text) {
95
96
  function removeTrailingBlankLines(text) {
96
97
  return text.replace(/(\r?\n)(\r?\n)*([ \t]*)`$/gu, "$1$3`");
97
98
  }
99
+ const projectMarker = "/src/";
100
+ let projectRoot = void 0;
98
101
  function findProjectRoot(filename) {
99
102
  const normalized = filename.replaceAll("\\", "/");
100
- let minimumIndex = Number.POSITIVE_INFINITY;
101
- for (const marker of ["src/", "tests/", "test-apps/", "esri/", ".github/"]) {
102
- const index = normalized.indexOf(marker);
103
- if (index === 0) {
104
- return ".";
105
- } else if (index > 0 && normalized.charCodeAt(index - 1) === slashCharCode) {
106
- minimumIndex = Math.min(minimumIndex, index);
107
- }
108
- }
109
- if (minimumIndex !== Number.POSITIVE_INFINITY) {
110
- return normalized.slice(0, minimumIndex);
103
+ const isProjectFile = normalized.includes(projectMarker);
104
+ if (isProjectFile && projectRoot) {
105
+ return projectRoot;
111
106
  }
112
107
  const fileToFind = "package.json";
113
108
  for (let root = dirname(filename), previousRoot = filename; root !== previousRoot; previousRoot = root, root = dirname(root)) {
114
109
  const filepath = join(root, fileToFind);
115
110
  if (existsSync(filepath)) {
111
+ if (isProjectFile) {
112
+ projectRoot = root;
113
+ }
116
114
  return root;
117
115
  }
118
116
  }
119
117
  return;
120
118
  }
121
- const slashCharCode = 47;
122
119
  const isWindows = process.platform === "win32";
123
120
  const collator = new Intl.Collator("en-US");
124
121
  plugin.createRule({
@@ -126,7 +123,8 @@ plugin.createRule({
126
123
  meta: {
127
124
  docs: {
128
125
  description: "Checks that imports are sorted and grouped",
129
- defaultLevel: "error"
126
+ defaultLevel: "error",
127
+ isTypeChecked: false
130
128
  },
131
129
  messages: {
132
130
  importFormat: "Imports are incorrectly sorted and/or grouped",
@@ -353,7 +351,8 @@ plugin.createRule({
353
351
  meta: {
354
352
  docs: {
355
353
  description: "Checks for duplicate comments before the first import declaration.",
356
- defaultLevel: "error"
354
+ defaultLevel: "error",
355
+ isTypeChecked: false
357
356
  },
358
357
  messages: { duplicate: "Delete duplicate comment" },
359
358
  schema: [],
@@ -395,7 +394,8 @@ plugin.createRule({
395
394
  meta: {
396
395
  docs: {
397
396
  description: "Checks for `todo` JSDoc tags with missing descriptions.",
398
- defaultLevel: "error"
397
+ defaultLevel: "error",
398
+ isTypeChecked: false
399
399
  },
400
400
  messages: { empty: "JSDoc `todo` tag description required" },
401
401
  schema: [],
@@ -420,7 +420,8 @@ plugin.createRule({
420
420
  meta: {
421
421
  docs: {
422
422
  description: "Enforces the declared class name passed to the @subclass() decorator",
423
- defaultLevel: "error"
423
+ defaultLevel: "error",
424
+ isTypeChecked: false
424
425
  },
425
426
  messages: {
426
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 `.`"
@@ -503,7 +504,8 @@ plugin.createRule({
503
504
  meta: {
504
505
  docs: {
505
506
  description: "Checks that files redundant to TypeScript implementation files are not checked in.",
506
- defaultLevel: "error"
507
+ defaultLevel: "error",
508
+ isTypeChecked: false
507
509
  },
508
510
  messages: {
509
511
  js: "Redundant JavaScript file detected. Please `git rm -f {{file}}`",
@@ -519,16 +521,16 @@ plugin.createRule({
519
521
  return {
520
522
  Program(node) {
521
523
  if (!filePath.endsWith(".d.ts") && tsRe.test(filePath)) {
522
- const projectRoot = findProjectRoot(filePath);
523
- if (!projectRoot) {
524
+ const projectRoot2 = findProjectRoot(filePath);
525
+ if (!projectRoot2) {
524
526
  context.report({ node, messageId: "missingProjectRoot" });
525
527
  return;
526
528
  }
527
- const gitIndexFiles2 = getGitIndexFiles(projectRoot);
529
+ const gitIndexFiles2 = getGitIndexFiles(projectRoot2);
528
530
  if (!gitIndexFiles2) {
529
531
  return;
530
532
  }
531
- filePath = relative(projectRoot, filePath);
533
+ filePath = relative(projectRoot2, filePath);
532
534
  const jsFilename = filePath.replace(tsRe, ".js");
533
535
  if (gitIndexFiles2.has(jsFilename)) {
534
536
  context.report({ node, messageId: "js", data: { file: jsFilename } });
@@ -547,7 +549,8 @@ plugin.createRule({
547
549
  meta: {
548
550
  docs: {
549
551
  description: "Checks that whenever possible import and export paths are relative instead of absolute.",
550
- defaultLevel: "error"
552
+ defaultLevel: "error",
553
+ isTypeChecked: false
551
554
  },
552
555
  messages: {
553
556
  importFormat: 'Prefer relative ("{{relPath}}") over absolute path',
@@ -625,7 +628,8 @@ plugin.createRule({
625
628
  meta: {
626
629
  docs: {
627
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.",
628
- defaultLevel: "error"
631
+ defaultLevel: "error",
632
+ isTypeChecked: false
629
633
  },
630
634
  messages: {
631
635
  missingImport: 'Import missing: import("@esri/calcite-components/dist/components/{{tag}}")',
@@ -674,7 +678,8 @@ plugin.createRule({
674
678
  meta: {
675
679
  docs: {
676
680
  description: "Enforce filenames to be part of spec (test) top-level suites.",
677
- defaultLevel: "error"
681
+ defaultLevel: "error",
682
+ isTypeChecked: false
678
683
  },
679
684
  messages: {
680
685
  name: "Suite name must be the name of the spec file",
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-BSUd88DM.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-bHvUvBdT.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
  };
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-BSUd88DM.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-bHvUvBdT.js";
2
2
  import { TSESTree, AST_TOKEN_TYPES, AST_NODE_TYPES, TSESLint } from "@typescript-eslint/utils";
3
3
  import path from "node:path";
4
4
  import { resolve } from "path/posix";
@@ -27,7 +27,8 @@ plugin.createRule({
27
27
  // Disabled by default because the rule is most relevant for autocasting
28
28
  // and only on public classes. We are discouraging autocasting in new
29
29
  // code.
30
- defaultLevel: "off"
30
+ defaultLevel: "off",
31
+ isTypeChecked: false
31
32
  },
32
33
  messages: {
33
34
  name: `By convention, the first parameter on an Accessor-based class must be called "properties". This is needed for autocasting - https://webgis.esri.com/references/api-extractor/api-node-kinds#constructor. If your class has constructors overloads, at least one of them must have a "properties" parameter.`,
@@ -111,13 +112,14 @@ If you wish to use a loose type like any/object, create a type alias \`type {{ e
111
112
  };
112
113
  }
113
114
  });
114
- const description$6 = `Enforce consistent logging so that ArcGIS developers can easily debug errors or warnings logged by our web components, which may lack a meaningful context in compiled code. See [our documentation on @arcgis/toolkit/log](https://webgis.esri.com/references/toolkit/log).`;
115
+ const description$7 = `Enforce consistent logging so that ArcGIS developers can easily debug errors or warnings logged by our web components, which may lack a meaningful context in compiled code. See [our documentation on @arcgis/toolkit/log](https://webgis.esri.com/references/toolkit/log).`;
115
116
  plugin.createRule({
116
117
  name: "consistent-logging",
117
118
  meta: {
118
119
  docs: {
119
- description: description$6,
120
- defaultLevel: "off"
120
+ description: description$7,
121
+ defaultLevel: "off",
122
+ isTypeChecked: false
121
123
  },
122
124
  messages: {
123
125
  consistentLoggingWarning: `For consistency, use the log utility from @arcgis/toolkit/log instead of console.{{logMethodName}}.`
@@ -155,7 +157,8 @@ plugin.createRule({
155
157
  description: "Enforce consistent mixin pattern. See https://webgis.esri.com/sdk/contributing/core/core/mixins",
156
158
  // Enabled by default because the rule targets a very specific pattern
157
159
  // and that pattern is tricky to get right without this rule.
158
- defaultLevel: "error"
160
+ defaultLevel: "error",
161
+ isTypeChecked: false
159
162
  },
160
163
  messages: {
161
164
  updateMixinCode: "Mixin typings need to be updated.",
@@ -480,17 +483,18 @@ function expressionToTypeString(expression, context, asConst) {
480
483
  }
481
484
  return;
482
485
  }
483
- const description$5 = "Using .d.ts files is discouraged. Prefer .ts files instead, as they are type-checked and not in global scope.";
486
+ const description$6 = "Using .d.ts files is discouraged. Prefer .ts files instead, as they are type-checked and not in global scope.";
484
487
  const allowedNames = /* @__PURE__ */ new Set(["vite-env.d.ts", "components.d.ts"]);
485
488
  plugin.createRule({
486
489
  name: "no-dts-files",
487
490
  meta: {
488
491
  docs: {
489
- description: description$5,
490
- defaultLevel: "warn"
492
+ description: description$6,
493
+ defaultLevel: "warn",
494
+ isTypeChecked: false
491
495
  },
492
496
  messages: {
493
- avoidDtsFiles: description$5
497
+ avoidDtsFiles: description$6
494
498
  },
495
499
  type: "suggestion",
496
500
  schema: []
@@ -526,7 +530,8 @@ plugin.createRule({
526
530
  docs: {
527
531
  description: "Disallow empty catch calls since empty catch calls in a promise chain don't catch any exceptions",
528
532
  // Enabled by default because this caught real bugs and has autofix
529
- defaultLevel: "error"
533
+ defaultLevel: "error",
534
+ isTypeChecked: false
530
535
  },
531
536
  messages: { emptyCatch: "no empty catch calls" },
532
537
  schema: [],
@@ -547,16 +552,17 @@ plugin.createRule({
547
552
  };
548
553
  }
549
554
  });
550
- const description$4 = `Imports of files outside the src/ folder are not-portable and likely to break for consumers of this package.`;
555
+ const description$5 = `Imports of files outside the src/ folder are not-portable and likely to break for consumers of this package.`;
551
556
  plugin.createRule({
552
557
  name: "no-import-outside-src",
553
558
  meta: {
554
559
  docs: {
555
- description: description$4,
556
- defaultLevel: "error"
560
+ description: description$5,
561
+ defaultLevel: "error",
562
+ isTypeChecked: false
557
563
  },
558
564
  messages: {
559
- noImportOutsideSrc: description$4
565
+ noImportOutsideSrc: description$5
560
566
  },
561
567
  type: "problem",
562
568
  schema: []
@@ -598,7 +604,8 @@ plugin.createRule({
598
604
  // Disabling by default because this matters for
599
605
  // lower-level libraries more than higher-level libraries or applications.
600
606
  // Also, many false-positives.
601
- defaultLevel: "off"
607
+ defaultLevel: "off",
608
+ isTypeChecked: false
602
609
  },
603
610
  schema: [
604
611
  {
@@ -684,6 +691,59 @@ function isClassDefinition(definition) {
684
691
  }
685
692
  return variableNode.init?.type === AST_NODE_TYPES.ClassExpression;
686
693
  }
694
+ const description$4 = "For Node.js compatibility, when TypeScript file imports another TypeScript file, use .ts extension over .js";
695
+ plugin.createRule({
696
+ name: "no-js-in-ts-imports",
697
+ meta: {
698
+ docs: {
699
+ description: description$4,
700
+ defaultLevel: "off",
701
+ isTypeChecked: false
702
+ },
703
+ messages: {
704
+ noJsInTsImports: description$4
705
+ },
706
+ type: "problem",
707
+ fixable: "code",
708
+ schema: []
709
+ },
710
+ defaultOptions: [],
711
+ create(context) {
712
+ if (!/\.tsx?$/u.test(context.filename)) {
713
+ return {};
714
+ }
715
+ function checkSpecifier(node) {
716
+ const specifier = node.value;
717
+ if (!(specifier.startsWith("./") || specifier.startsWith("../")) || !specifier.endsWith(".js")) {
718
+ return;
719
+ }
720
+ context.report({
721
+ node,
722
+ messageId: "noJsInTsImports",
723
+ data: { specifier },
724
+ fix: (fixer) => fixer.replaceTextRange([node.range[1] - 3, node.range[1] - 1], "ts")
725
+ });
726
+ }
727
+ return {
728
+ ImportDeclaration(node) {
729
+ checkSpecifier(node.source);
730
+ },
731
+ ImportExpression(node) {
732
+ if (node.source.type === AST_NODE_TYPES.Literal && typeof node.source.value === "string") {
733
+ checkSpecifier(node.source);
734
+ }
735
+ },
736
+ ExportAllDeclaration(node) {
737
+ checkSpecifier(node.source);
738
+ },
739
+ ExportNamedDeclaration(node) {
740
+ if (node.source) {
741
+ checkSpecifier(node.source);
742
+ }
743
+ }
744
+ };
745
+ }
746
+ });
687
747
  plugin.createRule({
688
748
  name: "no-kebab-case-props",
689
749
  meta: {
@@ -692,7 +752,8 @@ plugin.createRule({
692
752
  // Off by default till
693
753
  // https://devtopia.esri.com/WebGIS/arcgis-web-components/issues/5364#issuecomment-6321339
694
754
  // is resolved
695
- defaultLevel: "off"
755
+ defaultLevel: "off",
756
+ isTypeChecked: false
696
757
  },
697
758
  messages: {
698
759
  kebab: "JSX props should use camelCase instead of kebab-case, except for data- or aria- attributes"
@@ -749,7 +810,8 @@ plugin.createRule({
749
810
  meta: {
750
811
  docs: {
751
812
  description: description$3,
752
- defaultLevel: "off"
813
+ defaultLevel: "off",
814
+ isTypeChecked: false
753
815
  },
754
816
  messages: {
755
817
  noStoryRenderArgsTypeAnnotation: "Do not annotate `render(args)` in stories. Type the story with `Meta<T>` or `StoryObj<T>` and let `args` infer from that."
@@ -790,7 +852,8 @@ plugin.createRule({
790
852
  meta: {
791
853
  docs: {
792
854
  description: description$2,
793
- defaultLevel: "warn"
855
+ defaultLevel: "warn",
856
+ isTypeChecked: false
794
857
  },
795
858
  messages: {
796
859
  noTouchingJsDoc: description$2
@@ -835,7 +898,8 @@ plugin.createRule({
835
898
  meta: {
836
899
  docs: {
837
900
  description: description$1,
838
- defaultLevel: "warn"
901
+ defaultLevel: "warn",
902
+ isTypeChecked: false
839
903
  },
840
904
  messages: {
841
905
  error: description$1
@@ -890,7 +954,8 @@ plugin.createRule({
890
954
  docs: {
891
955
  description: "Async tests must await a screenshot assertion.",
892
956
  // Enabled by default because it targets a specific pattern and has autofix
893
- defaultLevel: "error"
957
+ defaultLevel: "error",
958
+ isTypeChecked: false
894
959
  },
895
960
  messages: { asyncAssert: "Async tests must await a screenshot assertion." },
896
961
  schema: [],
@@ -923,7 +988,8 @@ plugin.createRule({
923
988
  // presumably work correctly today) so enabling it is a bit too disruptive.
924
989
  // We should coordinate enabling it with enabling other lint rules to
925
990
  // announce at once.
926
- defaultLevel: "off"
991
+ defaultLevel: "off",
992
+ isTypeChecked: false
927
993
  },
928
994
  messages: { missingType: "An explicit type attribute is required on buttons" },
929
995
  schema: [],
@@ -952,7 +1018,8 @@ plugin.createRule({
952
1018
  meta: {
953
1019
  docs: {
954
1020
  description,
955
- defaultLevel: "warn"
1021
+ defaultLevel: "warn",
1022
+ isTypeChecked: false
956
1023
  },
957
1024
  messages: {
958
1025
  requireJsInImports: description
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcgis/eslint-config",
3
- "version": "5.2.0-next.57",
3
+ "version": "5.2.0-next.59",
4
4
  "description": "ESLint configuration for WebGIS SDK",
5
5
  "type": "module",
6
6
  "exports": {
@@ -41,7 +41,7 @@
41
41
  "tslib": "^2.8.1",
42
42
  "typescript": "~6.0.3",
43
43
  "typescript-eslint": "^8.63.0",
44
- "@arcgis/toolkit": "5.2.0-next.57"
44
+ "@arcgis/toolkit": "5.2.0-next.59"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "eslint": "^10.6.0"