@unshared/eslint-config 0.0.19 → 0.1.0

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