@arcgis/eslint-config 5.2.0-next.51 → 5.2.0-next.53

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/README.md CHANGED
@@ -8,5 +8,5 @@ It is not intended to be used directly, but rather used as a dependency by other
8
8
 
9
9
  ## License
10
10
 
11
- This package is licensed under the terms described in the `LICENSE.md` file, located in the root of the package, and at https://js.arcgis.com/5.1/LICENSE.txt.
12
- For third party notices, see https://js.arcgis.com/5.1/third-party-notices.txt.
11
+ This package is licensed under the terms described in the `LICENSE.md` file, located in the root of the package, and at https://js.arcgis.com/5.2/LICENSE.txt.
12
+ For third party notices, see https://js.arcgis.com/5.2/third-party-notices.txt.
@@ -0,0 +1,621 @@
1
+ import markdown from "@eslint/markdown";
2
+ import jsdocPlugin from "eslint-plugin-jsdoc";
3
+ import perfectionistPlugin from "eslint-plugin-perfectionist";
4
+ import reactJsxPlugin from "eslint-plugin-react-jsx";
5
+ import regexpPlugin from "eslint-plugin-regexp";
6
+ import unicornPlugin from "eslint-plugin-unicorn";
7
+ import { join } from "node:path";
8
+ import { corePlugin } from "../plugins/core/index.js";
9
+ const noRestrictedSyntax = [
10
+ "error",
11
+ "AccessorProperty",
12
+ "PrivateIdentifier",
13
+ {
14
+ selector: "CallExpression[callee.property.name='concat'][arguments.length=0]",
15
+ message: "Use slice() instead of concat()."
16
+ },
17
+ {
18
+ selector: "CallExpression[callee.property.name='slice'][arguments.length=1] > .arguments[value=0]",
19
+ message: "Use slice() instead of slice(0)."
20
+ },
21
+ {
22
+ selector: "TSAbstractPropertyDefinition[decorators.length>0]",
23
+ message: "Decorators are not supported on abstract properties."
24
+ },
25
+ {
26
+ selector: "TSEnumDeclaration:not([const=true])",
27
+ message: "Don't declare non-const enums. Use `const enum` instead, or an object with `as const`. See https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums"
28
+ },
29
+ {
30
+ selector: "VariableDeclarator > CallExpression > MemberExpression[property.name='getLogger']",
31
+ message: "Get a logger as needed instead of assigning it for future use."
32
+ },
33
+ {
34
+ selector: "TSModuleDeclaration[id.type='Identifier']",
35
+ message: "Use const objects or static classes instead. See https://devtopia.esri.com/WebGIS/arcgis-js-api/discussions/72194"
36
+ }
37
+ ];
38
+ const disabledMarkdownRules = Object.fromEntries(
39
+ Object.keys(markdown.rules).map((ruleName) => [`markdown/${ruleName}`, "off"])
40
+ );
41
+ const eslintConfigCore = [
42
+ {
43
+ files: ["packages/core-packages/**/*.{ts,tsx}"],
44
+ linterOptions: {
45
+ reportUnusedDisableDirectives: "off"
46
+ },
47
+ plugins: {
48
+ core: corePlugin,
49
+ jsdoc: jsdocPlugin,
50
+ regexp: regexpPlugin,
51
+ unicorn: unicornPlugin
52
+ },
53
+ settings: {
54
+ jsdoc: {
55
+ tagNamePreference: {
56
+ // Our tags
57
+ "public": "public",
58
+ "copyDoc": "copyDoc",
59
+ // Flags
60
+ "beta": "beta",
61
+ "experimental": "experimental",
62
+ "readonly": "readonly",
63
+ // Metadata
64
+ "deprecated": "deprecated",
65
+ "default": "default",
66
+ "since": "since",
67
+ "param": "param",
68
+ "returns": "returns",
69
+ "see": "see",
70
+ "esriCompatibilityName": "esriCompatibilityName",
71
+ // Long descriptions
72
+ "example": "example",
73
+ "privateRemarks": "privateRemarks",
74
+ // Legacy replacements
75
+ "const": "readonly",
76
+ "constant": "readonly",
77
+ "defaultvalue": "default",
78
+ "return": "returns",
79
+ // Obsolete tags. Do not use in new code. These are retained for
80
+ // compatibility with existing non-public Core JSDoc.
81
+ "amdalias": "amdalias",
82
+ "autocast": "autocast",
83
+ "noautocast": "noautocast",
84
+ "constructonly": "constructonly",
85
+ "tag constructor": "constructor",
86
+ "deprecatedParameters": "deprecatedParameters",
87
+ "deprecatedProperties": "deprecatedProperties",
88
+ "esmimport": "esmimport",
89
+ "extends": "extends",
90
+ "method": "method",
91
+ "moduletype": "moduletype",
92
+ "ignoreNilOnly": "ignoreNilOnly"
93
+ }
94
+ }
95
+ },
96
+ rules: {
97
+ //#region Temporary Disable monorepo-exclusive rules
98
+ "@typescript-eslint/adjacent-overload-signatures": "off",
99
+ "@typescript-eslint/array-type": "off",
100
+ "@typescript-eslint/await-thenable": "off",
101
+ "@typescript-eslint/consistent-generic-constructors": "off",
102
+ "@typescript-eslint/consistent-indexed-object-style": "off",
103
+ "@typescript-eslint/consistent-type-assertions": "off",
104
+ "@typescript-eslint/consistent-type-exports": "off",
105
+ "@typescript-eslint/dot-notation": "off",
106
+ "@typescript-eslint/max-params": "off",
107
+ "@typescript-eslint/method-signature-style": "off",
108
+ "@typescript-eslint/no-confusing-non-null-assertion": "off",
109
+ "@typescript-eslint/no-deprecated": "off",
110
+ "@typescript-eslint/no-duplicate-type-constituents": "off",
111
+ "@typescript-eslint/no-dynamic-delete": "off",
112
+ "@typescript-eslint/no-empty-function": "off",
113
+ "@typescript-eslint/no-empty-object-type": "off",
114
+ "@typescript-eslint/no-explicit-any": "off",
115
+ "@typescript-eslint/no-extra-non-null-assertion": "off",
116
+ "@typescript-eslint/no-extraneous-class": "off",
117
+ "@typescript-eslint/no-implied-eval": "off",
118
+ "@typescript-eslint/no-inferrable-types": "off",
119
+ "@typescript-eslint/no-misused-new": "off",
120
+ "@typescript-eslint/no-misused-spread": "off",
121
+ "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "off",
122
+ "@typescript-eslint/no-non-null-asserted-optional-chain": "off",
123
+ "@typescript-eslint/no-redundant-type-constituents": "off",
124
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
125
+ "@typescript-eslint/no-unnecessary-condition": "off",
126
+ "@typescript-eslint/no-unnecessary-template-expression": "off",
127
+ "@typescript-eslint/no-unnecessary-type-assertion": "off",
128
+ "@typescript-eslint/no-unnecessary-type-constraint": "off",
129
+ "@typescript-eslint/no-unnecessary-type-conversion": "off",
130
+ "@typescript-eslint/no-unsafe-argument": "off",
131
+ "@typescript-eslint/no-unsafe-assignment": "off",
132
+ "@typescript-eslint/no-unsafe-call": "off",
133
+ "@typescript-eslint/no-unsafe-enum-comparison": "off",
134
+ "@typescript-eslint/no-unsafe-function-type": "off",
135
+ "@typescript-eslint/no-unsafe-member-access": "off",
136
+ "@typescript-eslint/no-useless-empty-export": "off",
137
+ "@typescript-eslint/no-wrapper-object-types": "off",
138
+ "@typescript-eslint/non-nullable-type-assertion-style": "off",
139
+ "@typescript-eslint/only-throw-error": "off",
140
+ "@typescript-eslint/prefer-as-const": "off",
141
+ "@typescript-eslint/prefer-function-type": "off",
142
+ "@typescript-eslint/prefer-promise-reject-errors": "off",
143
+ "@typescript-eslint/prefer-reduce-type-parameter": "off",
144
+ "@typescript-eslint/prefer-return-this-type": "off",
145
+ "@typescript-eslint/promise-function-async": "off",
146
+ "@typescript-eslint/related-getter-setter-pairs": "off",
147
+ "@typescript-eslint/require-array-sort-compare": "off",
148
+ "@typescript-eslint/require-await": "off",
149
+ "@typescript-eslint/restrict-plus-operands": "off",
150
+ "@typescript-eslint/restrict-template-expressions": "off",
151
+ "@typescript-eslint/sort-type-constituents": "off",
152
+ "@typescript-eslint/switch-exhaustiveness-check": "off",
153
+ "@typescript-eslint/triple-slash-reference": "off",
154
+ "@typescript-eslint/unified-signatures": "off",
155
+ "array-callback-return": "off",
156
+ "default-case-last": "off",
157
+ "func-names": "off",
158
+ "func-style": "off",
159
+ "grouped-accessor-pairs": "off",
160
+ "id-denylist": "off",
161
+ "lumina/add-missing-jsx-import": "off",
162
+ "lumina/auto-add-type": "off",
163
+ "lumina/component-placement-rules": "off",
164
+ "lumina/consistent-event-naming": "off",
165
+ "lumina/consistent-nullability": "off",
166
+ "lumina/decorators-context": "off",
167
+ "lumina/explicit-setter-type": "off",
168
+ "lumina/member-ordering": "off",
169
+ "lumina/no-create-element-component": "off",
170
+ "lumina/no-ignore-jsdoc-tag": "off",
171
+ "lumina/no-incorrect-dynamic-tag-name": "off",
172
+ "lumina/no-inline-arrow-in-ref": "off",
173
+ "lumina/no-inline-exposure-jsdoc-tag": "off",
174
+ "lumina/no-invalid-directives-prop": "off",
175
+ "lumina/no-jsdoc-xref-links": "off",
176
+ "lumina/no-jsx-spread": "off",
177
+ "lumina/no-listen-in-connected-callback": "off",
178
+ "lumina/no-non-component-exports": "off",
179
+ "lumina/no-property-name-start-with-on": "off",
180
+ "lumina/no-render-false": "off",
181
+ "lumina/no-unnecessary-assertion-on-event": "off",
182
+ "lumina/no-unnecessary-attribute-name": "off",
183
+ "lumina/no-unnecessary-bind-this": "off",
184
+ "lumina/no-unnecessary-key": "off",
185
+ "lumina/tag-name-rules": "off",
186
+ "no-alert": "off",
187
+ "no-await-in-loop": "off",
188
+ "no-constructor-return": "off",
189
+ "no-extend-native": "off",
190
+ "no-extra-bind": "off",
191
+ "no-loss-of-precision": "off",
192
+ "no-multi-assign": "off",
193
+ "no-object-constructor": "off",
194
+ "no-restricted-syntax": "off",
195
+ "no-return-assign": "off",
196
+ "no-script-url": "off",
197
+ "no-self-compare": "off",
198
+ "no-sequences": "off",
199
+ "no-unneeded-ternary": "off",
200
+ "no-unreachable-loop": "off",
201
+ "no-unsafe-negation": "off",
202
+ "no-useless-call": "off",
203
+ "no-useless-computed-key": "off",
204
+ "no-useless-concat": "off",
205
+ "no-warning-comments": "off",
206
+ "prefer-arrow-callback": "off",
207
+ "prefer-numeric-literals": "off",
208
+ "prefer-object-has-own": "off",
209
+ "prefer-object-spread": "off",
210
+ "prefer-regex-literals": "off",
211
+ "prefer-rest-params": "off",
212
+ "prefer-spread": "off",
213
+ "prefer-template": "off",
214
+ "require-atomic-updates": "off",
215
+ "require-unicode-regexp": "off",
216
+ "strict": "off",
217
+ "symbol-description": "off",
218
+ "unicode-bom": "off",
219
+ "unicorn/number-literal-case": "off",
220
+ "webgis/consistent-logging": "off",
221
+ "webgis/no-dts-files": "off",
222
+ "webgis/no-import-outside-src": "off",
223
+ "webgis/no-touching-jsdoc": "off",
224
+ "webgis/no-unsafe-hash-links": "off",
225
+ "webgis/require-await-for-async-screenshot-assert": "off",
226
+ "webgis/require-js-in-imports": "off",
227
+ "yoda": "off",
228
+ //#endregion
229
+ //#region Temporary enable core-exclusive rules
230
+ "@typescript-eslint/ban-ts-comment": ["error", { "ts-expect-error": false, "ts-nocheck": false }],
231
+ "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
232
+ "@typescript-eslint/explicit-function-return-type": ["error", { allowExpressions: true }],
233
+ "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }],
234
+ "@typescript-eslint/naming-convention": [
235
+ "error",
236
+ { selector: ["typeLike"], format: ["PascalCase"] },
237
+ {
238
+ selector: ["function", "classMethod", "classProperty", "typeMethod"],
239
+ format: ["camelCase"],
240
+ leadingUnderscore: "allow"
241
+ },
242
+ {
243
+ selector: ["memberLike", "classProperty"],
244
+ modifiers: ["private"],
245
+ format: ["camelCase"],
246
+ leadingUnderscore: "require"
247
+ },
248
+ {
249
+ selector: ["classProperty"],
250
+ modifiers: ["static"],
251
+ format: ["UPPER_CASE", "PascalCase", "camelCase"],
252
+ leadingUnderscore: "allow"
253
+ },
254
+ {
255
+ selector: ["classProperty"],
256
+ modifiers: ["private", "static"],
257
+ format: ["UPPER_CASE", "PascalCase", "camelCase"],
258
+ leadingUnderscore: "allow"
259
+ }
260
+ ],
261
+ "@typescript-eslint/no-array-constructor": "error",
262
+ "@typescript-eslint/no-import-type-side-effects": "error",
263
+ "@typescript-eslint/no-redeclare": "off",
264
+ // turn on when this doesn't error on mixins
265
+ "@typescript-eslint/no-require-imports": "error",
266
+ "@typescript-eslint/no-restricted-imports": [
267
+ "error",
268
+ {
269
+ paths: [
270
+ { name: "esri/identity/IdentityManager", message: "Use `esri/kernel.id` or the `authMode` option." },
271
+ {
272
+ name: "esri/layers/support/rasterFunctionUtils",
273
+ message: "Import raster function creators directly instead."
274
+ },
275
+ {
276
+ name: "esri/TimeExtent",
277
+ message: "Use `esri/time/TimeExtent` instead. See https://devtopia.esri.com/WebGIS/arcgis-js-api/issues/49223."
278
+ },
279
+ {
280
+ name: "esri/TimeInterval",
281
+ message: "Use `esri/time/TimeInterval` instead. See https://devtopia.esri.com/WebGIS/arcgis-js-api/issues/49223."
282
+ },
283
+ { name: "esri/rest/geometryService", message: "Import geometry services directly instead" },
284
+ { name: "esri/rest/geoprocessor", message: "Import geoprocessor exports directly instead" },
285
+ { name: "esri/rest/locator", message: "Import locator exports directly instead" },
286
+ { name: "esri/rest/query", message: "use individual files instead" }
287
+ ],
288
+ patterns: [
289
+ {
290
+ group: ["@esri/calcite-components/dist/components/*"],
291
+ message: "Pass a dynamic import to `loadCalciteComponents` inside `loadDependencies` instead.",
292
+ allowTypeImports: true
293
+ }
294
+ ]
295
+ }
296
+ ],
297
+ "@typescript-eslint/no-unnecessary-parameter-property-assignment": "error",
298
+ "@typescript-eslint/no-unused-expressions": ["error", { allowShortCircuit: true, allowTernary: true }],
299
+ "@typescript-eslint/no-unused-vars": [
300
+ "error",
301
+ {
302
+ args: "all",
303
+ argsIgnorePattern: "^_",
304
+ caughtErrors: "none",
305
+ destructuredArrayIgnorePattern: "^_",
306
+ varsIgnorePattern: "^_|^tsx",
307
+ ignoreRestSiblings: true,
308
+ enableAutofixRemoval: { imports: true }
309
+ }
310
+ ],
311
+ "@typescript-eslint/prefer-namespace-keyword": "error",
312
+ "arrow-body-style": "error",
313
+ "core/glsl-whitespace": "error",
314
+ "core/imports-format": "error",
315
+ "core/no-duplicate-import-comments": "error",
316
+ "core/no-empty-jsdoc-todo": "error",
317
+ "core/no-redundant-checked-in-files": "error",
318
+ "core/prefer-relative-imports": "error",
319
+ "core/require-calcite-import": "error",
320
+ "curly": "error",
321
+ "eqeqeq": ["error", "smart"],
322
+ "import-x/no-duplicates": "error",
323
+ "import-x/no-dynamic-require": ["error", { esmodule: true }],
324
+ "import-x/no-restricted-paths": [
325
+ "error",
326
+ {
327
+ // This is temporary. Once most of this config is merged with the
328
+ // root @arcgis/eslint-config, the core-specific rules can be moved
329
+ // into @webgis/monorepo-config
330
+ basePath: join(import.meta.dirname, "../../../../core-packages/core"),
331
+ zones: [
332
+ {
333
+ target: "src",
334
+ from: "src/identity/IdentityManager.ts",
335
+ message: "Use `kernel.id` or the `authMode` request option."
336
+ },
337
+ {
338
+ target: "src",
339
+ from: "src/layers/support/rasterFunctionUtils.ts",
340
+ message: "Import raster function creators directly instead."
341
+ },
342
+ {
343
+ target: "src",
344
+ from: "src/rest/geometryService.ts",
345
+ message: "Import the `geometryService` exports directly instead."
346
+ },
347
+ {
348
+ target: "src",
349
+ from: "src/rest/geoprocessor.ts",
350
+ message: "Import the geoprocessor exports directly instead."
351
+ },
352
+ {
353
+ target: "src",
354
+ from: "src/rest/locator.ts",
355
+ message: "Import the locator exports directly instead."
356
+ },
357
+ {
358
+ target: "src",
359
+ from: "src/rest/query.ts",
360
+ message: "Import the query exports directly instead"
361
+ },
362
+ {
363
+ target: "src",
364
+ from: "tests",
365
+ message: "Modules in /src should not import modules in /tests."
366
+ }
367
+ ]
368
+ }
369
+ ],
370
+ "import-x/no-useless-path-segments": "error",
371
+ "jsdoc/check-tag-names": [
372
+ "error",
373
+ { definedTags: ["tstype", "ignoreNilOnly", "noautocast", "collectionItemType"] }
374
+ ],
375
+ "jsdoc/check-types": "error",
376
+ // Ensure @readonly and @public is used without any content
377
+ "jsdoc/empty-tags": "error",
378
+ // Avoid /**\n ** something */
379
+ "jsdoc/no-multi-asterisks": ["error", { allowWhitespace: true }],
380
+ // Enforce each JSDoc line starts with *
381
+ "jsdoc/require-asterisk-prefix": "error",
382
+ // Enforce @param has param name
383
+ "jsdoc/require-param-name": "error",
384
+ "no-array-constructor": "off",
385
+ "no-async-promise-executor": "error",
386
+ "no-caller": "error",
387
+ "no-case-declarations": "error",
388
+ "no-cond-assign": "error",
389
+ "no-constant-binary-expression": "error",
390
+ "no-control-regex": "error",
391
+ "no-debugger": "error",
392
+ "no-duplicate-case": "error",
393
+ "no-else-return": "error",
394
+ "no-eval": "error",
395
+ "no-fallthrough": ["error", { reportUnusedFallthroughComment: false }],
396
+ "no-implied-eval": "error",
397
+ "no-inner-declarations": "error",
398
+ "no-labels": ["error", { allowLoop: true, allowSwitch: true }],
399
+ "no-new-func": "error",
400
+ "no-new-wrappers": "error",
401
+ "no-redeclare": "off",
402
+ "no-regex-spaces": "error",
403
+ "no-restricted-globals": ["error", "event", "name", "origin"],
404
+ "no-shadow-restricted-names": "error",
405
+ "no-throw-literal": "error",
406
+ "no-unsafe-finally": "error",
407
+ "no-unsafe-optional-chaining": "error",
408
+ "no-unused-expressions": "off",
409
+ "no-unused-vars": "off",
410
+ "no-useless-escape": "error",
411
+ "no-useless-rename": "error",
412
+ "no-var": "error",
413
+ "object-shorthand": "error",
414
+ "one-var": ["error", { initialized: "never" }],
415
+ "prefer-const": ["error", { destructuring: "all" }],
416
+ "prefer-exponentiation-operator": "error",
417
+ "radix": "error",
418
+ "regexp/control-character-escape": "error",
419
+ "regexp/no-dupe-characters-character-class": "error",
420
+ "regexp/no-dupe-disjunctions": "error",
421
+ "regexp/no-empty-alternative": "error",
422
+ "regexp/no-empty-capturing-group": "error",
423
+ "regexp/no-empty-character-class": "error",
424
+ "regexp/no-empty-group": "error",
425
+ "regexp/no-empty-lookarounds-assertion": "error",
426
+ "regexp/no-escape-backspace": "error",
427
+ "regexp/no-extra-lookaround-assertions": "error",
428
+ "regexp/no-invalid-regexp": "error",
429
+ "regexp/no-invisible-character": "error",
430
+ "regexp/no-lazy-ends": "error",
431
+ "regexp/no-misleading-unicode-character": "error",
432
+ "regexp/no-missing-g-flag": "error",
433
+ "regexp/no-obscure-range": "error",
434
+ "regexp/no-optional-assertion": "error",
435
+ "regexp/no-trivially-nested-assertion": "error",
436
+ "regexp/no-trivially-nested-quantifier": "error",
437
+ "regexp/no-useless-assertions": "error",
438
+ "regexp/no-useless-backreference": "error",
439
+ "regexp/no-useless-character-class": "error",
440
+ "regexp/no-useless-dollar-replacements": "error",
441
+ "regexp/no-useless-escape": "error",
442
+ // adds auto-fix and additional checks compared to `no-useless-escape`
443
+ "regexp/no-useless-lazy": "error",
444
+ "regexp/no-useless-quantifier": "error",
445
+ "regexp/no-useless-range": "error",
446
+ "regexp/no-useless-set-operand": "error",
447
+ "regexp/no-useless-string-literal": "error",
448
+ "regexp/no-useless-two-nums-quantifier": "error",
449
+ "regexp/optimal-quantifier-concatenation": "error",
450
+ "regexp/prefer-predefined-assertion": "error",
451
+ "regexp/prefer-range": "error",
452
+ "regexp/prefer-set-operation": "error",
453
+ "unicorn/consistent-date-clone": "error",
454
+ "unicorn/consistent-empty-array-spread": "error",
455
+ "unicorn/no-abusive-eslint-disable": "error",
456
+ "unicorn/no-accessor-recursion": "error",
457
+ "unicorn/no-await-in-promise-methods": "error",
458
+ "unicorn/no-instanceof-builtins": "error",
459
+ "unicorn/no-invalid-remove-event-listener": "error",
460
+ "unicorn/no-negation-in-equality-check": "error",
461
+ "unicorn/no-single-promise-in-promise-methods": "error",
462
+ "unicorn/no-typeof-undefined": "error",
463
+ "unicorn/no-unnecessary-array-flat-depth": "error",
464
+ "unicorn/no-unnecessary-array-splice-count": "error",
465
+ "unicorn/no-unnecessary-slice-end": "error",
466
+ "unicorn/no-useless-fallback-in-spread": "error",
467
+ "unicorn/no-useless-length-check": "error",
468
+ "unicorn/no-useless-promise-resolve-reject": "error",
469
+ "unicorn/no-useless-spread": "error",
470
+ "unicorn/no-useless-undefined": ["error", { checkArguments: false, checkArrowFunctionBody: false }],
471
+ "unicorn/prefer-array-find": "error",
472
+ "unicorn/prefer-array-flat": "error",
473
+ "unicorn/prefer-array-flat-map": "error",
474
+ "unicorn/prefer-array-index-of": "error",
475
+ "unicorn/prefer-array-some": "error",
476
+ "unicorn/prefer-blob-reading-methods": "error",
477
+ "unicorn/prefer-date-now": "error",
478
+ "unicorn/prefer-default-parameters": "error",
479
+ "unicorn/prefer-includes": "error",
480
+ "unicorn/prefer-logical-operator-over-ternary": "error",
481
+ "unicorn/prefer-negative-index": "error",
482
+ "unicorn/prefer-node-protocol": "error",
483
+ "unicorn/prefer-regexp-test": "error",
484
+ "unicorn/prefer-set-has": "error",
485
+ "unicorn/prefer-set-size": "error",
486
+ "unicorn/prefer-string-replace-all": "error",
487
+ "unicorn/prefer-string-slice": "error",
488
+ "unicorn/prefer-string-starts-ends-with": "error",
489
+ "unicorn/throw-new-error": "error",
490
+ "webgis/consistent-constructor-arguments": "error",
491
+ "webgis/consistent-mixin-syntax": "error",
492
+ "webgis/no-empty-catch": "error",
493
+ "webgis/no-kebab-case-props": "error",
494
+ "webgis/require-button-type": "error"
495
+ //#endregion
496
+ }
497
+ },
498
+ {
499
+ files: ["packages/core-packages/**/*.md"],
500
+ rules: disabledMarkdownRules
501
+ },
502
+ {
503
+ files: ["packages/core-packages/core/package.json"],
504
+ rules: {
505
+ // @typescript/native-preview temporarily uses the `beta` tag rather than a semver range.
506
+ "package-json/valid-devDependencies": "off"
507
+ }
508
+ },
509
+ {
510
+ files: ["packages/core-packages/**/*.d.ts"],
511
+ rules: {
512
+ "@typescript-eslint/naming-convention": "off"
513
+ // we can't enforce names in libraries
514
+ }
515
+ },
516
+ {
517
+ // Type-aware rules
518
+ 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"],
521
+ rules: {
522
+ // Disabled until https://github.com/typescript-eslint/typescript-eslint/pull/11267 is available.
523
+ "@typescript-eslint/await-thenable": "off",
524
+ "@typescript-eslint/no-array-delete": "error",
525
+ "@typescript-eslint/no-floating-promises": "error",
526
+ "@typescript-eslint/no-for-in-array": "error",
527
+ "@typescript-eslint/no-meaningless-void-operator": "error",
528
+ "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }],
529
+ "@typescript-eslint/no-unsafe-unary-minus": "error",
530
+ "@typescript-eslint/prefer-find": "error",
531
+ "@typescript-eslint/prefer-includes": "error",
532
+ "@typescript-eslint/prefer-optional-chain": ["error", { requireNullish: true }],
533
+ "@typescript-eslint/prefer-string-starts-ends-with": "error",
534
+ "@typescript-eslint/return-await": ["error", "error-handling-correctness-only"]
535
+ }
536
+ },
537
+ {
538
+ files: ["packages/core-packages/**/*.tsx"],
539
+ plugins: {
540
+ "perfectionist": perfectionistPlugin,
541
+ "react-jsx": reactJsxPlugin
542
+ },
543
+ rules: {
544
+ "perfectionist/sort-jsx-props": [
545
+ "error",
546
+ {
547
+ groups: ["unknown", "callback"],
548
+ customGroups: [{ groupName: "callback", elementNamePattern: "^on.+" }]
549
+ }
550
+ ],
551
+ "react-jsx/no-children-prop": "error",
552
+ "react-jsx/no-comment-textnodes": "error",
553
+ "react-jsx/no-useless-fragment": "error"
554
+ }
555
+ },
556
+ {
557
+ files: ["packages/core-packages/core/src/**/*.{ts,tsx}"],
558
+ rules: {
559
+ "core/no-invalid-declared-class": "error"
560
+ }
561
+ },
562
+ {
563
+ files: ["packages/core-packages/core/src/**/*.{ts,tsx}"],
564
+ ignores: ["packages/core-packages/core/src/**/*.d.ts"],
565
+ rules: {
566
+ "no-restricted-syntax": noRestrictedSyntax
567
+ }
568
+ },
569
+ {
570
+ files: ["packages/core-packages/core/src/**/*.{ts,tsx}"],
571
+ ignores: ["packages/core-packages/core/src/arcade/**", "packages/core-packages/core/src/widgets/**"],
572
+ rules: {
573
+ "webgis/no-instanceof": "error"
574
+ }
575
+ },
576
+ {
577
+ files: ["packages/core-packages/core/tests/**/*.{ts,tsx}"],
578
+ rules: {
579
+ "webgis/no-instanceof": "off",
580
+ "@typescript-eslint/no-restricted-imports": [
581
+ "error",
582
+ {
583
+ patterns: [
584
+ {
585
+ group: ["*.spec", "*.spec.*", "**/*.spec", "**/*.spec.*"],
586
+ message: "Do not import test suites (.spec) from other tests. Move shared helpers to tests/support (use the test-support/* alias)."
587
+ }
588
+ ]
589
+ }
590
+ ],
591
+ "core/spec-suite-filename": "error",
592
+ "no-restricted-syntax": [
593
+ ...noRestrictedSyntax,
594
+ {
595
+ message: "The { only: true } test option may be used during local testing, but can not be committed.",
596
+ selector: "CallExpression ObjectExpression Property[key.name='only'][value.value='true']"
597
+ },
598
+ {
599
+ message: "test.only may be used during local testing, but can not be committed.",
600
+ selector: "CallExpression[callee.type='MemberExpression'][callee.object.name='test'] > MemberExpression.callee > Identifier.property[name='only']"
601
+ },
602
+ {
603
+ message: "The { repeatUntilFailure: true } test option may be used during local testing, but can not be committed.",
604
+ selector: "CallExpression ObjectExpression Property[key.name='repeatUntilFailure'][value.value='true']"
605
+ },
606
+ {
607
+ message: "test.repeatUntilFailure may be used during local testing, but can not be committed.",
608
+ selector: "CallExpression[callee.type='MemberExpression'][callee.object.name='test'] > MemberExpression.callee > Identifier.property[name='repeatUntilFailure']"
609
+ },
610
+ {
611
+ selector: "CallExpression MemberExpression[object.name='has'][property.name='add']",
612
+ message: "Avoid adding has flags manually. Instead use the suite/test-level options to set has flags."
613
+ }
614
+ ],
615
+ "webgis/require-await-for-async-screenshot-assert": "error"
616
+ }
617
+ }
618
+ ];
619
+ export {
620
+ eslintConfigCore as default
621
+ };
@@ -7,9 +7,12 @@ import { globalIgnores } from "eslint/config";
7
7
  import markdown from "@eslint/markdown";
