@arcgis/eslint-config 5.1.0-next.6 → 5.1.0-next.60
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/index.js +12 -0
- package/dist/estree-kBWxXj93.js +161 -0
- package/dist/plugins/lumina/index.js +81 -138
- package/dist/plugins/lumina/rules/no-inline-exposure-jsdoc-tag.d.ts +2 -0
- package/dist/plugins/lumina/utils/estree.d.ts +11 -0
- package/dist/plugins/webgis/index.js +71 -16
- package/dist/plugins/webgis/rules/no-unsafe-hash-links.d.ts +2 -0
- package/dist/utils/disable-rules.d.ts +24 -0
- package/dist/utils/disable-rules.js +47 -0
- package/package.json +5 -2
- package/dist/makePlugin-C3S0T31x.js +0 -41
package/dist/config/index.js
CHANGED
|
@@ -213,6 +213,18 @@ const defaultConfig = [
|
|
|
213
213
|
"@typescript-eslint/restrict-plus-operands": ["warn", { allowNumberAndString: true }],
|
|
214
214
|
// We often actually have control characters in our regexes
|
|
215
215
|
"no-control-regex": "off",
|
|
216
|
+
"@typescript-eslint/no-restricted-imports": [
|
|
217
|
+
"error",
|
|
218
|
+
{
|
|
219
|
+
paths: [
|
|
220
|
+
{
|
|
221
|
+
name: "commander",
|
|
222
|
+
importNames: ["Command"],
|
|
223
|
+
message: "Import from @commander-js/extra-typings instead."
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
],
|
|
216
228
|
// Functions that deal with JSON.stringify/localStorage may have a type
|
|
217
229
|
// parameter as a more readable alternative to a type assertion.
|
|
218
230
|
// Also, this rule is quite complicated/expensive.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
2
|
+
const version = "5.1.0-next.60";
|
|
3
|
+
const packageJson = {
|
|
4
|
+
version
|
|
5
|
+
};
|
|
6
|
+
function makeEslintPlugin(pluginName, urlCreator) {
|
|
7
|
+
const rules = [];
|
|
8
|
+
const creator = ESLintUtils.RuleCreator(urlCreator);
|
|
9
|
+
return {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
11
|
+
createRule(rule) {
|
|
12
|
+
const { meta, name, ...rest } = rule;
|
|
13
|
+
const docs = { ...meta.docs, name };
|
|
14
|
+
const ruleModule = creator({ ...rest, meta: { ...meta, docs }, name });
|
|
15
|
+
rules.push(ruleModule);
|
|
16
|
+
return ruleModule;
|
|
17
|
+
},
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
19
|
+
finalize() {
|
|
20
|
+
const config = {
|
|
21
|
+
rules: Object.fromEntries(
|
|
22
|
+
rules.map((rule) => [`${pluginName}/${rule.meta.docs.name}`, rule.meta.docs.defaultLevel])
|
|
23
|
+
)
|
|
24
|
+
};
|
|
25
|
+
const plugin = {
|
|
26
|
+
meta: { name: `@arcgis/eslint-plugin-${pluginName}`, version: packageJson.version },
|
|
27
|
+
configs: {
|
|
28
|
+
recommended: config
|
|
29
|
+
},
|
|
30
|
+
rules: Object.fromEntries(rules.map((rule) => [rule.meta.docs.name, rule]))
|
|
31
|
+
};
|
|
32
|
+
config.plugins = {
|
|
33
|
+
[pluginName]: plugin
|
|
34
|
+
};
|
|
35
|
+
return plugin;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const unwrapExpression = (expression) => expression.type === AST_NODE_TYPES.TSAsExpression || expression.type === AST_NODE_TYPES.TSNonNullExpression || expression.type === AST_NODE_TYPES.TSSatisfiesExpression ? unwrapExpression(expression.expression) : expression;
|
|
40
|
+
const luminaEntrypointName = "@arcgis/lumina";
|
|
41
|
+
const luminaTestEntrypointName = "@arcgis/lumina-compiler/testing";
|
|
42
|
+
const luminaJsxExportName = "h";
|
|
43
|
+
function checkForLuminaJsx() {
|
|
44
|
+
const ImportDeclaration = (node) => {
|
|
45
|
+
if (node.source.value !== luminaEntrypointName) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const specifier of node.specifiers) {
|
|
49
|
+
if (specifier.type === AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES.Identifier && specifier.imported.name === luminaJsxExportName || specifier.imported.type === AST_NODE_TYPES.Literal && specifier.imported.value === luminaJsxExportName)) {
|
|
50
|
+
withProperty.isLuminaJsx = true;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const withProperty = ImportDeclaration;
|
|
56
|
+
return withProperty;
|
|
57
|
+
}
|
|
58
|
+
function hasDecorator(node, decoratorName) {
|
|
59
|
+
return node.decorators.some(
|
|
60
|
+
(decorator) => decorator.expression.type === AST_NODE_TYPES.CallExpression && decorator.expression.callee.type === AST_NODE_TYPES.Identifier && decorator.expression.callee.name === decoratorName
|
|
61
|
+
) ?? false;
|
|
62
|
+
}
|
|
63
|
+
function extractDeclareElementsInterface(node) {
|
|
64
|
+
return node.kind === "global" ? node.body.body.find(
|
|
65
|
+
(node2) => node2.type === AST_NODE_TYPES.TSInterfaceDeclaration && node2.id.name === "DeclareElements"
|
|
66
|
+
) : void 0;
|
|
67
|
+
}
|
|
68
|
+
function getComponentDeclaration(node) {
|
|
69
|
+
for (const member of node.body.body) {
|
|
70
|
+
if (member.type !== AST_NODE_TYPES.TSPropertySignature) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const type = member.typeAnnotation?.typeAnnotation;
|
|
74
|
+
if (type?.type !== AST_NODE_TYPES.TSTypeReference || type.typeName.type !== AST_NODE_TYPES.Identifier) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (member.key.type !== AST_NODE_TYPES.Literal) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
return member;
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const sourceCodeDeclaresComponent = (sourceCode) => sourceCode.text.includes("interface DeclareElements");
|
|
85
|
+
function isCreateEvent(node) {
|
|
86
|
+
return node.value?.type === AST_NODE_TYPES.CallExpression && node.value.callee.type === AST_NODE_TYPES.Identifier && node.value.callee.name === "createEvent" && !node.static;
|
|
87
|
+
}
|
|
88
|
+
const getProperty = (properties, name) => properties?.find(
|
|
89
|
+
(option) => option.type === AST_NODE_TYPES.Property && option.key.type === AST_NODE_TYPES.Identifier && option.key.name === name
|
|
90
|
+
)?.value;
|
|
91
|
+
function isGetterWithoutSetter(node) {
|
|
92
|
+
const isGetter = node.type === AST_NODE_TYPES.MethodDefinition && node.kind === "get";
|
|
93
|
+
if (!isGetter) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
const index = node.parent.body.indexOf(node);
|
|
97
|
+
const previousNode = node.parent.body.at(index - 1);
|
|
98
|
+
const nextNode = node.parent.body.at(index + 1);
|
|
99
|
+
const name = getName(node);
|
|
100
|
+
if (name === void 0) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const previousIsSetter = previousNode?.type === AST_NODE_TYPES.MethodDefinition && previousNode.kind === "set" && getName(previousNode) === name;
|
|
104
|
+
if (previousIsSetter) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const nextIsSetter = nextNode?.type === AST_NODE_TYPES.MethodDefinition && nextNode.kind === "set" && getName(nextNode) === name;
|
|
108
|
+
return !nextIsSetter;
|
|
109
|
+
}
|
|
110
|
+
function getName(node) {
|
|
111
|
+
if (node.key.type === AST_NODE_TYPES.Identifier) {
|
|
112
|
+
return node.key.name;
|
|
113
|
+
} else if (node.key.type === AST_NODE_TYPES.Literal && typeof node.key.value === "string") {
|
|
114
|
+
return node.key.value;
|
|
115
|
+
} else {
|
|
116
|
+
return void 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function parsePropertyDecorator(decorator) {
|
|
120
|
+
const isPropertyDecorator = decorator.expression.type === AST_NODE_TYPES.CallExpression && decorator.expression.callee.type === AST_NODE_TYPES.Identifier && decorator.expression.callee.name === "property";
|
|
121
|
+
if (!isPropertyDecorator) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const callExpression = decorator?.expression.type === AST_NODE_TYPES.CallExpression ? decorator.expression : void 0;
|
|
125
|
+
if (callExpression === void 0) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const options = callExpression.arguments[0]?.type === AST_NODE_TYPES.ObjectExpression ? callExpression.arguments[0] : void 0;
|
|
129
|
+
const properties = options?.properties;
|
|
130
|
+
return {
|
|
131
|
+
callExpression,
|
|
132
|
+
options,
|
|
133
|
+
properties
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function isBindThisCallee(callee) {
|
|
137
|
+
return callee.type === AST_NODE_TYPES.MemberExpression && // expression.identifier(this)
|
|
138
|
+
callee.property.type === AST_NODE_TYPES.Identifier && // expression.bind(this)
|
|
139
|
+
callee.property.name === "bind" && // expression.expression.bind(this)
|
|
140
|
+
callee.object.type === AST_NODE_TYPES.MemberExpression && // expression.identifier.bind(this)
|
|
141
|
+
callee.object.property.type === AST_NODE_TYPES.Identifier && // this.identifier.bind(this)
|
|
142
|
+
callee.object.object.type === AST_NODE_TYPES.ThisExpression;
|
|
143
|
+
}
|
|
144
|
+
export {
|
|
145
|
+
luminaEntrypointName as a,
|
|
146
|
+
luminaTestEntrypointName as b,
|
|
147
|
+
getProperty as c,
|
|
148
|
+
isCreateEvent as d,
|
|
149
|
+
extractDeclareElementsInterface as e,
|
|
150
|
+
getName as f,
|
|
151
|
+
getComponentDeclaration as g,
|
|
152
|
+
hasDecorator as h,
|
|
153
|
+
isGetterWithoutSetter as i,
|
|
154
|
+
checkForLuminaJsx as j,
|
|
155
|
+
isBindThisCallee as k,
|
|
156
|
+
luminaJsxExportName as l,
|
|
157
|
+
makeEslintPlugin as m,
|
|
158
|
+
parsePropertyDecorator as p,
|
|
159
|
+
sourceCodeDeclaresComponent as s,
|
|
160
|
+
unwrapExpression as u
|
|
161
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as makeEslintPlugin } from "../../
|
|
1
|
+
import { m as makeEslintPlugin, 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-kBWxXj93.js";
|
|
2
2
|
import { AST_NODE_TYPES, ESLintUtils, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
|
|
3
3
|
import ts from "typescript";
|
|
4
4
|
import { camelToKebab } from "@arcgis/toolkit/string";
|
|
@@ -6,105 +6,17 @@ const plugin = makeEslintPlugin(
|
|
|
6
6
|
"lumina",
|
|
7
7
|
(rule) => `https://devtopia.esri.com/WebGIS/arcgis-web-components/tree/main/packages/support-packages/eslint-config/src/plugins/lumina/rules/${rule}.ts`
|
|
8
8
|
);
|
|
9
|
-
const unwrapExpression = (expression) => expression.type === AST_NODE_TYPES.TSAsExpression || expression.type === AST_NODE_TYPES.TSNonNullExpression || expression.type === AST_NODE_TYPES.TSSatisfiesExpression ? unwrapExpression(expression.expression) : expression;
|
|
10
|
-
const luminaEntrypointName = "@arcgis/lumina";
|
|
11
|
-
const luminaTestEntrypointName = "@arcgis/lumina-compiler/testing";
|
|
12
|
-
const luminaJsxExportName = "h";
|
|
13
|
-
function checkForLuminaJsx() {
|
|
14
|
-
const ImportDeclaration = (node) => {
|
|
15
|
-
if (node.source.value !== luminaEntrypointName) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
for (const specifier of node.specifiers) {
|
|
19
|
-
if (specifier.type === AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES.Identifier && specifier.imported.name === luminaJsxExportName || specifier.imported.type === AST_NODE_TYPES.Literal && specifier.imported.value === luminaJsxExportName)) {
|
|
20
|
-
withProperty.isLuminaJsx = true;
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
const withProperty = ImportDeclaration;
|
|
26
|
-
return withProperty;
|
|
27
|
-
}
|
|
28
|
-
function hasDecorator(node, decoratorName) {
|
|
29
|
-
return node.decorators.some(
|
|
30
|
-
(decorator) => decorator.expression.type === AST_NODE_TYPES.CallExpression && decorator.expression.callee.type === AST_NODE_TYPES.Identifier && decorator.expression.callee.name === decoratorName
|
|
31
|
-
) ?? false;
|
|
32
|
-
}
|
|
33
|
-
function extractDeclareElementsInterface(node) {
|
|
34
|
-
return node.kind === "global" ? node.body.body.find(
|
|
35
|
-
(node2) => node2.type === AST_NODE_TYPES.TSInterfaceDeclaration && node2.id.name === "DeclareElements"
|
|
36
|
-
) : void 0;
|
|
37
|
-
}
|
|
38
|
-
function isCreateEvent(node) {
|
|
39
|
-
return node.value?.type === AST_NODE_TYPES.CallExpression && node.value.callee.type === AST_NODE_TYPES.Identifier && node.value.callee.name === "createEvent" && !node.static;
|
|
40
|
-
}
|
|
41
|
-
const getProperty = (properties, name) => properties?.find(
|
|
42
|
-
(option) => option.type === AST_NODE_TYPES.Property && option.key.type === AST_NODE_TYPES.Identifier && option.key.name === name
|
|
43
|
-
)?.value;
|
|
44
|
-
function isGetterWithoutSetter(node) {
|
|
45
|
-
const isGetter = node.type === AST_NODE_TYPES.MethodDefinition && node.kind === "get";
|
|
46
|
-
if (!isGetter) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
const index = node.parent.body.indexOf(node);
|
|
50
|
-
const previousNode = node.parent.body.at(index - 1);
|
|
51
|
-
const nextNode = node.parent.body.at(index + 1);
|
|
52
|
-
const name = getName(node);
|
|
53
|
-
if (name === void 0) {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
const previousIsSetter = previousNode?.type === AST_NODE_TYPES.MethodDefinition && previousNode.kind === "set" && getName(previousNode) === name;
|
|
57
|
-
if (previousIsSetter) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
const nextIsSetter = nextNode?.type === AST_NODE_TYPES.MethodDefinition && nextNode.kind === "set" && getName(nextNode) === name;
|
|
61
|
-
return !nextIsSetter;
|
|
62
|
-
}
|
|
63
|
-
function getName(node) {
|
|
64
|
-
if (node.key.type === AST_NODE_TYPES.Identifier) {
|
|
65
|
-
return node.key.name;
|
|
66
|
-
} else if (node.key.type === AST_NODE_TYPES.Literal && typeof node.key.value === "string") {
|
|
67
|
-
return node.key.value;
|
|
68
|
-
} else {
|
|
69
|
-
return void 0;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function parsePropertyDecorator(decorator) {
|
|
73
|
-
const isPropertyDecorator = decorator.expression.type === AST_NODE_TYPES.CallExpression && decorator.expression.callee.type === AST_NODE_TYPES.Identifier && decorator.expression.callee.name === "property";
|
|
74
|
-
if (!isPropertyDecorator) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const callExpression = decorator?.expression.type === AST_NODE_TYPES.CallExpression ? decorator.expression : void 0;
|
|
78
|
-
if (callExpression === void 0) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const options = callExpression.arguments[0]?.type === AST_NODE_TYPES.ObjectExpression ? callExpression.arguments[0] : void 0;
|
|
82
|
-
const properties = options?.properties;
|
|
83
|
-
return {
|
|
84
|
-
callExpression,
|
|
85
|
-
options,
|
|
86
|
-
properties
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function isBindThisCallee(callee) {
|
|
90
|
-
return callee.type === AST_NODE_TYPES.MemberExpression && // expression.identifier(this)
|
|
91
|
-
callee.property.type === AST_NODE_TYPES.Identifier && // expression.bind(this)
|
|
92
|
-
callee.property.name === "bind" && // expression.expression.bind(this)
|
|
93
|
-
callee.object.type === AST_NODE_TYPES.MemberExpression && // expression.identifier.bind(this)
|
|
94
|
-
callee.object.property.type === AST_NODE_TYPES.Identifier && // this.identifier.bind(this)
|
|
95
|
-
callee.object.object.type === AST_NODE_TYPES.ThisExpression;
|
|
96
|
-
}
|
|
97
9
|
const importDeclaration = `import { ${luminaJsxExportName} } from "${luminaEntrypointName}";`;
|
|
98
|
-
const description$
|
|
10
|
+
const description$l = `To use Lumina's JSX, you need to ${importDeclaration}`;
|
|
99
11
|
plugin.createRule({
|
|
100
12
|
name: "add-missing-jsx-import",
|
|
101
13
|
meta: {
|
|
102
14
|
docs: {
|
|
103
|
-
description: description$
|
|
15
|
+
description: description$l,
|
|
104
16
|
defaultLevel: "error"
|
|
105
17
|
},
|
|
106
18
|
messages: {
|
|
107
|
-
addMissingJsxImport: description$
|
|
19
|
+
addMissingJsxImport: description$l
|
|
108
20
|
},
|
|
109
21
|
type: "problem",
|
|
110
22
|
schema: [],
|
|
@@ -161,12 +73,12 @@ plugin.createRule({
|
|
|
161
73
|
};
|
|
162
74
|
}
|
|
163
75
|
});
|
|
164
|
-
const description$
|
|
76
|
+
const description$k = "Auto add { type: Boolean } or { type: Number } where necessary";
|
|
165
77
|
plugin.createRule({
|
|
166
78
|
name: "auto-add-type",
|
|
167
79
|
meta: {
|
|
168
80
|
docs: {
|
|
169
|
-
description: description$
|
|
81
|
+
description: description$k,
|
|
170
82
|
defaultLevel: "warn"
|
|
171
83
|
},
|
|
172
84
|
messages: {
|
|
@@ -184,6 +96,9 @@ More information: https://devtopia.esri.com/WebGIS/arcgis-web-components/issues/
|
|
|
184
96
|
},
|
|
185
97
|
defaultOptions: [],
|
|
186
98
|
create(context) {
|
|
99
|
+
if (!sourceCodeDeclaresComponent(context.sourceCode)) {
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
187
102
|
const services = ESLintUtils.getParserServices(context);
|
|
188
103
|
return {
|
|
189
104
|
Decorator(decorator) {
|
|
@@ -362,6 +277,9 @@ plugin.createRule({
|
|
|
362
277
|
type: "problem"
|
|
363
278
|
},
|
|
364
279
|
create(context) {
|
|
280
|
+
if (!sourceCodeDeclaresComponent(context.sourceCode)) {
|
|
281
|
+
return {};
|
|
282
|
+
}
|
|
365
283
|
const bannedEventToMessageLookup = /* @__PURE__ */ new Map();
|
|
366
284
|
context.options.forEach((option) => {
|
|
367
285
|
const event = typeof option === "string" ? option : option.event;
|
|
@@ -382,32 +300,24 @@ plugin.createRule({
|
|
|
382
300
|
});
|
|
383
301
|
}
|
|
384
302
|
}
|
|
385
|
-
const luminaJsxCheck = checkForLuminaJsx();
|
|
386
303
|
return {
|
|
387
|
-
"ImportDeclaration": luminaJsxCheck,
|
|
388
304
|
"CallExpression:matches([callee.property.name=addEventListener], [callee.property.name=removeEventListener]), CallExpression[callee.object.type=ThisExpression][callee.property.name=listen]"(node) {
|
|
389
|
-
if (!luminaJsxCheck.isLuminaJsx) {
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
305
|
const eventName = node.arguments[0].value;
|
|
393
306
|
checkEvent(node, eventName);
|
|
394
307
|
},
|
|
395
308
|
"CallExpression[callee.object.type=ThisExpression][callee.property.name=listenOn]"(node) {
|
|
396
|
-
if (!luminaJsxCheck.isLuminaJsx) {
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
309
|
const eventName = node.arguments[1].value;
|
|
400
310
|
checkEvent(node, eventName);
|
|
401
311
|
}
|
|
402
312
|
};
|
|
403
313
|
}
|
|
404
314
|
});
|
|
405
|
-
const description$
|
|
315
|
+
const description$j = `Lumina component must be declared in a TSX file with a matching folder name located inside of src/components folder.`;
|
|
406
316
|
plugin.createRule({
|
|
407
317
|
name: "component-placement-rules",
|
|
408
318
|
meta: {
|
|
409
319
|
docs: {
|
|
410
|
-
description: description$
|
|
320
|
+
description: description$j,
|
|
411
321
|
defaultLevel: "error"
|
|
412
322
|
},
|
|
413
323
|
messages: {
|
|
@@ -446,7 +356,7 @@ plugin.createRule({
|
|
|
446
356
|
};
|
|
447
357
|
}
|
|
448
358
|
});
|
|
449
|
-
const description$
|
|
359
|
+
const description$i = `Enforce consistent event naming.`;
|
|
450
360
|
const defaultOptions$1 = [
|
|
451
361
|
{
|
|
452
362
|
eventNamespaces: ["arcgis"],
|
|
@@ -457,7 +367,7 @@ plugin.createRule({
|
|
|
457
367
|
name: "consistent-event-naming",
|
|
458
368
|
meta: {
|
|
459
369
|
docs: {
|
|
460
|
-
description: description$
|
|
370
|
+
description: description$i,
|
|
461
371
|
defaultLevel: "warn"
|
|
462
372
|
},
|
|
463
373
|
messages: {
|
|
@@ -558,12 +468,12 @@ Discussion: https://devtopia.esri.com/WebGIS/arcgis-web-components/discussions/3
|
|
|
558
468
|
}
|
|
559
469
|
});
|
|
560
470
|
const capitalAfterLower = /(?<=[a-z\d])[A-Z]/u;
|
|
561
|
-
const description$
|
|
471
|
+
const description$h = `Enforce consistent usage of ? for marking property as nullable, rather than |null, |undefined or |Nil.`;
|
|
562
472
|
plugin.createRule({
|
|
563
473
|
name: "consistent-nullability",
|
|
564
474
|
meta: {
|
|
565
475
|
docs: {
|
|
566
|
-
description: description$
|
|
476
|
+
description: description$h,
|
|
567
477
|
// TODO: enable this by default
|
|
568
478
|
defaultLevel: "off"
|
|
569
479
|
},
|
|
@@ -639,12 +549,12 @@ plugin.createRule({
|
|
|
639
549
|
};
|
|
640
550
|
}
|
|
641
551
|
});
|
|
642
|
-
const description$
|
|
552
|
+
const description$g = `Enforce that @property(), @method() and createEvent() members are used in the correct context.`;
|
|
643
553
|
plugin.createRule({
|
|
644
554
|
name: "decorators-context",
|
|
645
555
|
meta: {
|
|
646
556
|
docs: {
|
|
647
|
-
description: description$
|
|
557
|
+
description: description$g,
|
|
648
558
|
defaultLevel: "error"
|
|
649
559
|
},
|
|
650
560
|
messages: {
|
|
@@ -662,6 +572,9 @@ If you wish to hide this member from public documentation, use @private or @prot
|
|
|
662
572
|
},
|
|
663
573
|
defaultOptions: [],
|
|
664
574
|
create(context) {
|
|
575
|
+
if (!sourceCodeDeclaresComponent(context.sourceCode)) {
|
|
576
|
+
return {};
|
|
577
|
+
}
|
|
665
578
|
return {
|
|
666
579
|
PropertyDefinition(node) {
|
|
667
580
|
const hasPropertyDecorator = hasDecorator(node, "property");
|
|
@@ -738,7 +651,7 @@ function isLuminaJsxType(type) {
|
|
|
738
651
|
}
|
|
739
652
|
const hasTypeFlag = (type, flag) => type.flags & flag ? true : (type.flags & ts.TypeFlags.Union) !== 0 && type.types.some((t) => hasTypeFlag(t, flag));
|
|
740
653
|
const literalTypeFlag = ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.BooleanLike;
|
|
741
|
-
const description$
|
|
654
|
+
const description$f = `Need to add explicit type annotation: {{ setterType }}
|
|
742
655
|
|
|
743
656
|
Explanation:
|
|
744
657
|
Lumina automatically creates an attribute for a property if property type includes a literal type (string|number|boolean).
|
|
@@ -749,11 +662,11 @@ plugin.createRule({
|
|
|
749
662
|
name: "explicit-setter-type",
|
|
750
663
|
meta: {
|
|
751
664
|
docs: {
|
|
752
|
-
description: description$
|
|
665
|
+
description: description$f,
|
|
753
666
|
defaultLevel: "error"
|
|
754
667
|
},
|
|
755
668
|
messages: {
|
|
756
|
-
explicitSetterType: description$
|
|
669
|
+
explicitSetterType: description$f,
|
|
757
670
|
addExplicitSetterType: `Add {{ setterType }} type annotation`
|
|
758
671
|
},
|
|
759
672
|
type: "problem",
|
|
@@ -1299,16 +1212,16 @@ function isCreateElementComponent(node) {
|
|
|
1299
1212
|
}
|
|
1300
1213
|
return false;
|
|
1301
1214
|
}
|
|
1302
|
-
const description$
|
|
1215
|
+
const description$e = `Use @internal or @private JSDoc tag over @ignore. See https://webgis.esri.com/references/lumina/documenting-components#excluding-api-from-public-documentation`;
|
|
1303
1216
|
plugin.createRule({
|
|
1304
1217
|
name: "no-ignore-jsdoc-tag",
|
|
1305
1218
|
meta: {
|
|
1306
1219
|
docs: {
|
|
1307
|
-
description: description$
|
|
1220
|
+
description: description$e,
|
|
1308
1221
|
defaultLevel: "error"
|
|
1309
1222
|
},
|
|
1310
1223
|
messages: {
|
|
1311
|
-
noIgnoreJsDocTag: description$
|
|
1224
|
+
noIgnoreJsDocTag: description$e
|
|
1312
1225
|
},
|
|
1313
1226
|
type: "problem",
|
|
1314
1227
|
schema: []
|
|
@@ -1337,12 +1250,12 @@ plugin.createRule({
|
|
|
1337
1250
|
}
|
|
1338
1251
|
});
|
|
1339
1252
|
const reIgnore = /\* @ignore/gu;
|
|
1340
|
-
const description$
|
|
1253
|
+
const description$d = `Detect incorrect usage of dynamic JSX tag name`;
|
|
1341
1254
|
plugin.createRule({
|
|
1342
1255
|
name: "no-incorrect-dynamic-tag-name",
|
|
1343
1256
|
meta: {
|
|
1344
1257
|
docs: {
|
|
1345
|
-
description: description$
|
|
1258
|
+
description: description$d,
|
|
1346
1259
|
defaultLevel: "error"
|
|
1347
1260
|
},
|
|
1348
1261
|
messages: {
|
|
@@ -1385,18 +1298,18 @@ plugin.createRule({
|
|
|
1385
1298
|
};
|
|
1386
1299
|
}
|
|
1387
1300
|
});
|
|
1388
|
-
const description$
|
|
1301
|
+
const description$c = `If inline arrow function is passed to ref, it will be called again on each render.
|
|
1389
1302
|
|
|
1390
1303
|
If this is not desirable, see alternatives: https://webgis.esri.com/references/lumina/jsx#refs`;
|
|
1391
1304
|
plugin.createRule({
|
|
1392
1305
|
name: "no-inline-arrow-in-ref",
|
|
1393
1306
|
meta: {
|
|
1394
1307
|
docs: {
|
|
1395
|
-
description: description$
|
|
1308
|
+
description: description$c,
|
|
1396
1309
|
defaultLevel: "warn"
|
|
1397
1310
|
},
|
|
1398
1311
|
messages: {
|
|
1399
|
-
errorInlineArrow: description$
|
|
1312
|
+
errorInlineArrow: description$c
|
|
1400
1313
|
},
|
|
1401
1314
|
type: "problem",
|
|
1402
1315
|
schema: []
|
|
@@ -1422,6 +1335,44 @@ plugin.createRule({
|
|
|
1422
1335
|
};
|
|
1423
1336
|
}
|
|
1424
1337
|
});
|
|
1338
|
+
const description$b = `Put @internal and @private on their own JSDoc line, not inline.`;
|
|
1339
|
+
plugin.createRule({
|
|
1340
|
+
name: "no-inline-exposure-jsdoc-tag",
|
|
1341
|
+
meta: {
|
|
1342
|
+
docs: {
|
|
1343
|
+
description: description$b,
|
|
1344
|
+
defaultLevel: "error"
|
|
1345
|
+
},
|
|
1346
|
+
messages: {
|
|
1347
|
+
inlineExposure: description$b
|
|
1348
|
+
},
|
|
1349
|
+
type: "problem",
|
|
1350
|
+
schema: []
|
|
1351
|
+
},
|
|
1352
|
+
defaultOptions: [],
|
|
1353
|
+
create(context) {
|
|
1354
|
+
return {
|
|
1355
|
+
"Program:exit"() {
|
|
1356
|
+
const source = context.sourceCode.text;
|
|
1357
|
+
for (const match of source.matchAll(/@(?:internal|private)\b/gu)) {
|
|
1358
|
+
const idx = match.index;
|
|
1359
|
+
const lineStart = source.lastIndexOf("\n", idx - 1) + 1;
|
|
1360
|
+
const before = source.slice(lineStart, idx).trim();
|
|
1361
|
+
if (before === "*" || before === "/**") {
|
|
1362
|
+
continue;
|
|
1363
|
+
}
|
|
1364
|
+
context.report({
|
|
1365
|
+
messageId: "inlineExposure",
|
|
1366
|
+
loc: {
|
|
1367
|
+
start: context.sourceCode.getLocFromIndex(idx - 1),
|
|
1368
|
+
end: context.sourceCode.getLocFromIndex(idx + match[0].length)
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
});
|
|
1425
1376
|
const description$a = `directives={} prop value must be an array literal. Documentation: https://webgis.esri.com/references/lumina/jsx#lit-directives`;
|
|
1426
1377
|
plugin.createRule({
|
|
1427
1378
|
name: "no-invalid-directives-prop",
|
|
@@ -1575,28 +1526,20 @@ plugin.createRule({
|
|
|
1575
1526
|
},
|
|
1576
1527
|
defaultOptions: [],
|
|
1577
1528
|
create(context) {
|
|
1578
|
-
|
|
1579
|
-
|
|
1529
|
+
if (!sourceCodeDeclaresComponent(context.sourceCode)) {
|
|
1530
|
+
return {};
|
|
1531
|
+
}
|
|
1532
|
+
let className;
|
|
1580
1533
|
return {
|
|
1581
1534
|
TSModuleDeclaration(node) {
|
|
1582
1535
|
const luminaDeclarationInterface = extractDeclareElementsInterface(node);
|
|
1583
1536
|
if (luminaDeclarationInterface === void 0) {
|
|
1584
1537
|
return;
|
|
1585
1538
|
}
|
|
1586
|
-
luminaDeclarationInterface.
|
|
1587
|
-
if (member.type !== AST_NODE_TYPES.TSPropertySignature || member.computed) {
|
|
1588
|
-
return;
|
|
1589
|
-
}
|
|
1590
|
-
const type = member.typeAnnotation?.typeAnnotation;
|
|
1591
|
-
if (type?.type !== AST_NODE_TYPES.TSTypeReference || type.typeName.type !== AST_NODE_TYPES.Identifier) {
|
|
1592
|
-
return;
|
|
1593
|
-
}
|
|
1594
|
-
const className = type.typeName.name;
|
|
1595
|
-
declaredComponents.add(className);
|
|
1596
|
-
});
|
|
1539
|
+
className = getComponentDeclaration(luminaDeclarationInterface)?.typeAnnotation?.typeAnnotation.typeName.name;
|
|
1597
1540
|
},
|
|
1598
1541
|
ExportNamedDeclaration(node) {
|
|
1599
|
-
if (
|
|
1542
|
+
if (className === void 0) {
|
|
1600
1543
|
return;
|
|
1601
1544
|
}
|
|
1602
1545
|
if (node.exportKind === "type") {
|
|
@@ -1620,7 +1563,7 @@ plugin.createRule({
|
|
|
1620
1563
|
) {
|
|
1621
1564
|
return;
|
|
1622
1565
|
} else if (node.declaration?.type === AST_NODE_TYPES.ClassDeclaration) {
|
|
1623
|
-
const isComponent =
|
|
1566
|
+
const isComponent = node.declaration.id?.name === className;
|
|
1624
1567
|
if (isComponent) {
|
|
1625
1568
|
return;
|
|
1626
1569
|
}
|
|
@@ -1631,7 +1574,7 @@ plugin.createRule({
|
|
|
1631
1574
|
});
|
|
1632
1575
|
},
|
|
1633
1576
|
ExportDefaultDeclaration(node) {
|
|
1634
|
-
if (
|
|
1577
|
+
if (className === void 0) {
|
|
1635
1578
|
return;
|
|
1636
1579
|
}
|
|
1637
1580
|
context.report({
|
|
@@ -1640,7 +1583,7 @@ plugin.createRule({
|
|
|
1640
1583
|
});
|
|
1641
1584
|
},
|
|
1642
1585
|
ExportAllDeclaration(node) {
|
|
1643
|
-
if (
|
|
1586
|
+
if (className === void 0) {
|
|
1644
1587
|
return;
|
|
1645
1588
|
}
|
|
1646
1589
|
if (node.exportKind === "type") {
|
|
@@ -9,6 +9,17 @@ export declare function checkForLuminaJsx(): LuminaJsxCheck & {
|
|
|
9
9
|
};
|
|
10
10
|
export declare function hasDecorator(node: Pick<TSESTree.PropertyDefinitionNonComputedName, "decorators">, decoratorName: string): boolean;
|
|
11
11
|
export declare function extractDeclareElementsInterface(node: TSESTree.TSModuleDeclaration): TSESTree.TSInterfaceDeclaration | undefined;
|
|
12
|
+
export declare function getComponentDeclaration(node: TSESTree.TSInterfaceDeclaration): {
|
|
13
|
+
key: TSESTree.Literal;
|
|
14
|
+
typeAnnotation: {
|
|
15
|
+
typeAnnotation: {
|
|
16
|
+
typeName: TSESTree.Identifier;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
} | undefined;
|
|
20
|
+
export declare const sourceCodeDeclaresComponent: (sourceCode: {
|
|
21
|
+
readonly text: string;
|
|
22
|
+
}) => boolean;
|
|
12
23
|
export declare function isCreateEvent(node: TSESTree.PropertyDefinition): boolean;
|
|
13
24
|
export declare const getProperty: (properties: TSESTree.ObjectLiteralElement[] | undefined, name: string) => TSESTree.Property["value"] | undefined;
|
|
14
25
|
export declare function isGetterWithoutSetter(node: TSESTree.MethodDefinition | TSESTree.PropertyDefinition): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as makeEslintPlugin } from "../../
|
|
1
|
+
import { m as makeEslintPlugin, e as extractDeclareElementsInterface, g as getComponentDeclaration } from "../../estree-kBWxXj93.js";
|
|
2
2
|
import { resolve } from "path/posix";
|
|
3
3
|
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
4
4
|
const plugin = makeEslintPlugin(
|
|
@@ -7,16 +7,16 @@ const plugin = makeEslintPlugin(
|
|
|
7
7
|
);
|
|
8
8
|
const isTestFile = (filePath) => filePath.includes("/test") || filePath.includes(".test") || filePath.includes(".spec") || filePath.includes("e2e") || filePath.includes("__") || filePath.includes("/.");
|
|
9
9
|
const isStorybookFile = (filePath) => filePath.includes(".stories");
|
|
10
|
-
const description$
|
|
10
|
+
const description$5 = `Imports of files outside the src/ folder are not-portable and likely to break for consumers of this package.`;
|
|
11
11
|
plugin.createRule({
|
|
12
12
|
name: "no-import-outside-src",
|
|
13
13
|
meta: {
|
|
14
14
|
docs: {
|
|
15
|
-
description: description$
|
|
15
|
+
description: description$5,
|
|
16
16
|
defaultLevel: "error"
|
|
17
17
|
},
|
|
18
18
|
messages: {
|
|
19
|
-
noImportOutsideSrc: description$
|
|
19
|
+
noImportOutsideSrc: description$5
|
|
20
20
|
},
|
|
21
21
|
type: "problem",
|
|
22
22
|
schema: []
|
|
@@ -50,16 +50,16 @@ plugin.createRule({
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
|
-
const description$
|
|
53
|
+
const description$4 = `Having two JSDoc comments next to each other is most likely a mistake - consider combining them into one, or separating them for clarity.`;
|
|
54
54
|
plugin.createRule({
|
|
55
55
|
name: "no-touching-jsdoc",
|
|
56
56
|
meta: {
|
|
57
57
|
docs: {
|
|
58
|
-
description: description$
|
|
58
|
+
description: description$4,
|
|
59
59
|
defaultLevel: "warn"
|
|
60
60
|
},
|
|
61
61
|
messages: {
|
|
62
|
-
noTouchingJsDoc: description$
|
|
62
|
+
noTouchingJsDoc: description$4
|
|
63
63
|
},
|
|
64
64
|
type: "problem",
|
|
65
65
|
schema: []
|
|
@@ -95,17 +95,17 @@ plugin.createRule({
|
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
const reTouchingJsDoc = /\*\/\s+\/\*\*/gu;
|
|
98
|
-
const description$
|
|
98
|
+
const description$3 = `@arcgis/core imports need to end with .js for better compatibility with ESM CDN builds for @arcgis/core and other packages.`;
|
|
99
99
|
const packagesToEnforce = ["@arcgis/core/", "@amcharts/amcharts4/", "@amcharts/amcharts5/"];
|
|
100
100
|
plugin.createRule({
|
|
101
101
|
name: "require-js-in-imports",
|
|
102
102
|
meta: {
|
|
103
103
|
docs: {
|
|
104
|
-
description: description$
|
|
104
|
+
description: description$3,
|
|
105
105
|
defaultLevel: "warn"
|
|
106
106
|
},
|
|
107
107
|
messages: {
|
|
108
|
-
requireJsInCoreImport: description$
|
|
108
|
+
requireJsInCoreImport: description$3
|
|
109
109
|
},
|
|
110
110
|
type: "problem",
|
|
111
111
|
fixable: "code",
|
|
@@ -117,7 +117,7 @@ plugin.createRule({
|
|
|
117
117
|
return {};
|
|
118
118
|
}
|
|
119
119
|
function updateSpecifier(node) {
|
|
120
|
-
if (node.source.type !== AST_NODE_TYPES.Literal
|
|
120
|
+
if (node.source.type !== AST_NODE_TYPES.Literal) {
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
const specifier = node.source.value;
|
|
@@ -139,17 +139,17 @@ plugin.createRule({
|
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
});
|
|
142
|
-
const description$
|
|
142
|
+
const description$2 = "Using .d.ts files is discouraged. Prefer .ts files instead, as they are type-checked and not in global scope.";
|
|
143
143
|
const allowedNames = /* @__PURE__ */ new Set(["vite-env.d.ts", "components.d.ts"]);
|
|
144
144
|
plugin.createRule({
|
|
145
145
|
name: "no-dts-files",
|
|
146
146
|
meta: {
|
|
147
147
|
docs: {
|
|
148
|
-
description: description$
|
|
148
|
+
description: description$2,
|
|
149
149
|
defaultLevel: "warn"
|
|
150
150
|
},
|
|
151
151
|
messages: {
|
|
152
|
-
avoidDtsFiles: description$
|
|
152
|
+
avoidDtsFiles: description$2
|
|
153
153
|
},
|
|
154
154
|
type: "suggestion",
|
|
155
155
|
schema: []
|
|
@@ -179,12 +179,12 @@ plugin.createRule({
|
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
181
|
});
|
|
182
|
-
const description = `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).`;
|
|
182
|
+
const description$1 = `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).`;
|
|
183
183
|
plugin.createRule({
|
|
184
184
|
name: "consistent-logging",
|
|
185
185
|
meta: {
|
|
186
186
|
docs: {
|
|
187
|
-
description,
|
|
187
|
+
description: description$1,
|
|
188
188
|
defaultLevel: "off"
|
|
189
189
|
// NOTE: this is turned on conditionally in root eslint config
|
|
190
190
|
},
|
|
@@ -217,6 +217,61 @@ plugin.createRule({
|
|
|
217
217
|
};
|
|
218
218
|
}
|
|
219
219
|
});
|
|
220
|
+
const description = `Do not use links like [](#something) as they are not portable across .d.ts, and are not validated at build time. Use {@link } syntax, or absolute links. See https://webgis.esri.com/webgis/core/core/documenting-api#link`;
|
|
221
|
+
plugin.createRule({
|
|
222
|
+
name: "no-unsafe-hash-links",
|
|
223
|
+
meta: {
|
|
224
|
+
docs: {
|
|
225
|
+
description,
|
|
226
|
+
defaultLevel: "warn"
|
|
227
|
+
},
|
|
228
|
+
messages: {
|
|
229
|
+
error: description
|
|
230
|
+
},
|
|
231
|
+
type: "problem",
|
|
232
|
+
schema: [],
|
|
233
|
+
fixable: "code"
|
|
234
|
+
},
|
|
235
|
+
defaultOptions: [],
|
|
236
|
+
create(context) {
|
|
237
|
+
let declareElementsInterface;
|
|
238
|
+
return {
|
|
239
|
+
"TSModuleDeclaration"(node) {
|
|
240
|
+
declareElementsInterface = extractDeclareElementsInterface(node);
|
|
241
|
+
},
|
|
242
|
+
"Program:exit"() {
|
|
243
|
+
if (declareElementsInterface === void 0 && !context.sourceCode.text.includes("@public") && !context.sourceCode.text.includes("@internal")) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
for (const match of context.sourceCode.text.matchAll(reHashLink)) {
|
|
247
|
+
const fullMatch = match[0];
|
|
248
|
+
const anchor = match[2];
|
|
249
|
+
const replacement = computeReplacement(declareElementsInterface, anchor);
|
|
250
|
+
context.report({
|
|
251
|
+
messageId: "error",
|
|
252
|
+
loc: {
|
|
253
|
+
start: context.sourceCode.getLocFromIndex(match.index),
|
|
254
|
+
end: context.sourceCode.getLocFromIndex(match.index + fullMatch.length)
|
|
255
|
+
},
|
|
256
|
+
fix: replacement === void 0 ? void 0 : (fixer) => fixer.replaceTextRange([match.index, match.index + fullMatch.length], `{@link ${replacement}}`)
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
const reHashLink = /\[([^\]\n]+)\]\(#([^)]+)\)/gu;
|
|
264
|
+
function computeReplacement(declareElementsInterface, anchor) {
|
|
265
|
+
if (declareElementsInterface === void 0) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const declaration = getComponentDeclaration(declareElementsInterface);
|
|
269
|
+
if (declaration === void 0) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const tagName = declaration.key.value;
|
|
273
|
+
return `components/${tagName}#${anchor}`;
|
|
274
|
+
}
|
|
220
275
|
const webgisPlugin = plugin.finalize();
|
|
221
276
|
export {
|
|
222
277
|
webgisPlugin
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
/**
|
|
3
|
+
* A utility for temporary running ESLint with only specific rules enabled.
|
|
4
|
+
*
|
|
5
|
+
* @param config flat config
|
|
6
|
+
* @param enabledRules exceptions
|
|
7
|
+
* @param disableTypeChecking make ESLint much faster by temporary disabling
|
|
8
|
+
* type-aware linting.
|
|
9
|
+
* @returns a new flat config array where every rule is disabled,
|
|
10
|
+
* except for rules explicitly listed in `enabledRules`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const config = [
|
|
14
|
+
* // Your ESLint flat config
|
|
15
|
+
* ];
|
|
16
|
+
* export default disableAllRulesExcept(
|
|
17
|
+
* config,
|
|
18
|
+
* {
|
|
19
|
+
* "rule-name-1": "error",
|
|
20
|
+
* },
|
|
21
|
+
* true,
|
|
22
|
+
* );
|
|
23
|
+
*/
|
|
24
|
+
export declare function disableAllRulesExcept(config: TSESLint.FlatConfig.ConfigArray, enabledRules: Record<string, TSESLint.FlatConfig.RuleLevel>, disableTypeChecking: boolean): TSESLint.FlatConfig.ConfigArray;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function disableAllRulesExcept(config, enabledRules, disableTypeChecking) {
|
|
2
|
+
return config.map((entry) => applyRulesAndOptions(entry, enabledRules, disableTypeChecking));
|
|
3
|
+
}
|
|
4
|
+
function applyRulesAndOptions(entry, enabledRules, disableTypeChecking) {
|
|
5
|
+
if (!entry || typeof entry !== "object") {
|
|
6
|
+
return entry;
|
|
7
|
+
}
|
|
8
|
+
const nextEntry = entry.rules ? {
|
|
9
|
+
...entry,
|
|
10
|
+
rules: Object.fromEntries(
|
|
11
|
+
Object.keys(entry.rules).map((ruleName) => {
|
|
12
|
+
const override = enabledRules[ruleName];
|
|
13
|
+
return [ruleName, override ?? "off"];
|
|
14
|
+
})
|
|
15
|
+
)
|
|
16
|
+
} : entry;
|
|
17
|
+
return tweakOptions(nextEntry, disableTypeChecking);
|
|
18
|
+
}
|
|
19
|
+
function tweakOptions(entry, disableTypeChecking) {
|
|
20
|
+
if (entry.linterOptions !== void 0) {
|
|
21
|
+
entry = {
|
|
22
|
+
...entry,
|
|
23
|
+
linterOptions: {
|
|
24
|
+
...entry.linterOptions,
|
|
25
|
+
reportUnusedDisableDirectives: "off",
|
|
26
|
+
reportUnusedInlineConfigs: "off"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (disableTypeChecking && entry.languageOptions?.parserOptions) {
|
|
31
|
+
entry = {
|
|
32
|
+
...entry,
|
|
33
|
+
languageOptions: {
|
|
34
|
+
...entry.languageOptions,
|
|
35
|
+
parserOptions: {
|
|
36
|
+
...entry.languageOptions.parserOptions,
|
|
37
|
+
project: void 0,
|
|
38
|
+
projectService: void 0
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return entry;
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
disableAllRulesExcept
|
|
47
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcgis/eslint-config",
|
|
3
|
-
"version": "5.1.0-next.
|
|
3
|
+
"version": "5.1.0-next.60",
|
|
4
4
|
"description": "ESLint configuration for arcgis-web-components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -8,11 +8,14 @@
|
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./dist/config/index.js",
|
|
11
|
+
"./ts": "./src/config/index.ts",
|
|
11
12
|
"./application": "./dist/config/applications.js",
|
|
12
13
|
"./extra": "./dist/config/extra.js",
|
|
13
14
|
"./lumina": "./dist/config/lumina.js",
|
|
15
|
+
"./lumina/ts": "./src/config/lumina.ts",
|
|
14
16
|
"./plugins/webgis": "./dist/plugins/webgis/index.js",
|
|
15
17
|
"./plugins/lumina": "./dist/plugins/lumina/index.js",
|
|
18
|
+
"./utils/disable-rules": "./dist/utils/disable-rules.js",
|
|
16
19
|
"./package.json": "./package.json"
|
|
17
20
|
},
|
|
18
21
|
"files": [
|
|
@@ -32,7 +35,7 @@
|
|
|
32
35
|
"tslib": "^2.8.1",
|
|
33
36
|
"typescript": "~5.9.3",
|
|
34
37
|
"typescript-eslint": "^8.46.3",
|
|
35
|
-
"@arcgis/toolkit": "5.1.0-next.
|
|
38
|
+
"@arcgis/toolkit": "5.1.0-next.60"
|
|
36
39
|
},
|
|
37
40
|
"peerDependencies": {
|
|
38
41
|
"eslint": "^9.39.1"
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
-
const version = "5.1.0-next.6";
|
|
3
|
-
const packageJson = {
|
|
4
|
-
version
|
|
5
|
-
};
|
|
6
|
-
function makeEslintPlugin(pluginName, urlCreator) {
|
|
7
|
-
const rules = [];
|
|
8
|
-
const creator = ESLintUtils.RuleCreator(urlCreator);
|
|
9
|
-
return {
|
|
10
|
-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
11
|
-
createRule(rule) {
|
|
12
|
-
const { meta, name, ...rest } = rule;
|
|
13
|
-
const docs = { ...meta.docs, name };
|
|
14
|
-
const ruleModule = creator({ ...rest, meta: { ...meta, docs }, name });
|
|
15
|
-
rules.push(ruleModule);
|
|
16
|
-
return ruleModule;
|
|
17
|
-
},
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
19
|
-
finalize() {
|
|
20
|
-
const config = {
|
|
21
|
-
rules: Object.fromEntries(
|
|
22
|
-
rules.map((rule) => [`${pluginName}/${rule.meta.docs.name}`, rule.meta.docs.defaultLevel])
|
|
23
|
-
)
|
|
24
|
-
};
|
|
25
|
-
const plugin = {
|
|
26
|
-
meta: { name: `@arcgis/eslint-plugin-${pluginName}`, version: packageJson.version },
|
|
27
|
-
configs: {
|
|
28
|
-
recommended: config
|
|
29
|
-
},
|
|
30
|
-
rules: Object.fromEntries(rules.map((rule) => [rule.meta.docs.name, rule]))
|
|
31
|
-
};
|
|
32
|
-
config.plugins = {
|
|
33
|
-
[pluginName]: plugin
|
|
34
|
-
};
|
|
35
|
-
return plugin;
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export {
|
|
40
|
-
makeEslintPlugin as m
|
|
41
|
-
};
|