@arcgis/eslint-config 5.2.0-next.58 → 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.
- package/dist/config/core.js +28 -2
- package/dist/{makePlugin-epAxL-HZ.js → makePlugin-bHvUvBdT.js} +6 -2
- package/dist/plugins/core/index.js +31 -26
- package/dist/plugins/lumina/index.js +53 -27
- package/dist/plugins/utils/makePlugin.d.ts +17 -0
- package/dist/plugins/webgis/index.js +90 -23
- package/package.json +2 -2
package/dist/config/core.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
523
|
-
if (!
|
|
524
|
+
const projectRoot2 = findProjectRoot(filePath);
|
|
525
|
+
if (!projectRoot2) {
|
|
524
526
|
context.report({ node, messageId: "missingProjectRoot" });
|
|
525
527
|
return;
|
|
526
528
|
}
|
|
527
|
-
const gitIndexFiles2 = getGitIndexFiles(
|
|
529
|
+
const gitIndexFiles2 = getGitIndexFiles(projectRoot2);
|
|
528
530
|
if (!gitIndexFiles2) {
|
|
529
531
|
return;
|
|
530
532
|
}
|
|
531
|
-
filePath = relative(
|
|
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-
|
|
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-
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
490
|
-
defaultLevel: "warn"
|
|
492
|
+
description: description$6,
|
|
493
|
+
defaultLevel: "warn",
|
|
494
|
+
isTypeChecked: false
|
|
491
495
|
},
|
|
492
496
|
messages: {
|
|
493
|
-
avoidDtsFiles: description$
|
|
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$
|
|
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$
|
|
556
|
-
defaultLevel: "error"
|
|
560
|
+
description: description$5,
|
|
561
|
+
defaultLevel: "error",
|
|
562
|
+
isTypeChecked: false
|
|
557
563
|
},
|
|
558
564
|
messages: {
|
|
559
|
-
noImportOutsideSrc: description$
|
|
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.
|
|
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.
|
|
44
|
+
"@arcgis/toolkit": "5.2.0-next.59"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"eslint": "^10.6.0"
|