8
8
  import packageJson from "eslint-plugin-package-json";
9
9
  import { importX } from "eslint-plugin-import-x";
10
+ import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
10
11
  const packageJsonSortableCollections = packageJson.rules["sort-collections"].meta.defaultOptions[0].filter(
11
12
  (collection) => !["scripts", "exports"].includes(collection)
12
13
  ) ?? [];
14
+ const importXTypeScriptSettings = { ...importX.flatConfigs.typescript.settings };
15
+ delete importXTypeScriptSettings["import-x/resolver"];
13
16
  const config = [
14
17
  globalIgnores(["**/www", "**/dist", "**/assets", "**/coverage", "**/.docs"]),
15
18
  {
@@ -24,7 +27,13 @@ const config = [
24
27
  ...webgisPlugin.configs.recommended,
25
28
  files: ["**/*.ts", "**/*.tsx"]
26
29
  },
27
- importX.flatConfigs.typescript,
30
+ {
31
+ ...importX.flatConfigs.typescript,
32
+ settings: {
33
+ ...importXTypeScriptSettings,
34
+ "import-x/resolver-next": [createTypeScriptImportResolver()]
35
+ }
36
+ },
28
37
  {
29
38
  files: ["**/*.ts", "**/*.tsx"],
30
39
  linterOptions: {
@@ -1,5 +1,5 @@
1
1
  import { ESLintUtils } from "@typescript-eslint/utils";
2
- const version = "5.2.0-next.51";
2
+ const version = "5.2.0-next.53";
3
3
  const packageJson = {
4
4
  version
5
5
  };
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-DwtvWDJv.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-C1ZLydwC.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";
@@ -589,8 +589,15 @@ plugin.createRule({
589
589
  }
590
590
  });
591
591
  function pathRoot(p) {
592
- const dirName = path.dirname(p);
593
- return dirName === "." ? p : pathRoot(dirName);
592
+ const pathImplementation = win32.isAbsolute(p) && !posix.isAbsolute(p) ? win32 : path;
593
+ let root = p;
594
+ while (true) {
595
+ const parent = pathImplementation.dirname(root);
596
+ if (parent === "." || parent === root) {
597
+ return root;
598
+ }
599
+ root = parent;
600
+ }
594
601
  }
595
602
  function verifyRelativeImport(context, node, absImportPath, basePath, importRoot) {
596
603
  const modulePath = node.value;
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-DwtvWDJv.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-C1ZLydwC.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";
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-DwtvWDJv.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-C1ZLydwC.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";
@@ -4,7 +4,8 @@ import type { TSESLint } from "@typescript-eslint/utils";
4
4
  * A utility for temporary running ESLint with only specific rules enabled.
5
5
  *
6
6
  * @param config - flat config
7
- * @param enabledRules - exceptions
7
+ * @param enabledRules - exceptions. Set a rule to `true` to preserve existing
8
+ * configuration
8
9
  * @param disableTypeChecking - make ESLint much faster by temporary disabling
9
10
  * type-aware linting.
10
11
  * @returns a new flat config array where every rule is disabled,
@@ -21,4 +22,4 @@ import type { TSESLint } from "@typescript-eslint/utils";
21
22
  * true,
22
23
  * );
23
24
  */
24
- export function disableAllRulesExcept(config: TSESLint.FlatConfig.ConfigArray, enabledRules: Record<string, TSESLint.FlatConfig.RuleLevel>, disableTypeChecking: boolean): TSESLint.FlatConfig.ConfigArray;
25
+ export function disableAllRulesExcept(config: TSESLint.FlatConfig.ConfigArray, enabledRules: Partial<Record<string, TSESLint.FlatConfig.RuleEntry | true>>, disableTypeChecking: boolean): TSESLint.FlatConfig.ConfigArray;
@@ -10,7 +10,7 @@ function applyRulesAndOptions(entry, enabledRules, disableTypeChecking) {
10
10
  rules: Object.fromEntries(
11
11
  Object.keys(entry.rules).map((ruleName) => {
12
12
  const override = enabledRules[ruleName];
13
- return [ruleName, override ?? "off"];
13
+ return [ruleName, override === true ? entry.rules[ruleName] : override ?? "off"];
14
14
  })
15
15
  )
16
16
  } : entry;
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@arcgis/eslint-config",
3
- "version": "5.2.0-next.51",
3
+ "version": "5.2.0-next.53",
4
4
  "description": "ESLint configuration for WebGIS SDK",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./dist/config/index.js",
8
8
  "./application": "./dist/config/applications.js",
9
+ "./core": "./dist/config/core.js",
9
10
  "./extra": "./dist/config/extra.js",
10
11
  "./lumina": "./dist/config/lumina.js",
11
12
  "./plugins/core": "./dist/plugins/core/index.js",
@@ -27,15 +28,20 @@
27
28
  "confusing-browser-globals": "^1.0.11",
28
29
  "eslint-import-resolver-typescript": "^4.4.5",
29
30
  "eslint-plugin-import-x": "^4.17.1",
31
+ "eslint-plugin-jsdoc": "~63.0.13",
30
32
  "eslint-plugin-package-json": "~0.91.1",
33
+ "eslint-plugin-perfectionist": "~5.10.0",
34
+ "eslint-plugin-react-jsx": "~5.11.2",
35
+ "eslint-plugin-regexp": "~3.1.1",
31
36
  "eslint-plugin-storybook": "^10.3.4",
37
+ "eslint-plugin-unicorn": "~64.0.0",
32
38
  "globals": "^16.5.0",
33
39
  "jsonc-eslint-parser": "^3.1.0",
34
40
  "prettier-linter-helpers": "^1.0.1",
35
41
  "tslib": "^2.8.1",
36
42
  "typescript": "~6.0.3",
37
43
  "typescript-eslint": "^8.63.0",
38
- "@arcgis/toolkit": "5.2.0-next.51"
44
+ "@arcgis/toolkit": "5.2.0-next.53"
39
45
  },
40
46
  "peerDependencies": {
41
47
  "eslint": "^10.6.0"