@unshared/eslint-config 0.0.20 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -1,196 +1,103 @@
1
1
  import pluginAntfu from "eslint-plugin-antfu";
2
2
  import eslintCommentsPlugin from "eslint-plugin-eslint-comments";
3
3
  import pluginJsdoc from "eslint-plugin-jsdoc";
4
- import jsonc from "eslint-plugin-jsonc";
4
+ import pluginJsonc from "eslint-plugin-jsonc";
5
5
  import nodePlugin from "eslint-plugin-n";
6
6
  import pluginSonarjs from "eslint-plugin-sonarjs";
7
7
  import javascript from "@eslint/js";
8
8
  import stylistic from "@stylistic/eslint-plugin";
9
9
  import { toArray } from "@unshared/collection/toArray";
10
10
  import perfectionist from "eslint-plugin-perfectionist";
11
- import { cwd } from "node:process";
12
11
  import tslint from "typescript-eslint";
13
12
  import unicornPlugin from "eslint-plugin-unicorn";
14
- import vitestPlugin from "eslint-plugin-vitest";
13
+ import vitestPlugin from "@vitest/eslint-plugin";
15
14
  import { mergeProcessors } from "eslint-merge-processors";
16
15
  import vuePlugin from "eslint-plugin-vue";
17
16
  import vueProcessorBlocks from "eslint-processor-vue-blocks";
18
17
  import vueParser from "vue-eslint-parser";
