@tb-dev/eslint-config 1.4.10 → 1.4.11

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/index.cjs ADDED
@@ -0,0 +1,892 @@
1
+ 'use strict';
2
+
3
+ const eslintConfigPrettier = require('eslint-config-prettier');
4
+ const globals = require('globals');
5
+ const process = require('node:process');
6
+
7
+ var Glob;
8
+ (function (Glob) {
9
+ Glob["ALL"] = "**/*.?([cm])[jt]s?(x)";
10
+ Glob["JAVASCRIPT"] = "**/*.?([cm])js?(x)";
11
+ Glob["TYPESCRIPT"] = "**/*.?([cm])ts?(x)";
12
+ Glob["VUE"] = "**/*.vue";
13
+ })(Glob || (Glob = {}));
14
+ var GlobIgnore;
15
+ (function (GlobIgnore) {
16
+ GlobIgnore["CACHE"] = "**/cache";
17
+ GlobIgnore["DIST"] = "**/dist";
18
+ GlobIgnore["LOG"] = "**/log?(s)";
19
+ GlobIgnore["NODE_MODULES"] = "**/node_modules";
20
+ GlobIgnore["OUT"] = "**/out";
21
+ GlobIgnore["TEMP"] = "**/?(.)temp";
22
+ })(GlobIgnore || (GlobIgnore = {}));
23
+
24
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
25
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
26
+ /* eslint-disable @typescript-eslint/no-explicit-any */
27
+ async function interopDefault(promise) {
28
+ const result = await promise;
29
+ return result.default ?? result;
30
+ }
31
+ function getIgnores() {
32
+ return Object.values(GlobIgnore);
33
+ }
34
+
35
+ /**
36
+ * @see https://eslint.org/docs/latest/rules/
37
+ */
38
+ function javascript(options) {
39
+ const { overrides } = options;
40
+ const files = [Glob.ALL];
41
+ if (options.vue)
42
+ files.push(Glob.VUE);
43
+ return {
44
+ files,
45
+ languageOptions: {
46
+ ecmaVersion: 'latest',
47
+ sourceType: 'module',
48
+ globals: {
49
+ ...globals.browser,
50
+ ...globals.es2021,
51
+ ...globals.node,
52
+ document: 'readonly',
53
+ window: 'readonly'
54
+ }
55
+ },
56
+ rules: {
57
+ 'accessor-pairs': ['error', { enforceForClassMembers: true, setWithoutGet: true }],
58
+ 'array-callback-return': [
59
+ 'error',
60
+ {
61
+ checkForEach: true,
62
+ allowVoid: true
63
+ }
64
+ ],
65
+ 'block-scoped-var': 'error',
66
+ 'consistent-this': ['error', 'self'],
67
+ 'default-case-last': 'error',
68
+ eqeqeq: ['error', 'always'],
69
+ 'for-direction': 'error',
70
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
71
+ 'grouped-accessor-pairs': ['error', 'getBeforeSet'],
72
+ 'guard-for-in': 'error',
73
+ 'init-declarations': 'off',
74
+ 'logical-assignment-operators': ['error', 'always', { enforceForIfStatements: true }],
75
+ 'max-params': 'off',
76
+ 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }],
77
+ 'no-alert': 'error',
78
+ 'no-async-promise-executor': 'error',
79
+ 'no-caller': 'error',
80
+ 'no-case-declarations': 'error',
81
+ 'no-class-assign': 'error',
82
+ 'no-compare-neg-zero': 'error',
83
+ 'no-cond-assign': ['error', 'always'],
84
+ 'no-constant-binary-expression': 'error',
85
+ 'no-constant-condition': 'error',
86
+ 'no-constructor-return': 'error',
87
+ 'no-control-regex': 'error',
88
+ 'no-debugger': 'error',
89
+ 'no-delete-var': 'error',
90
+ 'no-dupe-else-if': 'error',
91
+ 'no-duplicate-case': 'error',
92
+ 'no-duplicate-imports': ['error', { includeExports: false }],
93
+ 'no-else-return': 'error',
94
+ 'no-empty': ['error', { allowEmptyCatch: true }],
95
+ 'no-empty-character-class': 'error',
96
+ 'no-empty-pattern': 'error',
97
+ 'no-empty-static-block': 'error',
98
+ 'no-eval': 'error',
99
+ 'no-ex-assign': 'error',
100
+ 'no-extend-native': 'error',
101
+ 'no-extra-bind': 'error',
102
+ 'no-extra-boolean-cast': 'error',
103
+ 'no-fallthrough': ['error', { allowEmptyCase: true }],
104
+ 'no-global-assign': 'error',
105
+ 'no-implicit-coercion': ['error', { disallowTemplateShorthand: true }],
106
+ 'no-import-assign': 'error',
107
+ 'no-inner-declarations': ['error', 'both'],
108
+ 'no-invalid-regexp': 'error',
109
+ 'no-irregular-whitespace': 'error',
110
+ 'no-iterator': 'error',
111
+ 'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
112
+ 'no-lone-blocks': 'error',
113
+ 'no-lonely-if': 'error',
114
+ 'no-misleading-character-class': 'error',
115
+ 'no-multi-assign': 'error',
116
+ 'no-multi-str': 'error',
117
+ 'no-new': 'error',
118
+ 'no-new-func': 'error',
119
+ 'no-new-native-nonconstructor': 'error',
120
+ 'no-new-wrappers': 'error',
121
+ 'no-nonoctal-decimal-escape': 'error',
122
+ 'no-object-constructor': 'error',
123
+ 'no-octal': 'error',
124
+ 'no-octal-escape': 'error',
125
+ 'no-promise-executor-return': ['error', { allowVoid: true }],
126
+ 'no-proto': 'error',
127
+ 'no-prototype-builtins': 'error',
128
+ 'no-regex-spaces': 'error',
129
+ 'no-script-url': 'error',
130
+ 'no-self-assign': 'error',
131
+ 'no-self-compare': 'error',
132
+ 'no-sequences': 'error',
133
+ 'no-shadow-restricted-names': 'error',
134
+ 'no-sparse-arrays': 'error',
135
+ 'no-template-curly-in-string': 'off',
136
+ 'no-undef-init': 'error',
137
+ 'no-undefined': 'error',
138
+ 'no-unexpected-multiline': 'error',
139
+ 'no-unmodified-loop-condition': 'error',
140
+ 'no-unneeded-ternary': ['error', { defaultAssignment: false }],
141
+ 'no-unreachable-loop': 'error',
142
+ 'no-unsafe-finally': 'error',
143
+ 'no-unsafe-optional-chaining': ['error', { disallowArithmeticOperators: true }],
144
+ 'no-unused-vars': 'off',
145
+ 'no-useless-backreference': 'error',
146
+ 'no-useless-call': 'error',
147
+ 'no-useless-catch': 'error',
148
+ 'no-useless-computed-key': 'error',
149
+ 'no-useless-concat': 'error',
150
+ 'no-useless-rename': 'error',
151
+ 'no-useless-return': 'error',
152
+ 'no-var': 'error',
153
+ 'no-with': 'error',
154
+ 'object-shorthand': ['error', 'always'],
155
+ 'operator-assignment': ['error', 'always'],
156
+ 'prefer-arrow-callback': 'error',
157
+ 'prefer-const': [
158
+ 'error',
159
+ {
160
+ destructuring: 'all',
161
+ ignoreReadBeforeAssign: true
162
+ }
163
+ ],
164
+ 'prefer-destructuring': 'off',
165
+ 'prefer-exponentiation-operator': 'error',
166
+ 'prefer-object-has-own': 'error',
167
+ 'prefer-object-spread': 'error',
168
+ 'prefer-promise-reject-errors': 'error',
169
+ 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
170
+ 'prefer-rest-params': 'error',
171
+ 'prefer-spread': 'error',
172
+ 'prefer-template': 'error',
173
+ 'require-atomic-updates': 'error',
174
+ 'sort-imports': [
175
+ 'error',
176
+ {
177
+ allowSeparatedGroups: false,
178
+ ignoreCase: false,
179
+ ignoreDeclarationSort: true,
180
+ ignoreMemberSort: false,
181
+ memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single']
182
+ }
183
+ ],
184
+ 'symbol-description': 'error',
185
+ 'use-isnan': 'error',
186
+ 'valid-typeof': 'error',
187
+ yoda: ['error', 'never'],
188
+ ...overrides?.javascript
189
+ }
190
+ };
191
+ }
192
+
193
+ /**
194
+ * @see https://eslint-plugin-perfectionist.azat.io/rules/
195
+ */
196
+ async function perfectionist(options) {
197
+ const { overrides, perfectionist: enabled = true } = options;
198
+ if (!enabled)
199
+ return {};
200
+ const plugin = await interopDefault(import('eslint-plugin-perfectionist'));
201
+ return {
202
+ plugins: {
203
+ perfectionist: plugin
204
+ },
205
+ rules: {
206
+ 'perfectionist/sort-classes': [
207
+ 'error',
208
+ {
209
+ type: 'natural',
210
+ order: 'asc',
211
+ groups: [
212
+ 'index-signature',
213
+ 'property',
214
+ 'private-property',
215
+ 'constructor',
216
+ 'method',
217
+ 'private-method',
218
+ ['get-method', 'set-method'],
219
+ 'static-property',
220
+ 'static-method',
221
+ 'static-private-method',
222
+ 'unknown'
223
+ ]
224
+ }
225
+ ],
226
+ 'perfectionist/sort-enums': [
227
+ 'error',
228
+ {
229
+ type: 'natural',
230
+ order: 'asc'
231
+ }
232
+ ],
233
+ 'perfectionist/sort-exports': [
234
+ 'error',
235
+ {
236
+ type: 'line-length',
237
+ order: 'asc'
238
+ }
239
+ ],
240
+ 'perfectionist/sort-imports': [
241
+ 'error',
242
+ {
243
+ type: 'line-length',
244
+ order: 'asc',
245
+ 'newlines-between': 'never',
246
+ groups: [
247
+ ['style', 'side-effect'],
248
+ ['builtin', 'builtin-type'],
249
+ ['external', 'external-type'],
250
+ ['internal', 'internal-type'],
251
+ 'unknown'
252
+ ]
253
+ }
254
+ ],
255
+ 'perfectionist/sort-interfaces': [
256
+ 'error',
257
+ {
258
+ type: 'natural',
259
+ order: 'asc',
260
+ 'partition-by-new-line': true
261
+ }
262
+ ],
263
+ 'perfectionist/sort-maps': [
264
+ 'error',
265
+ {
266
+ type: 'natural',
267
+ order: 'asc'
268
+ }
269
+ ],
270
+ 'perfectionist/sort-named-exports': [
271
+ 'error',
272
+ {
273
+ type: 'natural',
274
+ order: 'asc'
275
+ }
276
+ ],
277
+ 'sort-imports': 'off',
278
+ 'perfectionist/sort-named-imports': [
279
+ 'error',
280
+ {
281
+ type: 'natural',
282
+ order: 'asc'
283
+ }
284
+ ],
285
+ '@typescript-eslint/adjacent-overload-signatures': 'off',
286
+ 'perfectionist/sort-object-types': [
287
+ 'error',
288
+ {
289
+ type: 'natural',
290
+ order: 'asc',
291
+ 'partition-by-new-line': true
292
+ }
293
+ ],
294
+ ...overrides?.perfectionist
295
+ }
296
+ };
297
+ }
298
+
299
+ /**
300
+ * @see https://typescript-eslint.io/rules/
301
+ */
302
+ async function typescript(options) {
303
+ const { project, overrides } = options;
304
+ const [tsParser, tsPlugin] = await Promise.all([
305
+ await interopDefault(import('@typescript-eslint/parser')),
306
+ await interopDefault(import('@typescript-eslint/eslint-plugin'))
307
+ ]);
308
+ const files = [Glob.TYPESCRIPT];
309
+ if (options.vue)
310
+ files.push(Glob.VUE);
311
+ const rules = {
312
+ '@typescript-eslint/adjacent-overload-signatures': 'error',
313
+ 'no-array-constructor': 'off',
314
+ '@typescript-eslint/no-array-constructor': 'error',
315
+ '@typescript-eslint/array-type': ['error', { default: 'array' }],
316
+ '@typescript-eslint/ban-ts-comment': [
317
+ 'error',
318
+ {
319
+ 'ts-expect-error': 'allow-with-description',
320
+ 'ts-ignore': true,
321
+ 'ts-nocheck': true,
322
+ 'ts-check': false,
323
+ minimumDescriptionLength: 3
324
+ }
325
+ ],
326
+ '@typescript-eslint/class-literal-property-style': ['error', 'fields'],
327
+ 'class-methods-use-this': 'off',
328
+ '@typescript-eslint/class-methods-use-this': [
329
+ 'error',
330
+ {
331
+ ignoreOverrideMethods: true,
332
+ ignoreClassesThatImplementAnInterface: 'public-fields'
333
+ }
334
+ ],
335
+ '@typescript-eslint/consistent-generic-constructors': ['error', 'constructor'],
336
+ '@typescript-eslint/consistent-indexed-object-style': ['error', 'record'],
337
+ '@typescript-eslint/consistent-type-assertions': [
338
+ 'error',
339
+ { assertionStyle: 'as', objectLiteralTypeAssertions: 'allow-as-parameter' }
340
+ ],
341
+ '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
342
+ 'dot-notation': 'off',
343
+ '@typescript-eslint/dot-notation': ['error', { allowKeywords: true }],
344
+ '@typescript-eslint/explicit-function-return-type': 'off',
345
+ '@typescript-eslint/explicit-member-accessibility': [
346
+ 'error',
347
+ {
348
+ accessibility: 'explicit',
349
+ overrides: {
350
+ accessors: 'no-public',
351
+ constructors: 'no-public',
352
+ methods: 'explicit',
353
+ properties: 'explicit',
354
+ parameterProperties: 'explicit'
355
+ }
356
+ }
357
+ ],
358
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
359
+ '@typescript-eslint/method-signature-style': ['error', 'property'],
360
+ '@typescript-eslint/no-base-to-string': 'error',
361
+ '@typescript-eslint/no-confusing-non-null-assertion': 'error',
362
+ '@typescript-eslint/no-confusing-void-expression': [
363
+ 'error',
364
+ {
365
+ ignoreArrowShorthand: true,
366
+ ignoreVoidOperator: true
367
+ }
368
+ ],
369
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
370
+ '@typescript-eslint/no-duplicate-type-constituents': 'error',
371
+ '@typescript-eslint/no-dynamic-delete': 'error',
372
+ 'no-empty-function': 'off',
373
+ '@typescript-eslint/no-empty-function': 'error',
374
+ '@typescript-eslint/no-empty-interface': 'error',
375
+ '@typescript-eslint/no-explicit-any': ['error', { fixToUnknown: true }],
376
+ '@typescript-eslint/no-extra-non-null-assertion': 'error',
377
+ '@typescript-eslint/no-extraneous-class': 'error',
378
+ '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
379
+ '@typescript-eslint/no-for-in-array': 'error',
380
+ 'no-implied-eval': 'off',
381
+ '@typescript-eslint/no-implied-eval': 'error',
382
+ '@typescript-eslint/no-import-type-side-effects': 'error',
383
+ '@typescript-eslint/no-inferrable-types': 'error',
384
+ '@typescript-eslint/no-invalid-void-type': [
385
+ 'error',
386
+ {
387
+ allowInGenericTypeArguments: true,
388
+ allowAsThisParameter: true
389
+ }
390
+ ],
391
+ 'no-loop-func': 'off',
392
+ '@typescript-eslint/no-loop-func': 'error',
393
+ 'no-loss-of-precision': 'off',
394
+ '@typescript-eslint/no-loss-of-precision': 'error',
395
+ '@typescript-eslint/no-meaningless-void-operator': 'error',
396
+ '@typescript-eslint/no-misused-new': 'error',
397
+ '@typescript-eslint/no-misused-promises': [
398
+ 'error',
399
+ {
400
+ checksConditionals: true,
401
+ checksSpreads: true,
402
+ checksVoidReturn: {
403
+ arguments: true,
404
+ attributes: true,
405
+ properties: true,
406
+ returns: true,
407
+ variables: true
408
+ }
409
+ }
410
+ ],
411
+ '@typescript-eslint/no-mixed-enums': 'error',
412
+ '@typescript-eslint/no-namespace': 'error',
413
+ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
414
+ '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
415
+ '@typescript-eslint/no-non-null-assertion': 'error',
416
+ '@typescript-eslint/no-redundant-type-constituents': 'error',
417
+ '@typescript-eslint/no-require-imports': 'error',
418
+ 'no-shadow': 'off',
419
+ '@typescript-eslint/no-shadow': 'error',
420
+ '@typescript-eslint/no-this-alias': 'error',
421
+ 'no-throw-literal': 'off',
422
+ '@typescript-eslint/no-throw-literal': 'error',
423
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': [
424
+ 'error',
425
+ {
426
+ allowComparingNullableBooleansToTrue: false,
427
+ allowComparingNullableBooleansToFalse: true
428
+ }
429
+ ],
430
+ '@typescript-eslint/no-unnecessary-condition': 'error',
431
+ '@typescript-eslint/no-unnecessary-qualifier': 'error',
432
+ '@typescript-eslint/no-unnecessary-type-arguments': 'error',
433
+ '@typescript-eslint/no-unnecessary-type-assertion': 'error',
434
+ '@typescript-eslint/no-unnecessary-type-constraint': 'error',
435
+ '@typescript-eslint/no-unsafe-argument': 'off',
436
+ '@typescript-eslint/no-unsafe-assignment': 'error',
437
+ '@typescript-eslint/no-unsafe-call': 'error',
438
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
439
+ '@typescript-eslint/no-unsafe-enum-comparison': 'off',
440
+ '@typescript-eslint/no-unsafe-member-access': 'error',
441
+ '@typescript-eslint/no-unsafe-return': 'error',
442
+ '@typescript-eslint/no-unsafe-unary-minus': 'error',
443
+ 'no-unused-expressions': 'off',
444
+ '@typescript-eslint/no-unused-expressions': [
445
+ 'error',
446
+ {
447
+ allowTaggedTemplates: true
448
+ }
449
+ ],
450
+ 'no-use-before-define': 'off',
451
+ '@typescript-eslint/no-use-before-define': [
452
+ 'error',
453
+ {
454
+ functions: false,
455
+ enums: true,
456
+ typedefs: false
457
+ }
458
+ ],
459
+ 'no-useless-constructor': 'off',
460
+ '@typescript-eslint/no-useless-constructor': 'error',
461
+ '@typescript-eslint/no-useless-empty-export': 'error',
462
+ '@typescript-eslint/non-nullable-type-assertion-style': 'error',
463
+ '@typescript-eslint/prefer-as-const': 'error',
464
+ '@typescript-eslint/prefer-enum-initializers': 'error',
465
+ '@typescript-eslint/prefer-for-of': 'error',
466
+ '@typescript-eslint/prefer-function-type': 'error',
467
+ '@typescript-eslint/prefer-includes': 'error',
468
+ '@typescript-eslint/prefer-literal-enum-member': 'error',
469
+ '@typescript-eslint/prefer-nullish-coalescing': [
470
+ 'error',
471
+ {
472
+ ignoreTernaryTests: false,
473
+ ignoreConditionalTests: false,
474
+ ignoreMixedLogicalExpressions: false,
475
+ ignorePrimitives: {
476
+ bigint: false,
477
+ boolean: false,
478
+ number: false,
479
+ string: false
480
+ }
481
+ }
482
+ ],
483
+ '@typescript-eslint/prefer-optional-chain': 'error',
484
+ '@typescript-eslint/prefer-readonly': 'error',
485
+ '@typescript-eslint/prefer-readonly-parameter-types': 'off',
486
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
487
+ '@typescript-eslint/prefer-regexp-exec': 'error',
488
+ '@typescript-eslint/prefer-return-this-type': 'error',
489
+ '@typescript-eslint/prefer-string-starts-ends-with': 'error',
490
+ '@typescript-eslint/prefer-ts-expect-error': 'error',
491
+ '@typescript-eslint/promise-function-async': 'off',
492
+ '@typescript-eslint/require-array-sort-compare': 'error',
493
+ 'require-await': 'off',
494
+ '@typescript-eslint/require-await': 'error',
495
+ '@typescript-eslint/restrict-plus-operands': 'error',
496
+ '@typescript-eslint/restrict-template-expressions': 'error',
497
+ '@typescript-eslint/strict-boolean-expressions': 'off',
498
+ '@typescript-eslint/switch-exhaustiveness-check': [
499
+ 'error',
500
+ {
501
+ requireDefaultForNonUnion: true
502
+ }
503
+ ],
504
+ '@typescript-eslint/unbound-method': 'error',
505
+ '@typescript-eslint/unified-signatures': [
506
+ 'error',
507
+ {
508
+ ignoreDifferentlyNamedParameters: true
509
+ }
510
+ ],
511
+ ...overrides?.typescript
512
+ };
513
+ return {
514
+ files,
515
+ languageOptions: {
516
+ ecmaVersion: 'latest',
517
+ sourceType: 'module',
518
+ parser: tsParser,
519
+ parserOptions: {
520
+ project,
521
+ tsconfigRootDir: process.cwd(),
522
+ extraFileExtensions: options.vue ? ['.vue'] : []
523
+ }
524
+ },
525
+ plugins: {
526
+ '@typescript-eslint': tsPlugin
527
+ },
528
+ rules
529
+ };
530
+ }
531
+
532
+ /**
533
+ * @see https://github.com/sindresorhus/eslint-plugin-unicorn#rules
534
+ */
535
+ async function unicorn(options) {
536
+ const { overrides, unicorn: enabled = true } = options;
537
+ if (!enabled)
538
+ return {};
539
+ const plugin = await interopDefault(import('eslint-plugin-unicorn'));
540
+ return {
541
+ plugins: {
542
+ unicorn: plugin
543
+ },
544
+ rules: {
545
+ 'unicorn/catch-error-name': [
546
+ 'error',
547
+ {
548
+ name: 'err'
549
+ }
550
+ ],
551
+ 'unicorn/consistent-function-scoping': [
552
+ 'error',
553
+ {
554
+ checkArrowFunctions: true
555
+ }
556
+ ],
557
+ 'unicorn/custom-error-definition': 'error',
558
+ 'unicorn/error-message': 'error',
559
+ 'unicorn/no-array-for-each': 'error',
560
+ 'unicorn/no-array-method-this-argument': 'error',
561
+ 'unicorn/no-array-push-push': 'error',
562
+ 'unicorn/no-await-expression-member': 'error',
563
+ 'unicorn/no-invalid-remove-event-listener': 'error',
564
+ 'unicorn/no-thenable': 'error',
565
+ 'unicorn/no-typeof-undefined': 'error',
566
+ 'unicorn/no-useless-fallback-in-spread': 'error',
567
+ 'unicorn/no-useless-length-check': 'error',
568
+ 'unicorn/no-useless-promise-resolve-reject': 'error',
569
+ 'unicorn/prefer-at': 'error',
570
+ 'unicorn/prefer-date-now': 'error',
571
+ 'unicorn/prefer-dom-node-append': 'error',
572
+ 'unicorn/prefer-dom-node-dataset': 'error',
573
+ 'unicorn/prefer-dom-node-remove': 'error',
574
+ 'unicorn/prefer-dom-node-text-content': 'error',
575
+ 'unicorn/prefer-modern-dom-apis': 'error',
576
+ 'unicorn/prefer-node-protocol': 'error',
577
+ 'unicorn/prefer-number-properties': 'error',
578
+ 'unicorn/prefer-object-from-entries': 'error',
579
+ 'unicorn/prefer-prototype-methods': 'error',
580
+ 'unicorn/prefer-query-selector': 'error',
581
+ 'unicorn/prefer-reflect-apply': 'error',
582
+ 'unicorn/prefer-regexp-test': 'error',
583
+ 'unicorn/prefer-string-slice': 'error',
584
+ 'unicorn/prefer-type-error': 'error',
585
+ 'unicorn/relative-url-style': ['error', 'never'],
586
+ ...overrides?.unicorn
587
+ }
588
+ };
589
+ }
590
+
591
+ /* eslint-disable @typescript-eslint/no-explicit-any */
592
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
593
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
594
+ /**
595
+ * @see https://eslint.vuejs.org/rules/
596
+ */
597
+ async function vue(options) {
598
+ const { overrides, vue: enabled } = options;
599
+ if (!enabled)
600
+ return [];
601
+ const [vuePlugin, vueParser, tsParser] = await Promise.all([
602
+ // @ts-expect-error no types
603
+ await interopDefault(import('eslint-plugin-vue')),
604
+ await interopDefault(import('vue-eslint-parser')),
605
+ await interopDefault(import('@typescript-eslint/parser'))
606
+ ]);
607
+ const rules = {
608
+ ...vuePlugin.configs.base.rules,
609
+ 'vue/attribute-hyphenation': ['error', 'always'],
610
+ 'vue/attributes-order': 'error',
611
+ 'vue/block-lang': [
612
+ 'error',
613
+ {
614
+ script: {
615
+ lang: 'ts'
616
+ },
617
+ style: {
618
+ lang: 'scss',
619
+ allowNoLang: true
620
+ }
621
+ }
622
+ ],
623
+ 'vue/block-order': [
624
+ 'error',
625
+ {
626
+ order: [['script', 'template'], 'style:not([scoped])', 'style[scoped]']
627
+ }
628
+ ],
629
+ 'vue/block-tag-newline': [
630
+ 'error',
631
+ {
632
+ singleline: 'always',
633
+ multiline: 'always',
634
+ maxEmptyLines: 0
635
+ }
636
+ ],
637
+ 'vue/component-api-style': ['error', ['script-setup']],
638
+ 'vue/component-definition-name-casing': ['error', 'PascalCase'],
639
+ 'vue/component-name-in-template-casing': ['error', 'PascalCase'],
640
+ 'vue/custom-event-name-casing': ['error', 'camelCase'],
641
+ 'vue/define-emits-declaration': ['error', 'type-based'],
642
+ 'vue/define-macros-order': [
643
+ 'error',
644
+ {
645
+ order: ['defineProps', 'defineEmits']
646
+ }
647
+ ],
648
+ 'vue/define-props-declaration': ['error', 'type-based'],
649
+ 'vue/first-attribute-linebreak': 'off',
650
+ 'vue/html-button-has-type': [
651
+ 'error',
652
+ {
653
+ button: true,
654
+ submit: true,
655
+ reset: true
656
+ }
657
+ ],
658
+ 'vue/html-closing-bracket-newline': [
659
+ 'error',
660
+ {
661
+ singleline: 'never',
662
+ multiline: 'always'
663
+ }
664
+ ],
665
+ 'vue/html-closing-bracket-spacing': [
666
+ 'error',
667
+ {
668
+ startTag: 'never',
669
+ endTag: 'never',
670
+ selfClosingTag: 'always'
671
+ }
672
+ ],
673
+ 'vue/html-self-closing': [
674
+ 'error',
675
+ {
676
+ html: {
677
+ void: 'never',
678
+ normal: 'always',
679
+ component: 'always'
680
+ },
681
+ svg: 'always',
682
+ math: 'always'
683
+ }
684
+ ],
685
+ 'vue/match-component-file-name': [
686
+ 'error',
687
+ {
688
+ extensions: ['tsx', 'vue'],
689
+ shouldMatchCase: false
690
+ }
691
+ ],
692
+ 'vue/match-component-import-name': 'error',
693
+ 'vue/multi-word-component-names': 'off',
694
+ 'vue/mustache-interpolation-spacing': ['error', 'always'],
695
+ 'vue/no-arrow-functions-in-watch': 'off',
696
+ 'vue/no-async-in-computed-properties': 'error',
697
+ 'vue/no-boolean-default': ['error', 'no-default'],
698
+ 'vue/no-computed-properties-in-data': 'error',
699
+ 'vue/no-dupe-keys': 'error',
700
+ 'vue/no-dupe-v-else-if': 'error',
701
+ 'vue/no-duplicate-attributes': [
702
+ 'error',
703
+ {
704
+ allowCoexistClass: true,
705
+ allowCoexistStyle: true
706
+ }
707
+ ],
708
+ 'vue/no-export-in-script-setup': 'error',
709
+ 'vue/no-expose-after-await': 'error',
710
+ 'vue/no-lifecycle-after-await': 'error',
711
+ 'vue/no-lone-template': 'error',
712
+ 'vue/no-multi-spaces': 'error',
713
+ 'vue/no-multiple-objects-in-class': 'error',
714
+ 'vue/no-mutating-props': 'error',
715
+ 'vue/no-parsing-error': 'error',
716
+ 'vue/no-ref-as-operand': 'error',
717
+ 'vue/no-ref-object-reactivity-loss': 'error',
718
+ 'vue/no-reserved-component-names': 'error',
719
+ 'vue/no-reserved-keys': 'error',
720
+ 'vue/no-reserved-props': 'error',
721
+ 'vue/no-required-prop-with-default': [
722
+ 'error',
723
+ {
724
+ autofix: true
725
+ }
726
+ ],
727
+ 'vue/no-root-v-if': 'error',
728
+ 'vue/no-setup-props-reactivity-loss': 'error',
729
+ 'vue/no-shared-component-data': 'error',
730
+ 'vue/no-side-effects-in-computed-properties': 'error',
731
+ 'vue/no-spaces-around-equal-signs-in-attribute': 'error',
732
+ 'vue/no-static-inline-styles': [
733
+ 'error',
734
+ {
735
+ allowBinding: false
736
+ }
737
+ ],
738
+ 'vue/no-template-key': 'error',
739
+ 'vue/no-template-shadow': 'error',
740
+ 'vue/no-template-target-blank': 'error',
741
+ 'vue/no-textarea-mustache': 'error',
742
+ 'vue/no-unused-components': 'error',
743
+ 'vue/no-unused-emit-declarations': 'error',
744
+ 'vue/no-unused-properties': 'error',
745
+ 'vue/no-unused-refs': 'error',
746
+ 'vue/no-unused-vars': [
747
+ 'error',
748
+ {
749
+ ignorePattern: '^_'
750
+ }
751
+ ],
752
+ 'vue/no-use-computed-property-like-method': 'error',
753
+ 'vue/no-use-v-else-with-v-for': 'error',
754
+ 'vue/no-use-v-if-with-v-for': 'error',
755
+ 'vue/no-useless-mustaches': [
756
+ 'error',
757
+ {
758
+ ignoreIncludesComment: false,
759
+ ignoreStringEscape: false
760
+ }
761
+ ],
762
+ 'vue/no-useless-template-attributes': 'error',
763
+ 'vue/no-useless-v-bind': 'error',
764
+ 'vue/no-v-for-template-key-on-child': 'error',
765
+ 'vue/no-v-text-v-html-on-component': 'error',
766
+ 'vue/no-v-html': 'off',
767
+ 'vue/no-watch-after-await': 'error',
768
+ 'vue/order-in-components': 'error',
769
+ 'vue/padding-line-between-blocks': ['error', 'always'],
770
+ 'vue/prefer-define-options': 'error',
771
+ 'vue/prefer-import-from-vue': 'error',
772
+ 'vue/prefer-separate-static-class': 'error',
773
+ 'vue/prefer-true-attribute-shorthand': 'error',
774
+ 'vue/prop-name-casing': ['error', 'camelCase'],
775
+ 'vue/require-component-is': 'error',
776
+ 'vue/require-default-prop': 'off',
777
+ 'vue/require-explicit-emits': [
778
+ 'error',
779
+ {
780
+ allowProps: false
781
+ }
782
+ ],
783
+ 'vue/require-macro-variable-name': [
784
+ 'error',
785
+ {
786
+ defineProps: 'props',
787
+ defineEmits: 'emit',
788
+ defineSlots: 'slots',
789
+ useSlots: 'slots',
790
+ useAttrs: 'attrs'
791
+ }
792
+ ],
793
+ 'vue/require-prop-types': 'error',
794
+ 'vue/require-render-return': 'error',
795
+ 'vue/require-slots-as-functions': 'error',
796
+ 'vue/require-toggle-inside-transition': 'error',
797
+ 'vue/require-typed-ref': 'error',
798
+ 'vue/require-v-for-key': 'error',
799
+ 'vue/require-valid-default-prop': 'error',
800
+ 'vue/return-in-computed-property': 'error',
801
+ 'vue/return-in-emits-validator': 'error',
802
+ 'vue/this-in-template': ['error', 'never'],
803
+ 'vue/use-v-on-exact': 'error',
804
+ 'vue/v-bind-style': ['error', 'shorthand'],
805
+ 'vue/v-for-delimiter-style': ['error', 'of'],
806
+ 'vue/v-on-handler-style': [
807
+ 'error',
808
+ ['method', 'inline-function'],
809
+ {
810
+ ignoreIncludesComment: false
811
+ }
812
+ ],
813
+ 'vue/v-on-style': ['error', 'shorthand'],
814
+ 'vue/v-slot-style': [
815
+ 'error',
816
+ {
817
+ atComponent: 'shorthand',
818
+ default: 'shorthand',
819
+ named: 'shorthand'
820
+ }
821
+ ],
822
+ 'vue/v-on-event-hyphenation': ['error', 'always'],
823
+ 'vue/valid-attribute-name': 'error',
824
+ 'vue/valid-define-emits': 'error',
825
+ 'vue/valid-define-options': 'error',
826
+ 'vue/valid-define-props': 'error',
827
+ 'vue/valid-next-tick': 'error',
828
+ 'vue/valid-template-root': 'error',
829
+ 'vue/valid-v-bind': 'error',
830
+ 'vue/valid-v-cloak': 'error',
831
+ 'vue/valid-v-else-if': 'error',
832
+ 'vue/valid-v-else': 'error',
833
+ 'vue/valid-v-for': 'error',
834
+ 'vue/valid-v-html': 'error',
835
+ 'vue/valid-v-if': 'error',
836
+ 'vue/valid-v-memo': 'error',
837
+ 'vue/valid-v-model': 'error',
838
+ 'vue/valid-v-on': 'error',
839
+ 'vue/valid-v-once': 'error',
840
+ 'vue/valid-v-pre': 'error',
841
+ 'vue/valid-v-show': 'error',
842
+ 'vue/valid-v-slot': 'error',
843
+ 'vue/valid-v-text': 'error',
844
+ ...overrides?.vue
845
+ };
846
+ return [
847
+ {
848
+ plugins: {
849
+ vue: vuePlugin
850
+ }
851
+ },
852
+ {
853
+ files: [Glob.VUE],
854
+ languageOptions: {
855
+ parser: vueParser,
856
+ parserOptions: {
857
+ parser: tsParser,
858
+ project: options.project,
859
+ tsconfigRootDir: process.cwd(),
860
+ extraFileExtensions: ['.vue'],
861
+ sourceType: 'module',
862
+ ecmaVersion: 'latest'
863
+ }
864
+ }
865
+ },
866
+ {
867
+ // @ts-expect-error no types
868
+ processor: vuePlugin.processors['.vue'],
869
+ rules
870
+ }
871
+ ];
872
+ }
873
+
874
+ /* eslint-disable @typescript-eslint/no-explicit-any */
875
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
876
+ async function config(options) {
877
+ const { prettier = true } = options;
878
+ const objs = await Promise.all([
879
+ javascript(options),
880
+ typescript(options),
881
+ ...(await vue(options)),
882
+ perfectionist(options),
883
+ unicorn(options),
884
+ prettier ? eslintConfigPrettier : {},
885
+ {
886
+ ignores: [...getIgnores(), ...(options.ignores ?? [])]
887
+ }
888
+ ]);
889
+ return objs;
890
+ }
891
+
892
+ module.exports = config;