@remcohaszing/eslint 11.0.0

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/lib/config.js ADDED
@@ -0,0 +1,1129 @@
1
+ /**
2
+ * @import {Linter} from 'eslint'
3
+ */
4
+
5
+ import markdown from '@eslint/markdown'
6
+ // @ts-expect-error
7
+ import eslintCommunityEslintComments from '@eslint-community/eslint-plugin-eslint-comments'
8
+ import stylistic from '@stylistic/eslint-plugin'
9
+ import typescriptEslint from '@typescript-eslint/eslint-plugin'
10
+ import typescriptEslintParser from '@typescript-eslint/parser'
11
+ import confusingBrowserGlobals from 'confusing-browser-globals'
12
+ import { defineConfig } from 'eslint/config'
13
+ import importX from 'eslint-plugin-import-x'
14
+ // @ts-expect-error
15
+ import jestFormatting from 'eslint-plugin-jest-formatting'
16
+ import jsdoc from 'eslint-plugin-jsdoc'
17
+ import n from 'eslint-plugin-n'
18
+ import perfectionist from 'eslint-plugin-perfectionist'
19
+ import { Alphabet } from 'eslint-plugin-perfectionist/alphabet'
20
+ import prettier from 'eslint-plugin-prettier'
21
+ import unicorn from 'eslint-plugin-unicorn'
22
+ import globals from 'globals'
23
+
24
+ import { allowedProperties } from './allowedProperties.js'
25
+ import { typesOnlyPackages } from './constants.js'
26
+ import { getIgnorePatterns } from './getIgnorePatterns.js'
27
+
28
+ const restrictedImports = [
29
+ { name: 'node:assert', message: 'Use node:assert/strict instead.' },
30
+ { name: 'node:test', importNames: ['it'], message: 'Use test instead.' },
31
+ { name: 'node:dns', importNames: ['promises'], message: 'Use node:dns/promises instead.' },
32
+ { name: 'node:fs', importNames: ['promises'], message: 'Use node:fs/promises instead.' },
33
+ {
34
+ name: 'node:stream',
35
+ importNames: ['promises'],
36
+ message: 'Use node:stream/promises instead.'
37
+ },
38
+ {
39
+ name: 'node:timers',
40
+ importNames: ['promises'],
41
+ message: 'Use node:timers/promises instead.'
42
+ }
43
+ ]
44
+
45
+ const characters = Alphabet.generateRecommendedAlphabet().getCharacters()
46
+ const slashIndex = characters.indexOf('/')
47
+ const alphabet = `/${characters.slice(0, slashIndex)}${characters.slice(slashIndex + 1)}`
48
+
49
+ /**
50
+ * Any function declaration whose name starts woth a lower case character.
51
+ */
52
+ const NON_COMPONENT_FUNCTION = 'FunctionDeclaration[id.name=/^[a-z]/]'
53
+ const METHOD_DEFINITION = 'MethodDefinition'
54
+
55
+ const config = defineConfig([
56
+ getIgnorePatterns() ?? {},
57
+ {
58
+ name: 'base',
59
+ languageOptions: {
60
+ globals: {
61
+ ...globals.browser,
62
+ ...globals.es2021,
63
+ ...globals.node
64
+ },
65
+ parserOptions: {
66
+ ecmaVersion: 'latest',
67
+ ecmaFeatures: {
68
+ globalReturn: true,
69
+ impliedStrict: true
70
+ },
71
+ sourceType: 'module'
72
+ }
73
+ },
74
+ linterOptions: {
75
+ reportUnusedDisableDirectives: 'error',
76
+ reportUnusedInlineConfigs: 'error'
77
+ },
78
+ plugins: {
79
+ '@stylistic': stylistic,
80
+ // @ts-expect-error
81
+ '@typescript-eslint': typescriptEslint,
82
+ '@eslint-community/eslint-comments': eslintCommunityEslintComments,
83
+ // @ts-expect-error
84
+ 'import-x': importX,
85
+ 'jest-formatting': jestFormatting,
86
+ jsdoc,
87
+ n,
88
+ perfectionist,
89
+ prettier,
90
+ unicorn
91
+ },
92
+ settings: {
93
+ 'import-x/extensions': [],
94
+ 'import-x/parsers': {
95
+ '@typescript-eslint/parser': ['.cts', '.mts', '.ts', '.tsx']
96
+ },
97
+ 'import-x/resolver': {
98
+ node: {
99
+ extensions: []
100
+ }
101
+ },
102
+ jsdoc: {
103
+ mode: 'typescript',
104
+ tagNamePreference: {
105
+ abstract: false,
106
+ access: false,
107
+ alias: false,
108
+ async: false,
109
+ augments: false,
110
+ author: false,
111
+ borrows: false,
112
+ class: false,
113
+ classdesc: false,
114
+ constant: false,
115
+ constructs: false,
116
+ copyright: false,
117
+ description: false,
118
+ event: false,
119
+ exports: false,
120
+ external: false,
121
+ fires: false,
122
+ function: false,
123
+ generator: false,
124
+ global: false,
125
+ hideconstructor: false,
126
+ ignore: false,
127
+ implements: false,
128
+ inner: false,
129
+ instance: false,
130
+ interface: false,
131
+ kind: false,
132
+ lends: false,
133
+ license: false,
134
+ listens: false,
135
+ member: false,
136
+ memberof: false,
137
+ 'memberof!': false,
138
+ mixes: false,
139
+ mixin: false,
140
+ module: false,
141
+ name: false,
142
+ namespace: false,
143
+ override: false,
144
+ package: false,
145
+ private: false,
146
+ protected: false,
147
+ public: false,
148
+ readonly: false,
149
+ requires: false,
150
+ since: false,
151
+ static: false,
152
+ summary: false,
153
+ todo: false,
154
+ tutorial: false,
155
+ variation: false,
156
+ version: false,
157
+ yields: false
158
+ }
159
+ },
160
+ node: {
161
+ convertPath: {
162
+ 'src/**': ['src/(.+?)\\.ts$', 'dist/$1.js']
163
+ },
164
+ tryExtensions: [],
165
+ version: '>=20'
166
+ },
167
+ perfectionist: {
168
+ type: 'natural',
169
+ ignoreCase: false,
170
+ fallbackSort: {
171
+ type: 'alphabetical'
172
+ }
173
+ }
174
+ },
175
+ rules: {
176
+ // https://eslint.org/docs/latest/rules/
177
+ 'accessor-pairs': 'error',
178
+ 'array-callback-return': ['error', { allowImplicit: true }],
179
+ 'arrow-body-style': 'error',
180
+ 'block-scoped-var': 'error',
181
+ camelcase: ['error', { allow: allowedProperties }],
182
+ 'capitalized-comments': [
183
+ 'error',
184
+ 'always',
185
+ {
186
+ ignoreConsecutiveComments: true,
187
+ ignorePattern: /^\s*(c8|type-coverage:|webpack\w)/.source
188
+ }
189
+ ],
190
+ 'class-methods-use-this': 'error',
191
+ 'consistent-this': 'error',
192
+ 'constructor-super': 'error',
193
+ curly: 'error',
194
+ 'default-case-last': 'error',
195
+ 'default-param-last': 'error',
196
+ 'dot-notation': 'error',
197
+ eqeqeq: ['error', 'always', { null: 'never' }],
198
+ 'for-direction': 'error',
199
+ 'func-names': 'error',
200
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
201
+ 'getter-return': 'error',
202
+ 'grouped-accessor-pairs': ['error', 'getBeforeSet'],
203
+ 'guard-for-in': 'error',
204
+ 'id-denylist': ['error', 'l', 'O', 'React'],
205
+ 'logical-assignment-operators': ['error', 'always', { enforceForIfStatements: true }],
206
+ 'new-cap': 'error',
207
+ 'no-alert': 'error',
208
+ 'no-array-constructor': 'error',
209
+ 'no-async-promise-executor': 'error',
210
+ 'no-caller': 'error',
211
+ 'no-case-declarations': 'error',
212
+ 'no-class-assign': 'error',
213
+ 'no-compare-neg-zero': 'error',
214
+ 'no-cond-assign': 'error',
215
+ 'no-console': 'error',
216
+ 'no-const-assign': 'error',
217
+ 'no-constant-binary-expression': 'error',
218
+ 'no-constant-condition': 'error',
219
+ 'no-constructor-return': 'error',
220
+ 'no-control-regex': 'error',
221
+ 'no-debugger': 'error',
222
+ 'no-dupe-args': 'error',
223
+ 'no-dupe-class-members': 'error',
224
+ 'no-dupe-else-if': 'error',
225
+ 'no-dupe-keys': 'error',
226
+ 'no-duplicate-case': 'error',
227
+ 'no-duplicate-imports': ['error', { includeExports: true }],
228
+ 'no-else-return': ['error', { allowElseIf: false }],
229
+ 'no-empty': 'error',
230
+ 'no-empty-character-class': 'error',
231
+ 'no-empty-function': 'error',
232
+ 'no-empty-pattern': 'error',
233
+ 'no-empty-static-block': 'error',
234
+ 'no-eval': 'error',
235
+ 'no-ex-assign': 'error',
236
+ 'no-extend-native': 'error',
237
+ 'no-extra-bind': 'error',
238
+ 'no-extra-boolean-cast': 'error',
239
+ 'no-extra-label': 'error',
240
+ 'no-fallthrough': 'error',
241
+ 'no-func-assign': 'error',
242
+ 'no-global-assign': 'error',
243
+ 'no-implicit-coercion': ['error', { disallowTemplateShorthand: true }],
244
+ 'no-implicit-globals': 'error',
245
+ 'no-implied-eval': 'error',
246
+ 'no-import-assign': 'error',
247
+ 'no-inline-comments': ['error', { ignorePattern: /\s@type\s/.source }],
248
+ 'no-inner-declarations': 'error',
249
+ 'no-invalid-regexp': 'error',
250
+ 'no-irregular-whitespace': ['error', { skipStrings: false }],
251
+ 'no-iterator': 'error',
252
+ 'no-label-var': 'error',
253
+ 'no-labels': ['error', { allowLoop: true }],
254
+ 'no-lone-blocks': 'error',
255
+ 'no-loop-func': 'error',
256
+ 'no-loss-of-precision': 'error',
257
+ 'no-misleading-character-class': 'error',
258
+ 'no-multi-assign': 'error',
259
+ 'no-multi-str': 'error',
260
+ 'no-new': 'error',
261
+ 'no-new-func': 'error',
262
+ 'no-new-native-nonconstructor': 'error',
263
+ 'no-new-wrappers': 'error',
264
+ 'no-obj-calls': 'error',
265
+ 'no-object-constructor': 'error',
266
+ 'no-octal-escape': 'error',
267
+ 'no-param-reassign': [
268
+ 'error',
269
+ {
270
+ props: true,
271
+ ignorePropertyModificationsFor: ['ast', 'ctx', 'element', 'hast', 'mdast', 'node', 'root']
272
+ }
273
+ ],
274
+ 'no-plusplus': 'error',
275
+ 'no-promise-executor-return': 'error',
276
+ 'no-proto': 'error',
277
+ 'no-prototype-builtins': 'error',
278
+ 'no-redeclare': 'error',
279
+ 'no-regex-spaces': 'error',
280
+ 'no-restricted-globals': [
281
+ 'error',
282
+ ...confusingBrowserGlobals.filter((name) => name !== 'self')
283
+ ],
284
+ 'no-restricted-imports': ['error', ...restrictedImports],
285
+ 'no-restricted-syntax': [
286
+ 'error',
287
+ {
288
+ // `value.toString()`
289
+ selector:
290
+ 'CallExpression[callee.property.name="toString"][callee.optional=false][arguments.length=0][optional=false]',
291
+ message: 'Use String() instead.'
292
+ },
293
+ {
294
+ selector: '[returnType.type="TSTypeAnnotation"]>TSTypeAnnotation>TSVoidKeyword',
295
+ message: 'Use undefined for non-returning functions of unknown for callbacks'
296
+ }
297
+ ],
298
+ 'no-return-assign': ['error', 'always'],
299
+ 'no-return-await': 'error',
300
+ 'no-script-url': 'error',
301
+ 'no-self-assign': 'error',
302
+ 'no-self-compare': 'error',
303
+ 'no-sequences': ['error', { allowInParentheses: false }],
304
+ 'no-setter-return': 'error',
305
+ 'no-shadow': ['error', { hoist: 'all' }],
306
+ 'no-shadow-restricted-names': 'error',
307
+ 'no-this-before-super': 'error',
308
+ 'no-throw-literal': 'error',
309
+ 'no-undef': 'error',
310
+ 'no-undef-init': 'error',
311
+ 'no-underscore-dangle': 'error',
312
+ 'no-unneeded-ternary': 'error',
313
+ 'no-unreachable': 'error',
314
+ 'no-unreachable-loop': 'error',
315
+ 'no-unsafe-finally': 'error',
316
+ 'no-unsafe-negation': 'error',
317
+ 'no-unsafe-optional-chaining': 'error',
318
+ 'no-unused-expressions': ['error', { enforceForJSX: true }],
319
+ 'no-unused-labels': 'error',
320
+ 'no-unused-private-class-members': 'error',
321
+ 'no-unused-vars': ['error', { ignoreRestSiblings: true }],
322
+ 'no-use-before-define': 'error',
323
+ 'no-useless-assignment': 'error',
324
+ 'no-useless-backreference': 'error',
325
+ 'no-useless-call': 'error',
326
+ 'no-useless-catch': 'error',
327
+ 'no-useless-computed-key': 'error',
328
+ 'no-useless-concat': 'error',
329
+ 'no-useless-constructor': 'error',
330
+ 'no-useless-escape': 'error',
331
+ 'no-useless-rename': 'error',
332
+ 'no-useless-return': 'error',
333
+ 'no-var': 'error',
334
+ 'no-void': 'error',
335
+ 'no-with': 'error',
336
+ 'object-shorthand': ['error', 'always', { avoidExplicitReturnArrows: true }],
337
+ 'one-var': ['error', 'never'],
338
+ 'operator-assignment': 'error',
339
+ 'prefer-arrow-callback': ['error', { allowUnboundThis: false }],
340
+ 'prefer-const': ['error', { destructuring: 'all', ignoreReadBeforeAssign: true }],
341
+ 'prefer-destructuring': [
342
+ 'error',
343
+ {
344
+ VariableDeclarator: { array: false, object: true },
345
+ AssignmentExpression: { array: false, object: false }
346
+ }
347
+ ],
348
+ 'prefer-exponentiation-operator': 'error',
349
+ 'prefer-numeric-literals': 'error',
350
+ 'prefer-object-spread': 'error',
351
+ 'prefer-promise-reject-errors': 'error',
352
+ 'prefer-regex-literals': 'error',
353
+ 'prefer-rest-params': 'error',
354
+ 'prefer-spread': 'error',
355
+ 'prefer-template': 'error',
356
+ radix: ['error', 'as-needed'],
357
+ 'require-await': 'error',
358
+ 'require-yield': 'error',
359
+ strict: 'error',
360
+ 'symbol-description': 'error',
361
+ 'use-isnan': ['error', { enforceForIndexOf: true }],
362
+ 'valid-typeof': 'error',
363
+ yoda: 'error',
364
+
365
+ // https://github.com/eslint-community/eslint-plugin-eslint-comments
366
+ '@eslint-community/eslint-comments/disable-enable-pair': 'error',
367
+ '@eslint-community/eslint-comments/no-aggregating-enable': 'error',
368
+ '@eslint-community/eslint-comments/no-duplicate-disable': 'error',
369
+ '@eslint-community/eslint-comments/no-unlimited-disable': 'error',
370
+ '@eslint-community/eslint-comments/no-unused-disable': 'error',
371
+ '@eslint-community/eslint-comments/no-unused-enable': 'error',
372
+ '@eslint-community/eslint-comments/no-use': [
373
+ 'error',
374
+ { allow: ['eslint-disable-next-line'] }
375
+ ],
376
+
377
+ // https://eslint.style
378
+ '@stylistic/jsx-curly-brace-presence': 'error',
379
+ '@stylistic/jsx-self-closing-comp': 'error',
380
+ '@stylistic/line-comment-position': 'error',
381
+ '@stylistic/lines-around-comment': [
382
+ 'error',
383
+ {
384
+ allowBlockStart: true,
385
+ allowObjectStart: true,
386
+ allowArrayStart: true,
387
+ allowClassStart: true,
388
+ allowEnumStart: true,
389
+ allowInterfaceStart: true,
390
+ allowModuleStart: true,
391
+ allowTypeStart: true
392
+ }
393
+ ],
394
+ '@stylistic/lines-between-class-members': 'error',
395
+ '@stylistic/max-len': [
396
+ 'error',
397
+ {
398
+ code: Number.MAX_SAFE_INTEGER,
399
+ comments: 100,
400
+ ignorePattern: /^(?!\s+(\/\/|\*))|eslint-disable/.source,
401
+ ignoreUrls: true,
402
+ ignoreRegExpLiterals: true,
403
+ ignoreStrings: true,
404
+ ignoreTemplateLiterals: true
405
+ }
406
+ ],
407
+ '@stylistic/multiline-comment-style': ['error', 'separate-lines'],
408
+ '@stylistic/no-tabs': ['error', { allowIndentationTabs: true }],
409
+ '@stylistic/padding-line-between-statements': 'error',
410
+ '@stylistic/quotes': ['error', 'single', { avoidEscape: true, ignoreStringLiterals: true }],
411
+ '@stylistic/spaced-comment': [
412
+ 'error',
413
+ 'always',
414
+ {
415
+ block: { balanced: true },
416
+ line: { markers: ['/'] }
417
+ }
418
+ ],
419
+
420
+ // https://github.com/un-ts/eslint-plugin-import-x
421
+ 'import-x/consistent-type-specifier-style': ['error', 'prefer-inline'],
422
+ 'import-x/export': 'error',
423
+ 'import-x/extensions': ['error', 'ignorePackages'],
424
+ 'import-x/first': 'error',
425
+ 'import-x/named': 'error',
426
+ 'import-x/namespace': 'error',
427
+ 'import-x/newline-after-import': 'error',
428
+ 'import-x/no-absolute-path': 'error',
429
+ 'import-x/no-amd': 'error',
430
+ 'import-x/no-anonymous-default-export': [
431
+ 'error',
432
+ {
433
+ allowArray: true,
434
+ allowArrowFunction: false,
435
+ allowAnonymousClass: false,
436
+ allowAnonymousFunction: false,
437
+ allowCallExpression: true,
438
+ allowLiteral: true,
439
+ allowNew: true,
440
+ allowObject: true
441
+ }
442
+ ],
443
+ 'import-x/no-duplicates': ['error', { 'prefer-inline': true }],
444
+ 'import-x/no-extraneous-dependencies': [
445
+ 'error',
446
+ {
447
+ devDependencies: false,
448
+ optionalDependencies: true,
449
+ peerDependencies: true,
450
+ bundledDependencies: true
451
+ }
452
+ ],
453
+ 'import-x/no-mutable-exports': 'error',
454
+ 'import-x/no-named-as-default': 'error',
455
+ 'import-x/no-named-default': 'error',
456
+ 'import-x/no-relative-packages': 'error',
457
+ 'import-x/no-self-import': 'error',
458
+ 'import-x/no-unresolved': [
459
+ 'error',
460
+ {
461
+ caseSensitiveStrict: true,
462
+ commonjs: true,
463
+ ignore: [/^[@a-z]/.source, /[!*]/.source, /.\.(cjs|js|mjs)$/.source]
464
+ }
465
+ ],
466
+ 'import-x/no-useless-path-segments': 'error',
467
+ 'import-x/no-webpack-loader-syntax': 'error',
468
+
469
+ // https://github.com/dangreenisrael/eslint-plugin-jest-formatting
470
+ 'jest-formatting/padding-around-after-all-blocks': 'error',
471
+ 'jest-formatting/padding-around-after-each-blocks': 'error',
472
+ 'jest-formatting/padding-around-before-all-blocks': 'error',
473
+ 'jest-formatting/padding-around-before-each-blocks': 'error',
474
+ 'jest-formatting/padding-around-describe-blocks': 'error',
475
+ 'jest-formatting/padding-around-test-blocks': 'error',
476
+
477
+ // https://github.com/gajus/eslint-plugin-jsdoc
478
+ 'jsdoc/check-access': 'error',
479
+ 'jsdoc/check-indentation': [
480
+ 'error',
481
+ { excludeTags: ['example', 'param', 'returns', 'throws', 'todo'] }
482
+ ],
483
+ 'jsdoc/check-line-alignment': ['error', 'never', { wrapIndent: ' ' }],
484
+ 'jsdoc/check-param-names': ['error', { checkDestructured: false }],
485
+ 'jsdoc/check-tag-names': ['error', { jsxTags: true }],
486
+ 'jsdoc/check-template-names': 'error',
487
+ 'jsdoc/empty-tags': 'error',
488
+ 'jsdoc/match-name': [
489
+ 'error',
490
+ {
491
+ match: [
492
+ {
493
+ tags: ['param'],
494
+ allowName: '/^[a-z][a-z\\d]*$/i',
495
+ message: 'Parameters names should be camel case'
496
+ }
497
+ ]
498
+ }
499
+ ],
500
+ 'jsdoc/multiline-blocks': [
501
+ 'error',
502
+ {
503
+ noSingleLineBlocks: true,
504
+ noZeroLineText: true,
505
+ singleLineTags: ['jsx', 'jsxFrag', 'jsxImportSource', 'jsxRuntime', 'type']
506
+ }
507
+ ],
508
+ 'jsdoc/no-bad-blocks': 'error',
509
+ 'jsdoc/no-blank-block-descriptions': 'error',
510
+ 'jsdoc/no-blank-blocks': 'error',
511
+ 'jsdoc/no-defaults': 'error',
512
+ 'jsdoc/no-multi-asterisks': 'error',
513
+ 'jsdoc/no-restricted-syntax': [
514
+ 'error',
515
+ {
516
+ contexts: [
517
+ {
518
+ comment: 'JsdocBlock:has(JsdocTag[tag=typedef][parsedType.value=/object/i])',
519
+ message: 'Omit the object type from typedef'
520
+ }
521
+ ]
522
+ }
523
+ ],
524
+ 'jsdoc/no-undefined-types': 'error',
525
+ 'jsdoc/require-asterisk-prefix': 'error',
526
+ 'jsdoc/require-description': 'error',
527
+ 'jsdoc/require-hyphen-before-param-description': ['error', 'never'],
528
+ 'jsdoc/require-jsdoc': [
529
+ 'error',
530
+ {
531
+ contexts: [
532
+ 'ExportNamedDeclaration > ClassDeclaration',
533
+ 'FunctionDeclaration',
534
+ 'TSIndexSignature',
535
+ 'TSPropertySignature'
536
+ ]
537
+ }
538
+ ],
539
+ 'jsdoc/require-param': [
540
+ 'error',
541
+ {
542
+ checkDestructured: false,
543
+ checkDestructuredRoots: true,
544
+ contexts: [METHOD_DEFINITION, NON_COMPONENT_FUNCTION],
545
+ unnamedRootBase: ['arg']
546
+ }
547
+ ],
548
+ 'jsdoc/require-param-description': 'error',
549
+ 'jsdoc/require-param-name': 'error',
550
+ 'jsdoc/require-param-type': 'error',
551
+ 'jsdoc/require-property-type': 'error',
552
+ 'jsdoc/require-returns': ['error', { contexts: [METHOD_DEFINITION, NON_COMPONENT_FUNCTION] }],
553
+ 'jsdoc/require-returns-check': 'error',
554
+ 'jsdoc/require-returns-description': 'error',
555
+ 'jsdoc/require-returns-type': 'error',
556
+ 'jsdoc/sort-tags': ['error', { alphabetizeExtras: true }],
557
+ 'jsdoc/tag-lines': ['error', 'never', { applyToEndTag: false, startLines: 1, endLines: 0 }],
558
+
559
+ // https://github.com/eslint-community/eslint-plugin-n
560
+ 'n/callback-return': ['error', ['callback', 'cb']],
561
+ 'n/exports-style': 'error',
562
+ 'n/handle-callback-err': ['error', /^(err\w*|\w*Error)$/.source],
563
+ 'n/hashbang': 'error',
564
+ 'n/no-deprecated-api': 'error',
565
+ 'n/no-extraneous-import': ['error', { allowModules: typesOnlyPackages }],
566
+ 'n/no-new-require': 'error',
567
+ 'n/no-path-concat': 'error',
568
+ 'n/no-unpublished-bin': 'error',
569
+ 'n/prefer-global/buffer': 'error',
570
+ 'n/prefer-global/console': 'error',
571
+ 'n/prefer-global/process': 'error',
572
+ 'n/prefer-global/text-decoder': 'error',
573
+ 'n/prefer-global/text-encoder': 'error',
574
+ 'n/prefer-global/url': 'error',
575
+ 'n/prefer-global/url-search-params': 'error',
576
+ 'n/prefer-promises/dns': 'error',
577
+ 'n/prefer-promises/fs': 'error',
578
+ 'n/process-exit-as-throw': 'error',
579
+
580
+ // https://perfectionist.dev
581
+ 'perfectionist/sort-array-includes': 'error',
582
+ 'perfectionist/sort-classes': 'error',
583
+ 'perfectionist/sort-exports': [
584
+ 'error',
585
+ {
586
+ type: 'custom',
587
+ alphabet
588
+ }
589
+ ],
590
+ 'perfectionist/sort-heritage-clauses': 'error',
591
+ 'perfectionist/sort-imports': [
592
+ 'error',
593
+ {
594
+ type: 'custom',
595
+ alphabet,
596
+ internalPattern: ['^#'],
597
+ groups: [
598
+ 'side-effect',
599
+ 'builtin',
600
+ 'external',
601
+ 'internal',
602
+ 'parent',
603
+ { newlinesBetween: 'never' },
604
+ ['sibling', 'index'],
605
+ 'unknown',
606
+ 'object'
607
+ ]
608
+ }
609
+ ],
610
+ 'perfectionist/sort-intersection-types': 'error',
611
+ 'perfectionist/sort-jsx-props': [
612
+ 'error',
613
+ {
614
+ groups: ['key', 'unknown'],
615
+ customGroups: [{ groupName: 'key', elementNamePattern: 'key' }]
616
+ }
617
+ ],
618
+ 'perfectionist/sort-maps': 'error',
619
+ 'perfectionist/sort-named-exports': 'error',
620
+ 'perfectionist/sort-named-imports': 'error',
621
+ 'perfectionist/sort-objects': ['error', { objectDeclarations: false }],
622
+ 'perfectionist/sort-union-types': 'error',
623
+
624
+ // https://github.com/prettier/eslint-plugin-prettier
625
+ 'prettier/prettier': 'error',
626
+
627
+ // https://github.com/sindresorhus/eslint-plugin-unicorn
628
+ 'unicorn/better-regex': 'error',
629
+ 'unicorn/catch-error-name': ['error', { name: 'error', ignore: ['err', /Error^/] }],
630
+ 'unicorn/consistent-assert': 'error',
631
+ 'unicorn/consistent-date-clone': 'error',
632
+ 'unicorn/consistent-destructuring': 'error',
633
+ 'unicorn/consistent-empty-array-spread': 'error',
634
+ 'unicorn/consistent-function-scoping': 'error',
635
+ 'unicorn/custom-error-definition': 'error',
636
+ 'unicorn/error-message': 'error',
637
+ 'unicorn/escape-case': 'error',
638
+ 'unicorn/expiring-todo-comments': ['warn', { allowWarningComments: false }],
639
+ 'unicorn/import-style': [
640
+ 'error',
641
+ {
642
+ extendDefaultStyles: false,
643
+ styles: {
644
+ 'node:child_process': { named: true },
645
+ 'node:crypto': { named: true },
646
+ 'node:events': { named: true },
647
+ 'node:fs': { named: true },
648
+ 'node:fs/promises': { named: true },
649
+ 'node:os': { named: true },
650
+ 'node:path': { named: true },
651
+ 'node:url': { named: true },
652
+ 'node:util': { named: true },
653
+ 'node:zlib': { named: true },
654
+
655
+ preact: { named: true },
656
+ 'preact/compat': { named: true },
657
+ 'preact/hooks': { named: true },
658
+ react: { named: true }
659
+ }
660
+ }
661
+ ],
662
+ 'unicorn/new-for-builtins': 'error',
663
+ 'unicorn/no-accessor-recursion': 'error',
664
+ 'unicorn/no-array-for-each': 'error',
665
+ 'unicorn/no-array-method-this-argument': 'error',
666
+ 'unicorn/no-array-push-push': 'error',
667
+ 'unicorn/no-array-reduce': 'error',
668
+ 'unicorn/no-await-in-promise-methods': 'error',
669
+ 'unicorn/no-console-spaces': 'error',
670
+ 'unicorn/no-document-cookie': 'error',
671
+ 'unicorn/no-empty-file': 'error',
672
+ 'unicorn/no-for-loop': 'error',
673
+ 'unicorn/no-hex-escape': 'error',
674
+ 'unicorn/no-instanceof-builtins': 'error',
675
+ 'unicorn/no-invalid-fetch-options': 'error',
676
+ 'unicorn/no-invalid-remove-event-listener': 'error',
677
+ 'unicorn/no-length-as-slice-end': 'error',
678
+ 'unicorn/no-lonely-if': 'error',
679
+ 'unicorn/no-named-default': 'error',
680
+ 'unicorn/no-negated-condition': 'error',
681
+ 'unicorn/no-negation-in-equality-check': 'error',
682
+ 'unicorn/no-new-array': 'error',
683
+ 'unicorn/no-object-as-default-parameter': 'error',
684
+ 'unicorn/no-single-promise-in-promise-methods': 'error',
685
+ 'unicorn/no-static-only-class': 'error',
686
+ 'unicorn/no-this-assignment': 'error',
687
+ 'unicorn/no-typeof-undefined': 'error',
688
+ 'unicorn/no-unnecessary-await': 'error',
689
+ 'unicorn/no-unreadable-iife': 'error',
690
+ 'unicorn/no-unused-properties': 'error',
691
+ 'unicorn/no-useless-fallback-in-spread': 'error',
692
+ 'unicorn/no-useless-length-check': 'error',
693
+ 'unicorn/no-useless-promise-resolve-reject': 'error',
694
+ 'unicorn/no-useless-spread': 'error',
695
+ 'unicorn/no-useless-switch-case': 'error',
696
+ 'unicorn/no-useless-undefined': 'error',
697
+ 'unicorn/no-zero-fractions': 'error',
698
+ 'unicorn/numeric-separators-style': 'error',
699
+ 'unicorn/prefer-array-find': 'error',
700
+ 'unicorn/prefer-array-flat': 'error',
701
+ 'unicorn/prefer-array-flat-map': 'error',
702
+ 'unicorn/prefer-array-index-of': 'error',
703
+ 'unicorn/prefer-array-some': 'error',
704
+ 'unicorn/prefer-at': 'error',
705
+ 'unicorn/prefer-blob-reading-methods': 'error',
706
+ 'unicorn/prefer-date-now': 'error',
707
+ 'unicorn/prefer-default-parameters': 'error',
708
+ 'unicorn/prefer-dom-node-append': 'error',
709
+ 'unicorn/prefer-dom-node-dataset': 'error',
710
+ 'unicorn/prefer-dom-node-remove': 'error',
711
+ 'unicorn/prefer-dom-node-text-content': 'error',
712
+ 'unicorn/prefer-event-target': 'error',
713
+ 'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
714
+ 'unicorn/prefer-global-this': 'error',
715
+ 'unicorn/prefer-includes': 'error',
716
+ 'unicorn/prefer-json-parse-buffer': 'error',
717
+ 'unicorn/prefer-keyboard-event-key': 'error',
718
+ 'unicorn/prefer-logical-operator-over-ternary': 'error',
719
+ 'unicorn/prefer-math-min-max': 'error',
720
+ 'unicorn/prefer-math-trunc': 'error',
721
+ 'unicorn/prefer-modern-dom-apis': 'error',
722
+ 'unicorn/prefer-modern-math-apis': 'error',
723
+ 'unicorn/prefer-native-coercion-functions': 'error',
724
+ 'unicorn/prefer-negative-index': 'error',
725
+ 'unicorn/prefer-node-protocol': 'error',
726
+ 'unicorn/prefer-number-properties': 'error',
727
+ 'unicorn/prefer-object-from-entries': 'error',
728
+ 'unicorn/prefer-optional-catch-binding': 'error',
729
+ 'unicorn/prefer-prototype-methods': 'error',
730
+ 'unicorn/prefer-reflect-apply': 'error',
731
+ 'unicorn/prefer-regexp-test': 'error',
732
+ 'unicorn/prefer-set-has': 'error',
733
+ 'unicorn/prefer-set-size': 'error',
734
+ 'unicorn/prefer-string-replace-all': 'error',
735
+ 'unicorn/prefer-string-slice': 'error',
736
+ 'unicorn/prefer-string-starts-ends-with': 'error',
737
+ 'unicorn/prefer-string-trim-start-end': 'error',
738
+ 'unicorn/prefer-structured-clone': 'error',
739
+ 'unicorn/prefer-ternary': 'error',
740
+ 'unicorn/prefer-top-level-await': 'error',
741
+ 'unicorn/prefer-type-error': 'error',
742
+ 'unicorn/relative-url-style': 'error',
743
+ 'unicorn/require-post-message-target-origin': 'error',
744
+ 'unicorn/switch-case-braces': ['error', 'avoid'],
745
+ 'unicorn/template-indent': 'error',
746
+ 'unicorn/text-encoding-identifier-case': 'error',
747
+ 'unicorn/throw-new-error': 'error'
748
+ }
749
+ },
750
+
751
+ /**
752
+ * Enable the TypeScript rules for TypeScript files.
753
+ */
754
+ {
755
+ name: 'typescript',
756
+ files: ['**/*.cts', '**/*.mts', '**/*.ts', '**/*.tsx'],
757
+ languageOptions: {
758
+ parser: typescriptEslintParser,
759
+ parserOptions: {
760
+ ecmaVersion: 'latest',
761
+ globalReturn: true,
762
+ warnOnUnsupportedTypeScriptVersion: false
763
+ }
764
+ },
765
+ rules: {
766
+ 'array-callback-return': 'off',
767
+ camelcase: 'off',
768
+ 'class-methods-use-this': 'off',
769
+ 'default-param-last': 'off',
770
+ 'getter-return': 'off',
771
+ 'init-declarations': 'off',
772
+ 'max-params': 'off',
773
+ 'new-cap': 'off',
774
+ 'no-array-constructor': 'off',
775
+ 'no-dupe-class-members': 'off',
776
+ 'no-empty-function': 'off',
777
+ 'no-loop-func': 'off',
778
+ 'no-magic-numbers': 'off',
779
+ 'no-obj-calls': 'off',
780
+ 'no-redeclare': 'off',
781
+ 'no-restricted-imports': 'off',
782
+ 'no-setter-return': 'off',
783
+ 'no-shadow': 'off',
784
+ 'no-undef': 'off',
785
+ 'no-unused-expressions': 'off',
786
+ 'no-unused-vars': 'off',
787
+ 'no-use-before-define': 'off',
788
+ 'no-useless-constructor': 'off',
789
+
790
+ '@typescript-eslint/adjacent-overload-signatures': 'error',
791
+ '@typescript-eslint/array-type': 'error',
792
+ '@typescript-eslint/ban-ts-comment': [
793
+ 'error',
794
+ {
795
+ 'ts-expect-error': 'allow-with-description',
796
+ 'ts-check': true,
797
+ 'ts-ignore': true,
798
+ 'ts-nocheck': true
799
+ }
800
+ ],
801
+ '@typescript-eslint/class-literal-property-style': 'error',
802
+ '@typescript-eslint/class-methods-use-this': 'error',
803
+ '@typescript-eslint/consistent-generic-constructors': 'error',
804
+ '@typescript-eslint/consistent-indexed-object-style': 'error',
805
+ '@typescript-eslint/consistent-type-assertions': 'error',
806
+ '@typescript-eslint/consistent-type-definitions': 'error',
807
+ '@typescript-eslint/consistent-type-imports': [
808
+ 'error',
809
+ { disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' }
810
+ ],
811
+ '@typescript-eslint/default-param-last': 'error',
812
+ '@typescript-eslint/explicit-function-return-type': ['error', { allowExpressions: true }],
813
+ '@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'no-public' }],
814
+ '@typescript-eslint/member-ordering': [
815
+ 'error',
816
+ {
817
+ default: [
818
+ 'public-static-field',
819
+ 'protected-static-field',
820
+ 'private-static-field',
821
+ '#private-static-field',
822
+
823
+ 'public-decorated-field',
824
+ 'protected-decorated-field',
825
+ 'private-decorated-field',
826
+
827
+ 'public-instance-field',
828
+ 'protected-instance-field',
829
+ 'private-instance-field',
830
+ '#private-instance-field',
831
+
832
+ 'public-abstract-field',
833
+
834
+ 'signature',
835
+
836
+ 'public-static-method',
837
+ 'protected-static-method',
838
+ 'private-static-method',
839
+ '#private-static-method',
840
+
841
+ 'public-constructor',
842
+ 'protected-constructor',
843
+ 'private-constructor',
844
+
845
+ 'public-decorated-method',
846
+ 'protected-decorated-method',
847
+ 'private-decorated-method',
848
+
849
+ 'public-instance-method',
850
+ 'protected-instance-method',
851
+ 'private-instance-method',
852
+ '#private-instance-method',
853
+
854
+ 'public-abstract-method',
855
+ 'protected-abstract-method'
856
+ ]
857
+ }
858
+ ],
859
+ '@typescript-eslint/method-signature-style': 'error',
860
+ '@typescript-eslint/naming-convention': [
861
+ 'error',
862
+ {
863
+ selector: [
864
+ 'accessor',
865
+ 'enumMember',
866
+ 'objectLiteralMethod',
867
+ 'objectLiteralProperty',
868
+ 'typeMethod',
869
+ 'typeProperty'
870
+ ],
871
+ format: null,
872
+ modifiers: ['requiresQuotes']
873
+ },
874
+ {
875
+ selector: 'default',
876
+ format: ['camelCase', 'PascalCase'],
877
+ leadingUnderscore: 'forbid',
878
+ trailingUnderscore: 'forbid',
879
+ filter: { regex: `^(${allowedProperties.join('|')})$`, match: false }
880
+ },
881
+
882
+ // PropertyLike
883
+ { selector: 'variable', format: ['camelCase'] },
884
+ {
885
+ selector: 'variable',
886
+ modifiers: ['const'],
887
+ format: ['camelCase', 'PascalCase', 'UPPER_CASE']
888
+ },
889
+ { selector: 'function', format: ['camelCase', 'PascalCase'] },
890
+ { selector: 'parameter', format: ['camelCase', 'PascalCase'] },
891
+
892
+ // ParameterLike
893
+ {
894
+ selector: 'property',
895
+ format: ['camelCase', 'PascalCase'],
896
+ filter: { regex: `^(${allowedProperties.join('|')})$`, match: false }
897
+ },
898
+ { selector: 'parameterProperty', format: ['PascalCase'] },
899
+ { selector: 'method', format: ['camelCase'] },
900
+ { selector: 'accessor', format: ['camelCase', 'PascalCase'] },
901
+ { selector: 'enumMember', format: ['camelCase', 'PascalCase'] },
902
+
903
+ // TypeLike
904
+ { selector: 'typeLike', format: ['PascalCase'] }
905
+ ],
906
+ '@typescript-eslint/no-array-constructor': 'error',
907
+ '@typescript-eslint/no-dupe-class-members': 'error',
908
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
909
+ '@typescript-eslint/no-empty-function': 'error',
910
+ '@typescript-eslint/no-empty-object-type': 'error',
911
+ '@typescript-eslint/no-explicit-any': 'error',
912
+ '@typescript-eslint/no-extra-non-null-assertion': 'error',
913
+ '@typescript-eslint/no-extraneous-class': 'error',
914
+ '@typescript-eslint/no-inferrable-types': 'error',
915
+ '@typescript-eslint/no-loop-func': 'error',
916
+ '@typescript-eslint/no-misused-new': 'error',
917
+ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
918
+ '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
919
+ '@typescript-eslint/no-require-imports': ['error', { allowAsImport: true }],
920
+ '@typescript-eslint/no-restricted-imports': ['error', ...restrictedImports],
921
+ '@typescript-eslint/no-shadow': [
922
+ 'error',
923
+ {
924
+ hoist: 'all',
925
+ ignoreFunctionTypeParameterNameValueShadow: false,
926
+ ignoreTypeValueShadow: false
927
+ }
928
+ ],
929
+ '@typescript-eslint/no-this-alias': 'error',
930
+ '@typescript-eslint/no-unnecessary-type-constraint': 'error',
931
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
932
+ '@typescript-eslint/no-unsafe-function-type': 'error',
933
+ '@typescript-eslint/no-unused-expressions': ['error', { enforceForJSX: true }],
934
+ '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true }],
935
+ '@typescript-eslint/no-use-before-define': 'error',
936
+ '@typescript-eslint/no-useless-constructor': 'error',
937
+ '@typescript-eslint/no-useless-empty-export': 'error',
938
+ '@typescript-eslint/no-wrapper-object-types': 'error',
939
+ '@typescript-eslint/parameter-properties': 'error',
940
+ '@typescript-eslint/prefer-as-const': 'error',
941
+ '@typescript-eslint/prefer-for-of': 'error',
942
+ '@typescript-eslint/prefer-function-type': 'error',
943
+ '@typescript-eslint/prefer-literal-enum-member': 'error',
944
+ '@typescript-eslint/prefer-namespace-keyword': 'error',
945
+ '@typescript-eslint/triple-slash-reference': 'error',
946
+ '@typescript-eslint/unified-signatures': 'error',
947
+
948
+ 'import-x/default': 'off',
949
+ 'import-x/named': 'off',
950
+ 'import-x/namespace': 'off',
951
+ 'import-x/no-deprecated': 'off',
952
+
953
+ 'jsdoc/no-types': 'error',
954
+ 'jsdoc/no-undefined-types': 'off',
955
+ 'jsdoc/require-param-type': 'off',
956
+ 'jsdoc/require-property-type': 'off',
957
+ 'jsdoc/require-returns-type': 'off',
958
+
959
+ 'unicorn/prefer-json-parse-buffer': 'off'
960
+ }
961
+ },
962
+
963
+ /**
964
+ * Enable parsing of JSX files.
965
+ */
966
+ {
967
+ files: ['**/*.jsx'],
968
+ languageOptions: {
969
+ parserOptions: {
970
+ ecmaFeatures: {
971
+ jsx: true
972
+ }
973
+ }
974
+ }
975
+ },
976
+
977
+ /**
978
+ * Overrides for configuration files, for example:
979
+ *
980
+ * - `jest.setup.ts`
981
+ * - `webpack.config.js`
982
+ * - `.eslintrc.js`
983
+ * - `config/custom.js`
984
+ * - `__mocks__/fs.ts`
985
+ * - etc.
986
+ */
987
+ {
988
+ files: [
989
+ '**/jest.*',
990
+ '**/test.*',
991
+ '**/*.test.*',
992
+ '**/*.config.*',
993
+ '**/*rc.{cjs,js,mjs}',
994
+ '**/config/**',
995
+ '**/test/**',
996
+ '**/__mocks__/**'
997
+ ],
998
+ rules: {
999
+ 'import-x/no-extraneous-dependencies': [
1000
+ 'error',
1001
+ {
1002
+ devDependencies: true,
1003
+ optionalDependencies: true,
1004
+ peerDependencies: true,
1005
+ bundledDependencies: true
1006
+ }
1007
+ ],
1008
+
1009
+ 'jsdoc/require-jsdoc': 'off',
1010
+
1011
+ 'n/no-unpublished-import': 'off',
1012
+ 'n/no-unpublished-require': 'off',
1013
+ 'unicorn/consistent-function-scoping': 'off'
1014
+ }
1015
+ },
1016
+
1017
+ /**
1018
+ * Allow some normally disallowed syntax in Markdown
1019
+ */
1020
+ {
1021
+ files: ['**/*.md'],
1022
+ plugins: {
1023
+ markdown
1024
+ },
1025
+ processor: 'markdown/markdown',
1026
+ language: 'markdown/gfm'
1027
+ },
1028
+
1029
+ {
1030
+ files: ['**/*.md/**'],
1031
+ rules: {
1032
+ 'no-console': 'off',
1033
+ 'no-unused-vars': 'off',
1034
+
1035
+ '@typescript-eslint/no-unused-vars': 'off',
1036
+
1037
+ 'import-x/extensions': 'off',
1038
+ 'import-x/no-extraneous-dependencies': 'off',
1039
+ 'import-x/no-unresolved': 'off',
1040
+
1041
+ 'jsdoc/require-jsdoc': 'off',
1042
+
1043
+ 'n/no-unpublished-import': 'off',
1044
+ 'n/no-unpublished-require': 'off',
1045
+
1046
+ 'prettier/prettier': 'off',
1047
+
1048
+ 'unicorn/consistent-function-scoping': 'off'
1049
+ }
1050
+ }
1051
+ ])
1052
+
1053
+ export default config
1054
+
1055
+ export const typechecking = defineConfig([
1056
+ {
1057
+ name: 'typechecking',
1058
+ files: ['**/*.cts', '**/*.mts', '**/*.ts', '**/*.tsx'],
1059
+ ignores: ['**/*.md/**'],
1060
+ languageOptions: {
1061
+ parserOptions: {
1062
+ projectService: true
1063
+ }
1064
+ },
1065
+ rules: {
1066
+ 'dot-notation': 'off',
1067
+ 'no-implied-eval': 'off',
1068
+ 'only-throw-error': 'off',
1069
+ 'prefer-destructuring': 'off',
1070
+ 'prefer-promise-reject-errors': 'off',
1071
+
1072
+ '@typescript-eslint/await-thenable': 'error',
1073
+ '@typescript-eslint/dot-notation': 'error',
1074
+ '@typescript-eslint/no-array-delete': 'error',
1075
+ '@typescript-eslint/no-base-to-string': 'error',
1076
+ '@typescript-eslint/no-deprecated': 'warn',
1077
+ '@typescript-eslint/no-duplicate-type-constituents': 'error',
1078
+ '@typescript-eslint/no-for-in-array': 'error',
1079
+ '@typescript-eslint/no-implied-eval': 'error',
1080
+ '@typescript-eslint/no-meaningless-void-operator': 'error',
1081
+ '@typescript-eslint/no-redundant-type-constituents': 'error',
1082
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
1083
+ '@typescript-eslint/no-unnecessary-condition': 'error',
1084
+ '@typescript-eslint/no-unnecessary-qualifier': 'error',
1085
+ '@typescript-eslint/no-unnecessary-template-expression': 'error',
1086
+ '@typescript-eslint/no-unnecessary-type-arguments': 'error',
1087
+ '@typescript-eslint/no-unnecessary-type-assertion': 'error',
1088
+ '@typescript-eslint/no-unsafe-argument': 'error',
1089
+ '@typescript-eslint/no-unsafe-assignment': 'error',
1090
+ '@typescript-eslint/no-unsafe-call': 'error',
1091
+ '@typescript-eslint/no-unsafe-enum-comparison': 'error',
1092
+ '@typescript-eslint/no-unsafe-member-access': 'error',
1093
+ '@typescript-eslint/no-unsafe-return': 'error',
1094
+ '@typescript-eslint/no-unsafe-unary-minus': 'error',
1095
+ '@typescript-eslint/non-nullable-type-assertion-style': 'error',
1096
+ '@typescript-eslint/only-throw-error': 'error',
1097
+ '@typescript-eslint/prefer-destructuring': [
1098
+ 'error',
1099
+ {
1100
+ VariableDeclarator: { array: false, object: true },
1101
+ AssignmentExpression: { array: false, object: false }
1102
+ }
1103
+ ],
1104
+ '@typescript-eslint/prefer-find': 'error',
1105
+ '@typescript-eslint/prefer-includes': 'error',
1106
+ '@typescript-eslint/prefer-nullish-coalescing': 'error',
1107
+ '@typescript-eslint/prefer-optional-chain': 'error',
1108
+ '@typescript-eslint/prefer-promise-reject-errors': 'error',
1109
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
1110
+ '@typescript-eslint/prefer-regexp-exec': 'error',
1111
+ '@typescript-eslint/prefer-return-this-type': 'error',
1112
+ '@typescript-eslint/prefer-string-starts-ends-with': 'error',
1113
+ '@typescript-eslint/related-getter-setter-pairs': 'error',
1114
+ '@typescript-eslint/require-array-sort-compare': ['error', { ignoreStringArrays: true }],
1115
+ '@typescript-eslint/restrict-plus-operands': 'error',
1116
+ '@typescript-eslint/restrict-template-expressions': [
1117
+ 'error',
1118
+ { allowNumber: true, allowBoolean: true, allowAny: false, allowNullish: true }
1119
+ ],
1120
+ '@typescript-eslint/return-await': 'error',
1121
+ '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }],
1122
+ '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
1123
+
1124
+ 'unicorn/prefer-array-find': 'off',
1125
+ 'unicorn/prefer-includes': 'off',
1126
+ 'unicorn/prefer-starts-ends-with': 'off'
1127
+ }
1128
+ }
1129
+ ])