19
- function antfu(options) {
18
+ import pluginYml from "eslint-plugin-yml";
19
+ function antfu() {
20
20
  return [
21
21
  {
22
22
  plugins: {
23
23
  antfu: pluginAntfu
24
24
  },
25
25
  rules: {
26
+ // --- Enforce consistent line breaks for chaining member access.
27
+ "antfu/consistent-chaining": "error",
28
+ // --- Enforce consistent line breaks inside braces of object/array/named imports/exports and function parameters.
26
29
  "antfu/consistent-list-newline": "error",
27
- /**
28
- * Auto-fix import duplication. The TypeScript compiler already detects and removes
29
- * duplicate imports, but this rule can be used to fix the issue automatically in the editor.
30
- *
31
- * @see https://github.com/antfu/eslint-plugin-antfu/blob/main/src/rules/import-dedupe.md
32
- */
30
+ // --- Deduplicate imports.
33
31
  "antfu/import-dedupe": "error",
34
- /**
35
- * Enforce top-level function to be declared using function instead of arrow function. This
36
- * rule helps when you want to add additional overload signatures to a function without
37
- * having to transform the arrow function into a function declaration manually.
38
- *
39
- * On top of that, it mitigates the risk of accidentally using the `this` instance from
40
- * an outer scope.
41
- *
42
- * @see https://github.com/antfu/eslint-plugin-antfu/blob/main/src/rules/top-level-function.md
43
- */
44
- "antfu/top-level-function": "error",
45
- /**
46
- * Enforce consistent line breaks inside braces of object/array/named imports/exports and
47
- * function parameters. Reduces the cognitive load of reasoning about code style.
48
- *
49
- * @see https://github.com/antfu/eslint-plugin-antfu/blob/main/src/rules/consistent-list-newline.md
50
- */
51
- "object-curly-newline": "off",
52
- /** User-defined rules */
53
- ...options.rules
32
+ // --- Avoid importing from 'dist' directories.
33
+ "antfu/no-import-dist": "error",
34
+ // --- Enforce `export default` insteand of `export = {}`.
35
+ "antfu/no-ts-export-equal": "error",
36
+ // --- Enforce `function()` instead of `() => {}` for top-level functions.
37
+ "antfu/top-level-function": "error"
54
38
  }
55
39
  }
56
40
  ];
57
41
  }
58
- function eslintComments(options) {
42
+ function eslintComments() {
59
43
  return [
60
44
  {
61
45
  plugins: {
62
46
  "eslint-comments": eslintCommentsPlugin
63
47
  },
64
48
  rules: {
65
- /**
66
- * Allow multiple rules directive in a single comment. This
67
- * reduces the number of comments in the code.
68
- *
69
- * @see https://mysticatea.github.io/eslint-plugin-eslint-comments/rules/disable-enable-pair
70
- */
49
+ // --- Allow disable without having to enable again.
71
50
  "eslint-comments/disable-enable-pair": "off",
72
- /**
73
- * `eslint-enable` directive-comments can enable rules which are disabled by different
74
- * eslint-disable directive-comments. It can enable a rule unintentionally. This rule
75
- * will report such cases.
76
- *
77
- * @see https://mysticatea.github.io/eslint-plugin-eslint-comments/rules/no-aggregating-enable
78
- */
51
+ // --- Disallow eslint-disable comments without rule names. This ensures that we cannot
79
52
  "eslint-comments/no-aggregating-enable": "error",
80
- /**
81
- * Disallow duplicate eslint-disable comments. This rule will report when there are
82
- * multiple eslint-disable comments for the same rule, either in the same line or enabled
83
- * by different eslint-disable comments.
84
- *
85
- * @see https://mysticatea.github.io/eslint-plugin-eslint-comments/rules/no-duplicate-disable
86
- */
87
- "eslint-comments/no-duplicate-disable": "error",
88
- /**
89
- * Disallow eslint-disable comments without rule names. This ensures that we cannot
90
- * disable all rules in a file using eslint-disable comment.
91
- *
92
- * @see https://mysticatea.github.io/eslint-plugin-eslint-comments/rules/no-unlimited-disable
93
- */
53
+ // --- Disable must specify rule names.
94
54
  "eslint-comments/no-unlimited-disable": "error",
95
- /**
96
- * Errors when an eslint-disable comment has no effect. This is useful
97
- * to prevent unnecessary comments in the code.
98
- *
99
- * @see https://mysticatea.github.io/eslint-plugin-eslint-comments/rules/no-unused-disable
100
- */
55
+ // --- Prevent superfluous eslint comments.
56
+ "eslint-comments/no-duplicate-disable": "error",
101
57
  "eslint-comments/no-unused-disable": "error",
102
- /** User-defined rules */
103
- ...options.rules
58
+ "eslint-comments/no-unused-enable": "error"
104
59
  }
105
60
  }
106
61
  ];
107
62
  }
108
- function jsdoc(options) {
63
+ function jsdoc() {
109
64
  return [
110
- pluginJsdoc.configs["flat/recommended-typescript-flavor-error"],
65
+ pluginJsdoc.configs["flat/recommended-typescript-error"],
111
66
  {
112
67
  files: [
113
68
  "**/*.{ts,mts,cts,tsx,d.ts}",
114
69
  "**/*.{js,mjs,cjs,jsx}",
115
70
  "**/*.vue"
116
71
  ],
72
+ plugins: {
73
+ jsdoc: pluginJsdoc
74
+ },
117
75
  rules: {
118
- /**
119
- * Enforce a consistent padding of the block description.
120
- *
121
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/HEAD/docs/rules/check-alignment.md#readme
122
- */
123
- "jsdoc/check-alignment": "error",
124
- /**
125
- * Normalize the indentation in the JSdoc comment to improve readability.
126
- *
127
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-indentation.md#readme
128
- */
129
- "jsdoc/check-indentation": "error",
130
- /**
131
- * Enforce a strict set of tags for the JSDoc comment. This rule also includes
132
- * some custom tags that are used in our projects.
133
- *
134
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.README/rules/check-tag-names.md
135
- */
76
+ // --- Redudant with TypeScript.
136
77
  "jsdoc/require-jsdoc": "off",
137
78
  "jsdoc/require-param-type": "off",
138
- "jsdoc/check-tag-names": ["error", {
139
- definedTags: [
140
- "category"
141
- ]
142
- }],
143
- /**
144
- * Checks for multi-line-style comments which fail to meet the criteria of a jsdoc block,
145
- * namely that it should begin with two and only two asterisks.
146
- *
147
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-bad-blocks.md
148
- */
79
+ "jsdoc/require-returns-type": "off",
80
+ // --- Reports malformed JSDoc comments.
149
81
  "jsdoc/no-bad-blocks": "error",
150
- /**
151
- * It is common practice to prefix a hyphen to parameters in JSDoc. But this
152
- * is sometimes forgotten and has no real purpose. This rule aims to enforce
153
- * that no hyphen is used.
154
- *
155
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-hyphen-before-param-description
156
- */
82
+ "jsdoc/check-alignment": "error",
83
+ "jsdoc/check-indentation": "error",
84
+ // --- Reports invalid block tag names.
85
+ "jsdoc/check-tag-names": ["error", { definedTags: ["category"] }],
86
+ // --- Do not use hyphens before param descriptions.
157
87
  "jsdoc/require-hyphen-before-param-description": ["error", "never"],
158
- /**
159
- * Since we are using TypeScript, we don't need to enforce types in JSDoc.
160
- *
161
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param-type.md
162
- */
163
- "jsdoc/require-returns-type": "off",
164
- /**
165
- * Enforce a new-line between the JSDoc summary and tags. Aims to improve
166
- * readability by separating the summary and tags.
167
- *
168
- * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/tag-lines.md
169
- */
170
- "jsdoc/tag-lines": ["error", "any", { startLines: 1 }],
171
- /** User-defined rules */
172
- ...options.rules
88
+ // --- Newline after description.
89
+ "jsdoc/tag-lines": ["error", "any", { startLines: 1 }]
173
90
  }
174
91
  }
175
92
  ];
176
93
  }
177
- function configJson(options) {
94
+ function json() {
178
95
  return [
179
- ...jsonc.configs["flat/recommended-with-json"],
96
+ ...pluginJsonc.configs["flat/recommended-with-json"],
180
97
  {
181
- files: [
182
- "**/*.json",
183
- "**/*.json5"
184
- ],
185
98
  rules: {
186
- /**
187
- * Automatically apply jsonc rules similar to your configured ESLint core rules to JSON.
188
- *
189
- * @see https://ota-meshi.github.io/eslint-plugin-jsonc/rules/auto.html
190
- */
191
- "jsonc/auto": "error",
192
- /** User-defined rules */
193
- ...options.rules
99
+ // --- Automatically apply jsonc rules similar to your configured ESLint core rules to JSON.
100
+ "jsonc/auto": "error"
194
101
  }
195
102
  }
196
103
  ];
@@ -397,106 +304,89 @@ function jsonTsconfig() {
397
304
  }
398
305
  ];
399
306
  }
400
- function node(options) {
307
+ function node() {
401
308
  return [
309
+ nodePlugin.configs["flat/recommended"],
402
310
  {
403
- plugins: {
404
- n: nodePlugin
311
+ settings: {
312
+ node: {
313
+ version: ">=20.0.0"
314
+ }
405
315
  },
406
316
  rules: {
407
- ...nodePlugin.configs.recommended.rules,
408
- /**
409
- * Disallow the use of extraneous imports. This rule helps prevent the
410
- * use of third-party modules that are not listed in the project's
411
- * dependencies.
412
- *
413
- * @see https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/no-extraneous-import.md
414
- */
415
- "n/no-extraneous-import": "error",
416
- /**
417
- * Disable the no-missing-import as module resolution is already checked
418
- * by other tools and IDEs extensively. This rule is redundant.
419
- *
420
- * @see https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/no-missing-import.md
421
- */
317
+ // --- Redundant with TypeScript module resolution.
422
318
  "n/no-missing-import": "off",
423
319
  "n/no-missing-require": "off",
424
320
  "n/no-unpublished-import": "off",
425
- /**
426
- * Enfore the use of the asyncrounous version of the `fs` and `dns` APIs.
427
- *
428
- * @see https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/no-sync.md
429
- * @see https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/prefer-promises/fs.md
430
- * @see https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/prefer-promises/dns.md
431
- */
432
- "n/no-sync": "off",
433
- "n/prefer-promises/fs": "error",
434
- "n/prefer-promises/dns": "error",
435
- /**
436
- * Allow the use of features up to Node.js version 20. This will allow
437
- * the use of newer ECMAScript features and Node.js APIs.
438
- *
439
- * @see https://github.com/eslint-community/eslint-plugin-n/tree/master/docs/rules
440
- */
321
+ // --- Enforce async functions over synchronous functions.
322
+ "n/no-sync": ["error", { allowAtRootLevel: !0 }],
323
+ // --- Enforce the use of ECMAScript features.
441
324
  "n/no-unsupported-features/es-syntax": "error",
442
325
  "n/no-unsupported-features/es-builtins": "error",
443
- "n/no-unsupported-features/node-builtins": "error",
444
- /**
445
- * Prepend the `node:` prefix to all Node.js core modules. This helps
446
- * identify the module as a Node.js core module and not a third-party
447
- * module.
448
- *
449
- * @see https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/prefer-node-protocol.md
450
- */
326
+ // --- Ignore experimental warnings.
327
+ "n/no-unsupported-features/node-builtins": "off",
328
+ // --- Prefer the use of global objects over built-in modules.
329
+ "n/prefer-global/buffer": "error",
330
+ "n/prefer-global/console": "error",
331
+ "n/prefer-global/process": "error",
332
+ "n/prefer-global/text-decoder": "error",
333
+ "n/prefer-global/text-encoder": "error",
334
+ "n/prefer-global/url": "error",
335
+ "n/prefer-global/url-search-params": "error",
336
+ // --- Prefer the use of the `node:` protocol for built-in modules.
451
337
  "n/prefer-node-protocol": "error",
452
- /** User-defined rules */
453
- ...options.rules
454
- },
455
- settings: {
456
- node: {
457
- version: ">=22.1.0"
458
- }
338
+ // --- Prefer the use of promises over callbacks.
339
+ "n/prefer-promises/fs": "error",
340
+ "n/prefer-promises/dns": "error"
341
+ }
342
+ },
343
+ {
344
+ files: [
345
+ "**/*.test.ts",
346
+ "**/*.spec.ts"
347
+ ],
348
+ rules: {
349
+ // --- Disable the no-sync rule for tests.
350
+ "n/no-sync": "off"
459
351
  }
460
352
  }
461
353
  ];
462
354
  }
463
- function sonarjs(options) {
355
+ function sonarjs() {
464
356
  return [
465
357
  pluginSonarjs.configs.recommended,
466
358
  {
467
359
  rules: {
468
- /**
469
- * Cognitive Complexity is a measure of how hard the control flow of a function
470
- * is to understand. Functions with high Cognitive Complexity will be difficult
471
- * to maintain.
472
- *
473
- * @see https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/cognitive-complexity.md
474
- */
360
+ // --- Increase the default threshold to 30.
475
361
  "sonarjs/cognitive-complexity": ["error", 30],
476
- /**
477
- * Duplicated string literals make the process of refactoring error-prone,
478
- * since you must be sure to update all occurrences. On the other hand,
479
- * constants can be referenced from many places, but only need to be
480
- * updated in a single place.
481
- *
482
- * @see https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-duplicate-string.md
483
- */
484
- "sonarjs/no-duplicate-string": ["error", {
485
- threshold: 10
486
- }],
487
- /**
488
- * Those rules are crashing ESLint at startup, so they are disabled for now.
489
- */
490
- "sonarjs/no-empty-collection": "off",
491
- "sonarjs/no-extra-arguments": "off",
492
- "sonarjs/no-gratuitous-expressions": "off",
493
- "sonarjs/no-one-iteration-loop": "off",
494
- "sonarjs/no-redundant-jump": "off",
495
- "sonarjs/no-unused-collection": "off",
362
+ // --- Increase the default threshold to 10.
363
+ "sonarjs/no-duplicate-string": ["error", { threshold: 10 }],
364
+ // --- Disable unnecessary rules.
365
+ "sonarjs/use-type-alias": "off",
496
366
  "sonarjs/no-use-of-empty-return-value": "off",
497
- "sonarjs/prefer-immediate-return": "off",
498
- /** User-defined rules */
499
- ...options.rules
367
+ "sonarjs/no-nested-functions": "off",
368
+ // --- Disable rules that are already covered by TypeScript.
369
+ "sonarjs/no-extra-arguments": "off",
370
+ "sonarjs/function-return-type": "off",
371
+ "sonarjs/no-misused-promises": "off",
372
+ "sonarjs/no-invariant-returns": "off",
373
+ "sonarjs/no-unused-expressions": "off",
374
+ "sonarjs/different-types-comparison": "off",
375
+ // --- Allow control characters in regex.
376
+ "sonarjs/sonar-no-control-regex": "off"
377
+ }
378
+ },
379
+ {
380
+ files: [
381
+ "**/*.test.ts",
382
+ "**/*.spec.ts"
383
+ ],
384
+ rules: {
385
+ // --- Disable unnecessary rules for test files.
386
+ "sonarjs/cognitive-complexity": "off",
387
+ "sonarjs/no-duplicate-string": "off",
388
+ "sonarjs/no-useless-constructor": "off",
389
+ "sonarjs/public-static-readonly": "off"
500
390
  }
501
391
  }
502
392
  ];
@@ -508,6 +398,7 @@ function getConfigRules(config) {
508
398
  function typescript(options) {
509
399
  return [
510
400
  javascript.configs.recommended,
401
+ // stylistic.configs['recommended-flat'],
511
402
  {
512
403
  languageOptions: {
513
404
  // @ts-expect-error: ignore
@@ -516,7 +407,7 @@ function typescript(options) {
516
407
  ecmaVersion: "latest",
517
408
  sourceType: "module",
518
409
  project: toArray(options.tsConfigPath ?? "./tsconfig.json"),
519
- tsconfigRootDir: cwd()
410
+ tsconfigRootDir: process.cwd()
520
411
  }
521
412
  },
522
413
  plugins: {
@@ -526,7 +417,8 @@ function typescript(options) {
526
417
  },
527
418
  files: [
528
419
  "**/*.{ts,tsx,cts,mts}",
529
- "**/*.{js,jsx,cjs,mjs}"
420
+ "**/*.{js,jsx,cjs,mjs}",
421
+ "**/*.vue"
530
422
  ],
531
423
  rules: {
532
424
  /**
@@ -535,25 +427,11 @@ function typescript(options) {
535
427
  */
536
428
  ...getConfigRules(tslint.configs.recommendedTypeChecked),
537
429
  ...getConfigRules(tslint.configs.stylisticTypeChecked),
538
- /**
539
- * Age-old debate over how to style braces. This rule aims to reduce the
540
- * cognitive load of reasoning about code by enforcing a consistent style.
541
- *
542
- * @see https://eslint.style/rules/default/brace-style
543
- */
430
+ // --- Enforce stroustrup brace style.
544
431
  "brace-style": "off",
545
432
  "@typescript-eslint/brace-style": "off",
546
- "@stylistic/brace-style": ["error", "stroustrup", {
547
- allowSingleLine: !0
548
- }],
549
- /**
550
- * Enforce an indent of 2 spaces. Aims to reduce visual noise and maintain
551
- * readability of code when viewed on GitHub or GitLab.
552
- *
553
- * @see https://eslint.style/rules/default/no-tabs
554
- * @see https://eslint.style/rules/default/indent
555
- * @see https://eslint.style/rules/default/indent-binary-ops
556
- */
433
+ "@stylistic/brace-style": ["error", "stroustrup", { allowSingleLine: !0 }],
434
+ // --- Enforce 2 spaces for indentation and disallow tabs.
557
435
  "no-tabs": "off",
558
436
  indent: "off",
559
437
  "indent-binary-ops": "off",
@@ -563,67 +441,24 @@ function typescript(options) {
563
441
  "@stylistic/no-tabs": "error",
564
442
  "@stylistic/indent": ["error", 2],
565
443
  "@stylistic/indent-binary-ops": ["error", 2],
566
- /**
567
- * Enforce no semi-colons. This rule aims to maintain consistency around the
568
- * use or omission of trailing semicolons. Helps reduce the visual noise in
569
- * the codebase. Also helps to prevent errors when refactoring and adding
570
- * new lines.
571
- *
572
- * @see https://eslint.style/rules/default/semi
573
- */
444
+ // --- No semicolons.
574
445
  semi: "off",
575
446
  "@typescript-eslint/semi": "off",
576
447
  "@stylistic/semi": ["error", "never"],
577
- /**
578
- * Enforce a consistent linebreak style and ensure no leading line breaks
579
- * and a single trailing line break. This rule aims to maintain consistency
580
- * around the use of line breaks in the codebase and reduce the amount of
581
- * diff churn when making changes.
582
- *
583
- * @see https://eslint.style/rules/default/linebreak-style
584
- */
448
+ // --- Consistent line breaks.
585
449
  "eol-last": "off",
586
450
  "no-multiple-empty-lines": "off",
587
451
  "@stylistic/eol-last": ["error", "always"],
588
- "@stylistic/no-multiple-empty-lines": ["error", {
589
- max: 1,
590
- maxBOF: 0,
591
- maxEOF: 0
592
- }],
593
- /**
594
- * Enforce a trailing comma after the last element or property in a multiline
595
- * list of properties or elements. This rule improves the clarity of diffs
596
- * when an item is added or removed from an object or array.
597
- *
598
- * @see https://eslint.style/rules/default/comma-dangle
599
- * @see https://eslint.style/rules/default/comma-spacing
600
- */
452
+ "@stylistic/no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }],
453
+ // --- Enforce dangling commas in multiline object literals.
601
454
  "comma-dangle": "off",
602
455
  "@typescript-eslint/comma-dangle": "off",
603
456
  "@stylistic/comma-dangle": ["error", "always-multiline"],
604
- /**
605
- * This rule requires empty lines before and/or after comments. It is disabled
606
- * however when in an object literal, array, or type literal.
607
- *
608
- * @see https://eslint.style/rules/default/lines-around-comment
609
- */
610
- /**
611
- * Normalize type declaration and definition. This reduces the cognitive load
612
- * of reasoning about code by enforcing a consistent style.
613
- *
614
- * @see https://typescript-eslint.io/rules/consistent-indexed-object-style
615
- */
457
+ // --- Enforce type interfaces over type aliases.
616
458
  "@typescript-eslint/consistent-indexed-object-style": ["error", "record"],
617
459
  "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
618
460
  "@typescript-eslint/array-type": ["error", { default: "array-simple", readonly: "array-simple" }],
619
- /**
620
- * Enforce sequential declarations in the same block. This rule aims to
621
- * enforce a top to bottom ordering of variable and type declarations.
622
- * This reduces the likelihood of a developer skipping over a declaration
623
- * when modifying code.
624
- *
625
- * @see https://typescript-eslint.io/rules/no-use-before-define
626
- */
461
+ // --- Enforce declaration and usage from top to bottom.
627
462
  "no-use-before-define": "off",
628
463
  "@typescript-eslint/no-use-before-define": ["error", {
629
464
  enums: !0,
@@ -633,17 +468,7 @@ function typescript(options) {
633
468
  functions: !1,
634
469
  ignoreTypeReferences: !0
635
470
  }],
636
- /**
637
- * Enforce a consistent spacing around various places where spaces are optional.
638
- * This rule aims to maintain consistency around the use of spaces in the codebase
639
- * and reduce the amount of diff churn when making changes.
640
- *
641
- * @see https://eslint.style/rules/default/key-spacing
642
- * @see https://eslint.style/rules/default/comma-spacing
643
- * @see https://eslint.style/rules/default/block-spacing
644
- * @see https://eslint.style/rules/default/arrow-spacing
645
- * @see https://eslint.style/rules/default/object-curly-spacing
646
- */
471
+ // --- Consistent spacing and line breaks between tokens.
647
472
  "key-spacing": "off",
648
473
  "comma-spacing": "off",
649
474
  "block-spacing": "off",
@@ -713,15 +538,7 @@ function typescript(options) {
713
538
  returnType: { before: !1, after: !0 }
714
539
  }
715
540
  }],
716
- /**
717
- * Enforce the use of `@ts-expect-error` over `@ts-ignore` to silence TypeScript
718
- * errors. This rule aims to ensure that TypeScript errors are never silenced
719
- * without explanation or justification. When an error is fixed, the
720
- * `@ts-expect-error` forces the developer to remove the comment.
721
- *
722
- * @see https://typescript-eslint.io/rules/prefer-ts-expect-error
723
- * @see https://typescript-eslint.io/rules/ban-ts-comment
724
- */
541
+ // --- Enforce `@ts-expect-error` over `@ts-ignore`.
725
542
  "@typescript-eslint/prefer-ts-expect-error": "error",
726
543
  "@typescript-eslint/ban-ts-comment": ["error", {
727
544
  "ts-check": !1,
@@ -886,93 +703,32 @@ function typescript(options) {
886
703
  }
887
704
  ];
888
705
  }
889
- const UNICORN_RECOMMENDED_RULES = unicornPlugin.configs.recommended.rules;
890
- function unicorn(options) {
706
+ function unicorn() {
891
707
  return [
708
+ unicornPlugin.configs["flat/recommended"],
892
709
  {
893
- plugins: {
894
- unicorn: unicornPlugin
895
- },
896
710
  rules: {
897
- ...UNICORN_RECOMMENDED_RULES,
898
- /**
899
- * Improve regexes by making them shorter, consistent, and safer. This rule
900
- * aims to improve readability and consistency of regexes while also
901
- * mitigating regex denial of service attacks by disallowing potentially
902
- * catastrophic backtracking.
903
- *
904
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/better-regex.md
905
- */
711
+ // --- Allow any kind of import style.
712
+ "unicorn/import-style": "off",
713
+ // --- Improve regexes by making them shorter, consistent, and safer.
906
714
  "unicorn/better-regex": "error",
907
- /**
908
- * Enforce the catch clause parameter name to be named `error`. This rule
909
- * aims to enforce a consistent parameter name in catch clauses. The name
910
- * `error` is the most commonly used name for the parameter that is passed
911
- * to the catch clause.
912
- *
913
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/catch-error-name.md
914
- */
915
- "unicorn/catch-error-name": ["error", {
916
- name: "error"
917
- }],
918
- /**
919
- * Enforce the use of camelCase or PascalCase when naming folders, files and
920
- * variables. This rule aims to enforce a consistent naming convention for
921
- * filenames, directory names, and variable names.
922
- *
923
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/filename-case.md
924
- */
715
+ // --- Use destructured variables over properties.
716
+ "unicorn/consistent-destructuring": "error",
717
+ // --- Enforce consistent function scoping except for arrow functions.
718
+ "unicorn/consistent-function-scoping": ["error", { checkArrowFunctions: !1 }],
719
+ // --- Disable switch-case fallthrough.
720
+ "unicorn/prefer-switch": "off",
721
+ // --- Enforce camelCase & PascalCase in filenames. Exepct non TS/JS files.
925
722
  "unicorn/filename-case": ["error", {
926
- cases: {
927
- camelCase: !0,
928
- pascalCase: !0
929
- },
930
- ignore: [
931
- "^[A-Z]+(.md)?$"
932
- ]
723
+ multipleFileExtensions: !1,
724
+ cases: { camelCase: !0, pascalCase: !0 },
725
+ ignore: [/\.json$/, /\.md$/, /\.yml$/, /\.yaml$/]
933
726
  }],
934
- /**
935
- * Disable the recommended import style rules. We want to be able to use both
936
- * named and default imports in our codebase.
937
- *
938
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/import-style.md
939
- */
940
- "unicorn/import-style": "off",
941
- /**
942
- * Disallow unsafe regular expressions. Regular expressions can be unsafe
943
- * when they are too complex and can cause catastrophic backtracking. This
944
- * rule disallows regular expressions that can lead to catastrophic
945
- *
946
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unsafe-regex.md
947
- */
948
- "unicorn/no-unsafe-regex": "error",
949
- /**
950
- * Enforces a convention of grouping digits using numeric separators.
951
- * Long numbers can become really hard to read, so cutting it into groups
952
- * of digits, separated with a _, is important to keep your code clear.
953
- *
954
- * @see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/numeric-separators-style.md
955
- */
727
+ // --- Improve readability by using numeric separators.
956
728
  "unicorn/numeric-separators-style": ["error", {
957
729
  onlyIfContainsSeparator: !0
958
730
  }],
959
- "unicorn/number-literal-case": "error",
960
- "unicorn/consistent-function-scoping": "off",
961
- "unicorn/error-message": "error",
962
- "unicorn/escape-case": "error",
963
- "unicorn/no-array-callback-reference": "off",
964
- "unicorn/no-array-for-each": "off",
965
- "unicorn/no-array-instanceof": "error",
966
- "unicorn/no-new-buffer": "error",
967
- "unicorn/no-static-only-class": "off",
968
- "unicorn/prefer-code-point": "off",
969
- "unicorn/prefer-exponentiation-operator": "error",
970
- "unicorn/prefer-includes": "error",
971
- "unicorn/prefer-module": "off",
972
- "unicorn/prefer-starts-ends-with": "error",
973
- "unicorn/prefer-switch": "off",
974
- "unicorn/prefer-text-content": "error",
975
- "unicorn/prefer-type-error": "error",
731
+ // --- Enforce long variable names when they are meaningful.
976
732
  "unicorn/prevent-abbreviations": ["error", {
977
733
  allowList: {
978
734
  args: !0,
@@ -990,110 +746,50 @@ function unicorn(options) {
990
746
  y: !0,
991
747
  z: !0
992
748
  }
993
- }],
994
- "unicorn/throw-new-error": "error"
995
- },
996
- /** User-defined rules */
997
- ...options.rules
749
+ }]
750
+ }
751
+ },
752
+ {
753
+ files: [
754
+ "**/*.test.ts",
755
+ "**/*.spec.ts"
756
+ ],
757
+ rules: {
758
+ // --- Disable unnecessary rules for test files.
759
+ "unicorn/no-null": "off",
760
+ "unicorn/no-useless-undefined": "off",
761
+ "unicorn/no-static-only-class": "off"
762
+ }
998
763
  }
999
764
  ];
1000
765
  }
1001
- function vitest(options) {
766
+ function vitest() {
1002
767
  return [
768
+ vitestPlugin.configs.recommended,
1003
769
  {
1004
- plugins: {
1005
- vitest: vitestPlugin
1006
- },
1007
- files: [
1008
- "**/*.{ts,mts,cts,tsx,d.ts}",
1009
- "**/*.{js,mjs,cjs,jsx}"
1010
- ],
1011
- settings: {
1012
- vitest: {
1013
- typecheck: !0
1014
- }
1015
- },
1016
- languageOptions: {
1017
- globals: {
1018
- ...vitestPlugin.environments.env.globals,
1019
- expectTypeOf: !0
1020
- }
1021
- },
1022
770
  rules: {
1023
- /**
1024
- * Inject all configuration from eslint-plugin-vitest.
1025
- *
1026
- * @see https://github.com/veritem/eslint-plugin-vitest/tree/main?tab=readme-ov-file#rules
1027
- */
1028
- ...vitestPlugin.configs.all.rules,
1029
- /**
1030
- * This rule aims to enforce having at least one expectation
1031
- * in test body to ensure that the test is actually testing something.
1032
- *
1033
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md
1034
- */
771
+ // --- Add the `expectTypeOf` function to the list of assert functions.
1035
772
  "vitest/expect-expect": ["error", {
1036
- assertFunctionNames: [
1037
- "expect",
1038
- "expectTypeOf"
1039
- ]
773
+ assertFunctionNames: ["expect", "expectTypeOf"]
1040
774
  }],
1041
- /**
1042
- * Disable the conditional test rule as it is prevent's us to use in-source
1043
- * testing when using the `if (import.meta.vitest)` condition. Also disable
1044
- * the rule that prevents the use of if-else statements in tests as we want
1045
- * to use it to test type predicates.
1046
- *
1047
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-in-test.md
1048
- */
1049
- "vitest/no-conditional-in-test": "off",
1050
- "vitest/no-conditional-tests": "off",
1051
- /**
1052
- * Since we use in-source testing, we need to disable the rule as it may prevent
1053
- * us from using top level evaluation that are not part of the test suite.
1054
- *
1055
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md
1056
- */
1057
- "vitest/require-hook": "off",
1058
- "vitest/no-hooks": "off",
1059
- /**
1060
- * Disable the rule that enforces the use of `expect.assertions` in tests.
1061
- * As much as this rule enforces a best-practice, it is not always necessary.
1062
- *
1063
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-expect-assertions.md
1064
- */
1065
- "vitest/prefer-expect-assertions": "off",
1066
- /**
1067
- * Some functions may have a single test case, and it is not necessary
1068
- * to wrap them in a describe block.
1069
- *
1070
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/require-top-level-describe.md
1071
- */
1072
- "vitest/require-top-level-describe": "off",
1073
- /**
1074
- * Enforce rule titles starts with 'should'. This is a convention
1075
- * to force the developer to write the test in a way that it reads
1076
- * like a sentence.
1077
- *
1078
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md
1079
- */
775
+ // --- Enforce a single top-level describe block.
776
+ "vitest/require-top-level-describe": ["error", { maxNumberOfTopLevelDescribes: 1 }],
777
+ // --- Enforce 'should' as the prefix for test titles.
1080
778
  "vitest/valid-title": ["error", {
1081
779
  ignoreTypeOfDescribeName: !0,
1082
- mustMatch: {
1083
- test: ["^should"]
1084
- }
780
+ mustMatch: { test: ["^should"] }
1085
781
  }],
1086
- /**
1087
- * Disable the prefer-truthy/false rule as we want to allow the use of strict equality checks
1088
- * with boolean values.
1089
- *
1090
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-truthy.md
1091
- * @see https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-falsy.md
1092
- */
782
+ // --- Prefer strict equality checks.
1093
783
  "vitest/prefer-to-be-truthy": "off",
1094
784
  "vitest/prefer-to-be-falsy": "off",
1095
- /** User-defined rules */
1096
- ...options.rules
785
+ /// --- Loosen the rules for test files.
786
+ "vitest/no-hooks": "off",
787
+ "vitest/require-hook": "off",
788
+ "vitest/no-conditional-in-test": "off",
789
+ "vitest/no-conditional-tests": "off",
790
+ "vitest/prefer-expect-assertions": "off",
791
+ "vitest/padding-around-all": "off",
792
+ "vitest/padding-around-expect-groups": "off"
1097
793
  }
1098
794
  }
1099
795
  ];
@@ -1101,7 +797,7 @@ function vitest(options) {
1101
797
  function vue(options) {
1102
798
  const TYPESCRIPT_CONFIG = typescript(options).at(1);
1103
799
  return [
1104
- ...vuePlugin.configs?.["flat/base"],
800
+ ...vuePlugin.configs["flat/recommended"],
1105
801
  {
1106
802
  plugins: {
1107
803
  vue: vuePlugin,
@@ -1132,109 +828,48 @@ function vue(options) {
1132
828
  }
1133
829
  },
1134
830
  processor: mergeProcessors([
1135
- // @ts-expect-error: ignore
1136
- vuePlugin.processors[".vue"],
831
+ vuePlugin.processors.vue,
1137
832
  vueProcessorBlocks()
1138
833
  ]),
1139
834
  files: [
1140
- "**/*.vue"
835
+ "**/*.vue",
836
+ "**/*.ts"
1141
837
  ],
1142
838
  rules: {
1143
- ...TYPESCRIPT_CONFIG.rules,
1144
- // @ts-expect-error: ignore
1145
- ...vuePlugin.configs["flat/recommended"].rules,
1146
- // @ts-expect-error: ignore
1147
- ...vuePlugin.configs["flat/strongly-recommended"].rules,
1148
- // @ts-expect-error: ignore
1149
- ...vuePlugin.configs["flat/essential"].rules,
1150
- /**
1151
- * Disable some TypeScript rules that may conflict with the Vue SFC parser.
1152
- */
1153
- "@typescript-eslint/no-unsafe-call": "off",
1154
- "@typescript-eslint/no-unsafe-return": "off",
1155
- "@typescript-eslint/no-misused-promises": "off",
1156
- "@typescript-eslint/no-unsafe-assignment": "off",
1157
- "@typescript-eslint/no-unsafe-member-access": "off",
1158
- /**
1159
- * Enforces consistent usage of type imports. This rule will enforce the use
1160
- * of `type` imports to make it easier for the Vue SFC compiler to analyze
1161
- * the code and infer the dependency graph correctly.
1162
- *
1163
- * @see https://typescript-eslint.io/rules/consistent-type-imports
1164
- * @see https://vuejs.github.io/vetur/guide/FAQ.html#why-does-vetur-show-cannot-find-module-xxx
1165
- */
1166
- // '@typescript-eslint/consistent-type-imports': ['error', {
1167
- // disallowTypeAnnotations: false,
1168
- // fixStyle: 'inline-type-imports',
1169
- // prefer: 'type-imports',
1170
- // }],
1171
- /**
1172
- * Enforce the order of the top-level properties in the component. This rule
1173
- * helps to maintain consistency and readability by enforcing a predictable
1174
- * order of the top-level properties in the component.
1175
- *
1176
- * @see https://eslint.vuejs.org/rules/ordered-component-elements.html
1177
- */
1178
- "vue/block-order": ["error", {
1179
- order: [
1180
- "docs",
1181
- "script",
1182
- "template",
1183
- "style"
1184
- ]
1185
- }],
1186
- /**
1187
- * Enforce use of the Composition API and TypeScript. This rule forbids the
1188
- * use of the Options API and JavaScript in Vue components for better
1189
- * consistency and maintainability.
1190
- *
1191
- * @see https://eslint.vuejs.org/rules/vue/prefer-define-options.html
1192
- * @see https://eslint.vuejs.org/rules/vue/component-api-style.html
1193
- */
839
+ "vue/return-in-computed-property": "off",
840
+ // --- Allow multiple component definitions in a single file.
841
+ "vue/one-component-per-file": "off",
842
+ // --- Enforce Component API style.
1194
843
  "vue/prefer-define-options": "error",
1195
- "vue/component-api-style": ["error", ["script-setup"]],
1196
- /**
1197
- * Enforce the component name casing to be PascalCase. This rules helps identify
1198
- * and distinguish between components and HTML elements. It also helps to avoid
1199
- * conflicts with existing and future HTML elements.
1200
- *
1201
- * @see https://eslint.vuejs.org/rules/component-name-in-template-casing.html
1202
- */
844
+ "vue/component-api-style": ["error", ["script-setup", "composition"]],
845
+ // --- Enforce PascalCase components and allow reserved and single-word names.
846
+ "vue/multi-word-component-names": "off",
847
+ "vue/no-reserved-component-names": "off",
1203
848
  "vue/component-name-in-template-casing": ["error", "PascalCase", {
1204
849
  ignores: [String.raw`/\./`],
1205
850
  registeredComponentsOnly: !1
1206
851
  }],
1207
- /**
1208
- * Enforce consistent spacing between HTML comments and their content.
1209
- *
1210
- * @see https://eslint.vuejs.org/rules/html-comment-content-spacing.html
1211
- * @see https://eslint.vuejs.org/rules/html-comment-content-newline.html
1212
- */
852
+ // --- Consistent spacing around HTML comments.
853
+ "vue/html-comment-indent": ["error", 2],
854
+ "vue/multiline-html-element-content-newline": ["error", {
855
+ allowEmptyLines: !0,
856
+ ignores: [],
857
+ ignoreWhenEmpty: !0
858
+ }],
1213
859
  "vue/html-comment-content-spacing": ["error", "always"],
1214
860
  "vue/html-comment-content-newline": ["error", {
1215
861
  multiline: "always",
1216
862
  singleline: "never"
1217
863
  }],
1218
- /**
1219
- * Enforce consistent spacing between HTML / Component tags. This makes it
1220
- * easier to read and understand the structure of the component.
1221
- *
1222
- * @see https://eslint.vuejs.org/rules/block-spacing.html
1223
- * @see https://eslint.vuejs.org/rules/padding-line-between-blocks.html
1224
- * @see https://eslint.vuejs.org/rules/padding-line-between-tags.html
1225
- */
864
+ // --- Consistent block order in Vue components.
865
+ "vue/block-order": ["error", { order: ["script", "template", "style", "i18n"] }],
866
+ // --- Consistent spacing in and around the block.
1226
867
  "vue/block-spacing": ["error", "always"],
1227
868
  "vue/padding-line-between-blocks": ["error", "always"],
1228
869
  "vue/padding-line-between-tags": ["error", [
1229
870
  { blankLine: "consistent", next: "*", prev: "*" },
1230
871
  { blankLine: "always", next: "*", prev: "comment" }
1231
872
  ]],
1232
- "vue/html-comment-indent": ["error", 2],
1233
- "vue/multiline-html-element-content-newline": ["error", {
1234
- allowEmptyLines: !0,
1235
- ignores: [],
1236
- ignoreWhenEmpty: !0
1237
- }],
1238
873
  /**
1239
874
  * Enforce consistent spacing and newlines in the template. This rule helps
1240
875
  * to maintain consistency and readability by enforcing a predictable
@@ -1263,8 +898,6 @@ function vue(options) {
1263
898
  *
1264
899
  * @see https://eslint.vuejs.org/rules/multi-word-component-names.html
1265
900
  */
1266
- "vue/multi-word-component-names": "off",
1267
- "vue/no-reserved-component-names": "off",
1268
901
  /**
1269
902
  * Reports the destructuring or member expression of props passed to setup
1270
903
  * causing the value to lose reactivity. This rule helps to avoid common
@@ -1336,7 +969,6 @@ function vue(options) {
1336
969
  "vue/block-lang": ["error", {
1337
970
  script: { lang: "ts" }
1338
971
  }],
1339
- "vue/return-in-computed-property": "off",
1340
972
  "vue/no-sparse-arrays": "error",
1341
973
  "vue/no-unused-emit-declarations": "error",
1342
974
  "vue/no-use-v-else-with-v-for": "error",
@@ -1407,34 +1039,89 @@ function vue(options) {
1407
1039
  "vue/space-in-parens": ["error", "never"],
1408
1040
  "vue/space-infix-ops": "error",
1409
1041
  "vue/space-unary-ops": ["error", { nonwords: !1, words: !0 }],
1410
- "vue/template-curly-spacing": "error",
1411
- /** User-defined rules */
1412
- ...options.rules
1042
+ "vue/template-curly-spacing": "error"
1043
+ }
1044
+ },
1045
+ // --- Disable some TypeScript rules that may conflict with the Vue SFC parser.
1046
+ {
1047
+ files: [
1048
+ "**/*.vue"
1049
+ ],
1050
+ rules: {
1051
+ "@typescript-eslint/no-unsafe-call": "off",
1052
+ "@typescript-eslint/no-unsafe-return": "off",
1053
+ "@typescript-eslint/no-unsafe-argument": "off",
1054
+ "@typescript-eslint/no-unsafe-assignment": "off",
1055
+ "@typescript-eslint/no-unsafe-member-access": "off",
1056
+ "@typescript-eslint/no-misused-promises": "off"
1057
+ }
1058
+ },
1059
+ // --- Disable in test files.
1060
+ {
1061
+ files: [
1062
+ "**/*.test.ts",
1063
+ "**/*.spec.ts"
1064
+ ],
1065
+ rules: {
1066
+ "vue/one-component-per-file": "off"
1067
+ }
1068
+ }
1069
+ ];
1070
+ }
1071
+ function yml() {
1072
+ return [
1073
+ ...pluginYml.configs["flat/standard"],
1074
+ ...pluginYml.configs["flat/recommended"],
1075
+ {
1076
+ rules: {
1077
+ // --- Force single quotes.
1078
+ "yml/quotes": ["error", {
1079
+ avoidEscape: !0,
1080
+ prefer: "single"
1081
+ }],
1082
+ // --- Remove trailing zeros in numbers.
1083
+ "yml/no-trailing-zeros": "error",
1084
+ // --- Prevent empty keys.
1085
+ "yml/require-string-key": "error",
1086
+ // --- Prevent empty values or weird newlines in mappings.
1087
+ "yml/block-mapping-colon-indicator-newline": "error",
1088
+ // --- No more than one empty line.
1089
+ "yml/no-multiple-empty-lines": ["error", {
1090
+ max: 1,
1091
+ maxBOF: 0,
1092
+ maxEOF: 0
1093
+ }],
1094
+ // --- Sort environemnt variables alphabetically.
1095
+ "yml/sort-sequence-values": ["error", {
1096
+ pathPattern: "^env$",
1097
+ order: { type: "asc" }
1098
+ }]
1413
1099
  }
1414
1100
  }
1415
1101
  ];
1416
1102
  }
1417
1103
  function all(options = {}) {
1418
1104
  return [
1419
- ...antfu(options),
1420
- ...eslintComments(options),
1421
- ...jsdoc(options),
1422
- ...configJson(options),
1105
+ ...antfu(),
1106
+ ...eslintComments(),
1107
+ ...jsdoc(),
1108
+ ...json(),
1423
1109
  ...jsonPackage(),
1424
1110
  ...jsonTsconfig(),
1425
- ...node(options),
1426
- ...sonarjs(options),
1111
+ ...node(),
1112
+ ...sonarjs(),
1427
1113
  ...typescript(options),
1428
- ...unicorn(options),
1429
- ...vitest(options),
1114
+ ...unicorn(),
1115
+ ...vitest(),
1430
1116
  ...vue(options),
1117
+ ...yml(),
1431
1118
  {
1432
1119
  ignores: [
1433
1120
  "**/dist",
1434
1121
  "**/bin",
1435
1122
  "**/node_modules",
1436
1123
  "**/.nuxt",
1437
- "**/output",
1124
+ "**/.output",
1438
1125
  "**/coverage",
1439
1126
  "**/public",
1440
1127
  "**/__wip__",