@d-kuehn/eslint-config 1.0.3

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.js ADDED
@@ -0,0 +1,1216 @@
1
+ // src/eslintConfigs/defaults.ts
2
+ import process from "node:process";
3
+
4
+ // src/helpers/index.ts
5
+ var interopDefault = async (module_) => {
6
+ const resolved = await module_;
7
+ return resolved.default || resolved;
8
+ };
9
+ var combine = async (...configs) => {
10
+ const resolved = await Promise.all(configs);
11
+ return resolved.flat();
12
+ };
13
+
14
+ // src/eslintConfigs/globs.ts
15
+ var GLOBS_EXCLUDE = [
16
+ "**/node_modules",
17
+ "**/dist",
18
+ "**/package-lock.json",
19
+ "**/yarn.lock",
20
+ "**/pnpm-lock.yaml",
21
+ "**/bun.lockb",
22
+ "**/output",
23
+ "**/coverage",
24
+ "**/temp",
25
+ "**/.temp",
26
+ "**/tmp",
27
+ "**/.tmp",
28
+ "**/.history",
29
+ "**/.vitepress/cache",
30
+ "**/.nuxt",
31
+ "**/.next",
32
+ "**/.vercel",
33
+ "**/.changeset",
34
+ "**/.idea",
35
+ "**/.cache",
36
+ "**/.output",
37
+ "**/.vite-inspect",
38
+ "**/.yarn",
39
+ "**/CHANGELOG*.md",
40
+ "**/*.min.*",
41
+ "**/LICENSE*",
42
+ "**/__snapshots__",
43
+ "**/auto-import?(s).d.ts",
44
+ "**/components.d.ts",
45
+ "**/.git",
46
+ "**/playwright",
47
+ "**/docs",
48
+ "**/lib",
49
+ "**/storybook-static",
50
+ "**/.pnpm-store"
51
+ ];
52
+ var GLOB_VUE = "**/*.vue";
53
+ var GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
54
+ var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
55
+ var GLOB_TS = "**/*.?([cm])ts";
56
+ var GLOB_TSX = "**/*.?([cm])tsx";
57
+ var GLOB_JS = "**/*.?([cm])js";
58
+ var GLOB_JSX = "**/*.?([cm])jsx";
59
+ var GLOB_JSON = "**/*.json";
60
+ var GLOB_JSON5 = "**/*.json5";
61
+ var GLOB_JSONC = "**/*.jsonc";
62
+ var GLOB_STYLE = "**/*.{c,le,sc}ss";
63
+ var GLOB_CSS = "**/*.css";
64
+ var GLOB_POSTCSS = "**/*.{p,post}css";
65
+ var GLOB_LESS = "**/*.less";
66
+ var GLOB_SCSS = "**/*.scss";
67
+ var GLOB_MARKDOWN = "**/*.md";
68
+ var GLOB_STORYBOOK = "**/*.stories.{ts,tsx,js,jsx,mjs,cjs}";
69
+ var GLOB_HTML = "**/*.htm?(l)";
70
+ var GLOBS_TESTS = [
71
+ `**/*.spec.${GLOB_SRC_EXT}`,
72
+ `**/*.test.${GLOB_SRC_EXT}`,
73
+ `**/*.bench.${GLOB_SRC_EXT}`,
74
+ `**/*.benchmark.${GLOB_SRC_EXT}`
75
+ ];
76
+ var GLOBS_TESTS_E2E = [
77
+ `**/*.e2e.${GLOB_SRC_EXT}`
78
+ ];
79
+
80
+ // src/eslintConfigs/defaults.ts
81
+ var defaults = async (options = {}) => {
82
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
83
+ const eslint = await interopDefault(import("@eslint/js"));
84
+ return [
85
+ {
86
+ ignores: commonIgnores,
87
+ name: "eslint/ignores"
88
+ },
89
+ {
90
+ files: [
91
+ GLOB_SRC,
92
+ GLOB_VUE
93
+ ],
94
+ ignores: commonIgnores,
95
+ ...options?.plugins && { plugins: options.plugins },
96
+ name: "eslint/custom",
97
+ rules: {
98
+ ...eslint.configs.recommended.rules,
99
+ "complexity": ["error", 10],
100
+ "consistent-return": "error",
101
+ "curly": ["error", "multi-line"],
102
+ "max-lines-per-function": [
103
+ "error",
104
+ {
105
+ max: 32,
106
+ skipBlankLines: true,
107
+ skipComments: true
108
+ }
109
+ ],
110
+ "no-console": process.env.NODE_ENV === "production" ? "error" : "warn",
111
+ "no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn",
112
+ "sort-imports": [
113
+ "error",
114
+ {
115
+ allowSeparatedGroups: true,
116
+ ignoreCase: false,
117
+ ignoreMemberSort: false
118
+ }
119
+ ],
120
+ ...options?.rules && options.rules
121
+ }
122
+ }
123
+ ];
124
+ };
125
+
126
+ // src/eslintConfigs/importX.ts
127
+ var importX = async (options = {}) => {
128
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
129
+ const pluginImport = await interopDefault(import("eslint-plugin-import-x"));
130
+ return [
131
+ {
132
+ ignores: commonIgnores,
133
+ name: "import-x/ignores"
134
+ },
135
+ {
136
+ files: [GLOB_SRC, GLOB_VUE],
137
+ ignores: commonIgnores,
138
+ name: "import-x/custom",
139
+ plugins: {
140
+ "import-x": pluginImport,
141
+ ...options?.plugins && options.plugins
142
+ },
143
+ rules: {
144
+ "import-x/exports-last": "error",
145
+ "import-x/first": "error",
146
+ "import-x/newline-after-import": [
147
+ "error",
148
+ { considerComments: true }
149
+ ],
150
+ // todo: enable on local when https://github.com/un-ts/eslint-plugin-import-x/issues/113 is resolved
151
+ // currently it takes 30 seconds longer or segfault when using this rule
152
+ // 'import-x/no-cycle': 'error',
153
+ "import-x/no-duplicates": "error",
154
+ // ref: https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-extraneous-dependencies.md
155
+ "import-x/no-extraneous-dependencies": [
156
+ "error",
157
+ {
158
+ devDependencies: false,
159
+ optionalDependencies: false,
160
+ peerDependencies: false
161
+ }
162
+ ],
163
+ "import-x/no-internal-modules": "off",
164
+ "import-x/no-mutable-exports": "error",
165
+ "import-x/no-self-import": "error",
166
+ "import-x/no-unused-modules": ["error"],
167
+ // ref: https://github.com/import-js/eslint-plugin-import/issues/2524
168
+ "import-x/no-useless-path-segments": [
169
+ "error",
170
+ { noUselessIndex: true }
171
+ ],
172
+ "import-x/order": [
173
+ "error",
174
+ {
175
+ "distinctGroup": false,
176
+ "groups": [
177
+ "builtin",
178
+ "external",
179
+ "internal",
180
+ "parent",
181
+ "sibling",
182
+ "index",
183
+ "object",
184
+ "type"
185
+ ],
186
+ "newlines-between": "always-and-inside-groups",
187
+ "pathGroups": [
188
+ {
189
+ group: "internal",
190
+ pattern: "@/**",
191
+ position: "after"
192
+ }
193
+ ]
194
+ }
195
+ ],
196
+ "import-x/prefer-default-export": "off",
197
+ ...options?.rules && options.rules
198
+ }
199
+ }
200
+ ];
201
+ };
202
+
203
+ // src/eslintConfigs/jsdoc.ts
204
+ var jsdoc = async (options = {}) => {
205
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
206
+ const pluginJsdoc = await interopDefault(import("eslint-plugin-jsdoc"));
207
+ return [
208
+ {
209
+ ignores: commonIgnores,
210
+ name: "jsdoc/ignores"
211
+ },
212
+ {
213
+ files: [GLOB_SRC, GLOB_VUE],
214
+ ignores: commonIgnores,
215
+ name: "jsdoc/custom",
216
+ plugins: {
217
+ jsdoc: pluginJsdoc,
218
+ ...options.plugins && options.plugins
219
+ },
220
+ rules: {
221
+ ...pluginJsdoc.configs["flat/recommended"].rules,
222
+ "jsdoc/check-tag-names": [
223
+ "warn",
224
+ { definedTags: ["vitest-environment"] }
225
+ ],
226
+ "jsdoc/no-defaults": "off",
227
+ "jsdoc/tag-lines": [
228
+ "error",
229
+ "any",
230
+ { startLines: 1 }
231
+ ],
232
+ ...options?.rules && options.rules
233
+ }
234
+ }
235
+ ];
236
+ };
237
+
238
+ // src/eslintConfigs/jsonc.ts
239
+ var DEFAULTS = {
240
+ "jsonc/indent": ["error", 2],
241
+ "jsonc/key-spacing": [
242
+ "error",
243
+ {
244
+ afterColon: true,
245
+ beforeColon: false
246
+ }
247
+ ],
248
+ "jsonc/object-curly-newline": [
249
+ "error",
250
+ {
251
+ consistent: true,
252
+ multiline: true
253
+ }
254
+ ],
255
+ "jsonc/object-curly-spacing": ["error", "always"],
256
+ "jsonc/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }]
257
+ };
258
+ var jsonc = async (options = {}) => {
259
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
260
+ const [pluginJsonc, parserJsonc] = await Promise.all([
261
+ interopDefault(import("eslint-plugin-jsonc")),
262
+ interopDefault(import("jsonc-eslint-parser"))
263
+ ]);
264
+ return [
265
+ {
266
+ ignores: commonIgnores,
267
+ name: "jsonc/ignores"
268
+ },
269
+ {
270
+ files: [
271
+ GLOB_JSON,
272
+ GLOB_JSONC,
273
+ GLOB_JSON5
274
+ ],
275
+ ignores: commonIgnores,
276
+ languageOptions: {
277
+ parser: parserJsonc
278
+ },
279
+ name: "jsonc/setup",
280
+ plugins: {
281
+ jsonc: pluginJsonc,
282
+ ...options?.plugins && options.plugins
283
+ }
284
+ },
285
+ {
286
+ files: [GLOB_JSON],
287
+ name: "jsonc/json",
288
+ rules: {
289
+ ...pluginJsonc.configs["recommended-with-json"].rules,
290
+ ...DEFAULTS
291
+ }
292
+ },
293
+ {
294
+ files: [GLOB_JSONC],
295
+ name: "jsonc/jsonc",
296
+ rules: {
297
+ ...pluginJsonc.configs["recommended-with-jsonc"].rules,
298
+ ...DEFAULTS
299
+ }
300
+ },
301
+ {
302
+ files: [GLOB_JSON5],
303
+ name: "jsonc/json5",
304
+ rules: {
305
+ ...pluginJsonc.configs["recommended-with-json5"].rules,
306
+ ...DEFAULTS
307
+ }
308
+ }
309
+ ];
310
+ };
311
+
312
+ // src/eslintConfigs/perfectionist.ts
313
+ var perfectionist = async (options = {}) => {
314
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
315
+ const pluginPerfectionist = await interopDefault(import("eslint-plugin-perfectionist"));
316
+ return [
317
+ {
318
+ ignores: commonIgnores,
319
+ name: "perfectionist/ignores"
320
+ },
321
+ {
322
+ files: [
323
+ GLOB_SRC,
324
+ GLOB_VUE
325
+ ],
326
+ ignores: commonIgnores,
327
+ name: "perfectionist/custom",
328
+ plugins: {
329
+ perfectionist: pluginPerfectionist,
330
+ ...options?.plugins && options.plugins
331
+ },
332
+ rules: {
333
+ ...pluginPerfectionist.configs["recommended-natural"].rules,
334
+ "perfectionist/sort-array-includes": [
335
+ "error",
336
+ {
337
+ groupKind: "literals-first",
338
+ ignoreCase: false,
339
+ order: "asc",
340
+ type: "natural"
341
+ }
342
+ ],
343
+ "perfectionist/sort-classes": [
344
+ "error",
345
+ {
346
+ groups: [
347
+ "index-signature",
348
+ "static-property",
349
+ "private-property",
350
+ "property",
351
+ "constructor",
352
+ "static-method",
353
+ "private-method",
354
+ "method"
355
+ ],
356
+ order: "asc",
357
+ type: "natural"
358
+ }
359
+ ],
360
+ "perfectionist/sort-enums": [
361
+ "error",
362
+ {
363
+ ignoreCase: false,
364
+ order: "asc",
365
+ type: "natural"
366
+ }
367
+ ],
368
+ // conflicts with eslint-import-x
369
+ "perfectionist/sort-imports": "off",
370
+ "perfectionist/sort-interfaces": [
371
+ "error",
372
+ {
373
+ ignoreCase: false,
374
+ order: "asc",
375
+ type: "natural"
376
+ }
377
+ ],
378
+ "perfectionist/sort-maps": [
379
+ "error",
380
+ {
381
+ ignoreCase: false,
382
+ order: "asc",
383
+ type: "natural"
384
+ }
385
+ ],
386
+ "perfectionist/sort-named-exports": [
387
+ "error",
388
+ {
389
+ ignoreCase: false,
390
+ order: "asc",
391
+ type: "natural"
392
+ }
393
+ ],
394
+ // import sorting is handled by eslint-plugin-import-x
395
+ "perfectionist/sort-named-imports": "off",
396
+ "perfectionist/sort-object-types": [
397
+ "error",
398
+ {
399
+ ignoreCase: false,
400
+ order: "asc",
401
+ type: "natural"
402
+ }
403
+ ],
404
+ "perfectionist/sort-objects": [
405
+ "error",
406
+ {
407
+ ignoreCase: false,
408
+ order: "asc",
409
+ type: "natural"
410
+ }
411
+ ],
412
+ "perfectionist/sort-union-types": [
413
+ "error",
414
+ {
415
+ ignoreCase: false,
416
+ order: "asc",
417
+ type: "natural"
418
+ }
419
+ ],
420
+ // ref: https://github.com/azat-io/eslint-plugin-perfectionist/issues/175
421
+ "perfectionist/sort-vue-attributes": "off",
422
+ ...options?.rules && options.rules
423
+ }
424
+ }
425
+ ];
426
+ };
427
+
428
+ // src/eslintConfigs/playwright.ts
429
+ var playwright = async (options = {}) => {
430
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
431
+ const [pluginImport, pluginPlaywright, pluginUnicorn] = await Promise.all([
432
+ interopDefault(import("eslint-plugin-import-x")),
433
+ interopDefault(import("eslint-plugin-playwright")),
434
+ interopDefault(import("eslint-plugin-unicorn"))
435
+ ]);
436
+ return [
437
+ {
438
+ ignores: commonIgnores,
439
+ name: "playwright/ignores"
440
+ },
441
+ {
442
+ ...pluginPlaywright.configs["flat/recommended"],
443
+ files: [...GLOBS_TESTS_E2E],
444
+ ignores: commonIgnores,
445
+ name: "playwright/custom",
446
+ plugins: {
447
+ "import-x": pluginImport,
448
+ "playwright": pluginPlaywright,
449
+ "unicorn": pluginUnicorn,
450
+ ...options?.plugins && options.plugins
451
+ },
452
+ rules: {
453
+ ...pluginPlaywright.configs["flat/recommended"].rules,
454
+ "import-x/no-extraneous-dependencies": [
455
+ "error",
456
+ {
457
+ devDependencies: [
458
+ ...GLOBS_TESTS,
459
+ ...GLOBS_TESTS_E2E
460
+ ],
461
+ optionalDependencies: false,
462
+ peerDependencies: false
463
+ }
464
+ ],
465
+ "unicorn/prevent-abbreviations": [
466
+ "error",
467
+ {
468
+ ignore: [
469
+ ".e2e.*"
470
+ ]
471
+ }
472
+ ],
473
+ ...options?.rules && options.rules
474
+ }
475
+ }
476
+ ];
477
+ };
478
+
479
+ // src/eslintConfigs/regexp.ts
480
+ var regexp = async (options = {}) => {
481
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
482
+ const pluginRegexp = await interopDefault(import("eslint-plugin-regexp"));
483
+ return [
484
+ {
485
+ ignores: commonIgnores,
486
+ name: "regexp/ignores"
487
+ },
488
+ {
489
+ files: [
490
+ GLOB_SRC,
491
+ GLOB_VUE
492
+ ],
493
+ ignores: commonIgnores,
494
+ name: "regexp/custom",
495
+ plugins: {
496
+ regexp: pluginRegexp,
497
+ ...options?.plugins && options.plugins
498
+ },
499
+ rules: {
500
+ ...pluginRegexp.configs["flat/recommended"].rules,
501
+ ...options?.rules && options.rules
502
+ }
503
+ }
504
+ ];
505
+ };
506
+
507
+ // src/eslintConfigs/storybook.ts
508
+ var storybook = async (options = {}) => {
509
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
510
+ const pluginStorybook = await interopDefault(import("eslint-plugin-storybook"));
511
+ return [
512
+ {
513
+ ignores: commonIgnores
514
+ },
515
+ ...pluginStorybook.configs["flat/recommended"],
516
+ {
517
+ files: [GLOB_STORYBOOK],
518
+ ignores: commonIgnores,
519
+ name: "storybook/custom",
520
+ plugins: {
521
+ storybook: pluginStorybook,
522
+ ...options?.plugins && options.plugins
523
+ },
524
+ rules: {
525
+ // add you custom rules here
526
+ ...options?.rules && options.rules
527
+ }
528
+ }
529
+ ];
530
+ };
531
+
532
+ // src/eslintConfigs/stylistic.ts
533
+ var stylistic = async (options = {}) => {
534
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
535
+ const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
536
+ return [
537
+ {
538
+ ignores: commonIgnores,
539
+ name: "stylistic/ignores"
540
+ },
541
+ {
542
+ files: [
543
+ GLOB_SRC,
544
+ GLOB_VUE
545
+ ],
546
+ ignores: commonIgnores,
547
+ name: "stylistic/custom",
548
+ plugins: {
549
+ "@stylistic": pluginStylistic,
550
+ ...options?.plugins && options.plugins
551
+ },
552
+ rules: {
553
+ ...pluginStylistic.configs["recommended-flat"].rules,
554
+ "@stylistic/array-bracket-newline": ["error", "consistent"],
555
+ // enforce consistent space for array values
556
+ "@stylistic/array-bracket-spacing": ["error", "always"],
557
+ "@stylistic/array-element-newline": [
558
+ "error",
559
+ {
560
+ consistent: true,
561
+ multiline: true
562
+ }
563
+ ],
564
+ // enforce consistent use of parentheses in arrow functions
565
+ "@stylistic/arrow-parens": ["error", "always"],
566
+ "@stylistic/arrow-spacing": "error",
567
+ // curly brace styles
568
+ "@stylistic/brace-style": ["error", "1tbs"],
569
+ // enforce consistent use of comma
570
+ "@stylistic/comma-dangle": [
571
+ "error",
572
+ {
573
+ arrays: "always",
574
+ enums: "always",
575
+ exports: "always",
576
+ functions: "never",
577
+ generics: "always",
578
+ imports: "always",
579
+ objects: "always",
580
+ tuples: "always"
581
+ }
582
+ ],
583
+ // enforce consistent non whitespace between the function's name and the parentheses
584
+ "@stylistic/function-call-spacing": ["error", "never"],
585
+ "@stylistic/indent": ["error", 2],
586
+ "@stylistic/indent-binary-ops": ["error", 2],
587
+ "@stylistic/max-len": [
588
+ "error",
589
+ { code: 120 }
590
+ ],
591
+ // enforce consistent statements per line
592
+ "@stylistic/max-statements-per-line": ["error", { max: 2 }],
593
+ "@stylistic/member-delimiter-style": [
594
+ "error",
595
+ {
596
+ multiline: {
597
+ delimiter: "semi",
598
+ requireLast: true
599
+ },
600
+ multilineDetection: "brackets",
601
+ singleline: {
602
+ delimiter: "semi",
603
+ requireLast: true
604
+ }
605
+ }
606
+ ],
607
+ "@stylistic/multiline-ternary": ["error", "always-multiline"],
608
+ // enforce consistent space around operators
609
+ "@stylistic/no-multi-spaces": "error",
610
+ // prevent multiple empty lines
611
+ "@stylistic/no-multiple-empty-lines": [
612
+ "error",
613
+ {
614
+ max: 1,
615
+ maxBOF: 0,
616
+ maxEOF: 0
617
+ }
618
+ ],
619
+ // enforce consistent newline
620
+ "@stylistic/object-curly-newline": [
621
+ "error",
622
+ {
623
+ ExportDeclaration: {
624
+ minProperties: 1,
625
+ multiline: true
626
+ },
627
+ ImportDeclaration: "always",
628
+ ObjectExpression: {
629
+ consistent: true,
630
+ minProperties: 2,
631
+ multiline: true
632
+ },
633
+ ObjectPattern: {
634
+ consistent: true,
635
+ minProperties: 2,
636
+ multiline: true
637
+ }
638
+ }
639
+ ],
640
+ // enforce consistent space for objects
641
+ "@stylistic/object-curly-spacing": ["error", "always"],
642
+ // enforce consistent newline for imports, exports and objects
643
+ "@stylistic/object-property-newline": [
644
+ "error",
645
+ { allowAllPropertiesOnSameLine: true }
646
+ ],
647
+ "@stylistic/padding-line-between-statements": [
648
+ "error",
649
+ {
650
+ blankLine: "always",
651
+ next: "*",
652
+ prev: ["multiline-const"]
653
+ },
654
+ {
655
+ blankLine: "always",
656
+ next: "export",
657
+ prev: "*"
658
+ }
659
+ ],
660
+ "@stylistic/quotes": ["error", "single"],
661
+ "@stylistic/semi": ["error", "always"],
662
+ "@stylistic/space-infix-ops": "error",
663
+ "@stylistic/template-curly-spacing": ["error", "never"],
664
+ ...options?.rules && options.rules
665
+ }
666
+ }
667
+ ];
668
+ };
669
+
670
+ // src/eslintConfigs/tailwindCss.ts
671
+ var tailwindCss = async (options = {}) => {
672
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
673
+ const pluginTailwindCss = await interopDefault(import("eslint-plugin-tailwindcss"));
674
+ return [
675
+ {
676
+ ignores: commonIgnores,
677
+ name: "tailwindcss/ignores"
678
+ },
679
+ ...pluginTailwindCss.configs["flat/recommended"],
680
+ {
681
+ files: [
682
+ GLOB_SRC,
683
+ GLOB_VUE
684
+ ],
685
+ ignores: commonIgnores,
686
+ name: "tailwindcss/custom",
687
+ plugins: {
688
+ tailwindcss: pluginTailwindCss,
689
+ ...options?.plugins && options.plugins
690
+ },
691
+ settings: {
692
+ tailwindcss: {
693
+ config: "tailwind.config.js"
694
+ // returned from `loadConfig()` utility if not provided
695
+ }
696
+ },
697
+ ...options?.rules && { rules: options.rules }
698
+ }
699
+ ];
700
+ };
701
+
702
+ // src/eslintConfigs/testingLibrary.ts
703
+ var testingLibrary = async (options = {}) => {
704
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
705
+ const [pluginTestingLibrary, eslintCompat] = await Promise.all([
706
+ // @ts-expect-error TS7016: Could not find a declaration file for module eslint-plugin-testing-library
707
+ interopDefault(import("eslint-plugin-testing-library")),
708
+ interopDefault(import("@eslint/compat"))
709
+ ]);
710
+ return [
711
+ {
712
+ ignores: commonIgnores,
713
+ name: "testing-library/ignores"
714
+ },
715
+ {
716
+ files: [
717
+ ...GLOBS_TESTS
718
+ ],
719
+ ignores: commonIgnores,
720
+ name: "testing-library/custom",
721
+ plugins: {
722
+ // ref: https://github.com/testing-library/eslint-plugin-testing-library/issues/924
723
+ "testing-library": eslintCompat.fixupPluginRules({
724
+ rules: pluginTestingLibrary.rules
725
+ }),
726
+ ...options?.plugins && options.plugins
727
+ },
728
+ rules: {
729
+ ...pluginTestingLibrary.configs["flat/vue"].rules,
730
+ ...options?.rules && options.rules
731
+ }
732
+ }
733
+ ];
734
+ };
735
+
736
+ // src/eslintConfigs/typescript.ts
737
+ import process2 from "node:process";
738
+ var createLanguageOptions = async (options = {}) => {
739
+ const parserTs = await interopDefault(import("@typescript-eslint/parser"));
740
+ const defaultOptions = {
741
+ parser: parserTs,
742
+ parserOptions: {
743
+ extraFileExtensions: [".vue"],
744
+ projectService: {
745
+ // allowDefaultProject: [ '*.js', '*.ts'],
746
+ defaultProject: "./tsconfig.json"
747
+ },
748
+ sourceType: "module",
749
+ tsconfigRootDir: process2.cwd()
750
+ }
751
+ };
752
+ return {
753
+ ...defaultOptions,
754
+ ...options,
755
+ parserOptions: {
756
+ ...defaultOptions.parserOptions,
757
+ ...options?.parserOptions,
758
+ projectService: {
759
+ ...defaultOptions.parserOptions.projectService,
760
+ ...typeof options?.parserOptions?.projectService === "object" && options?.parserOptions?.projectService
761
+ }
762
+ }
763
+ };
764
+ };
765
+ var typescript = async (options = {}) => {
766
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
767
+ const tsEslint = await interopDefault(import("typescript-eslint"));
768
+ const languageOptions = await createLanguageOptions(options.languageOptions);
769
+ return [
770
+ {
771
+ ignores: commonIgnores,
772
+ name: "typescript-eslint/ignores"
773
+ },
774
+ // ignoring json and markdown files because of different parsers
775
+ ...tsEslint.configs.recommendedTypeChecked.map((config) => ({
776
+ ...config,
777
+ ignores: [
778
+ ...GLOBS_EXCLUDE,
779
+ GLOB_JSON,
780
+ GLOB_JSON5,
781
+ GLOB_JSONC,
782
+ GLOB_MARKDOWN,
783
+ ...options?.ignores ? [...options.ignores] : []
784
+ ]
785
+ })),
786
+ // ignoring json and markdown files because of different parsers
787
+ ...tsEslint.configs.stylisticTypeChecked.map((config) => ({
788
+ ...config,
789
+ ignores: [
790
+ ...GLOBS_EXCLUDE,
791
+ GLOB_JSON,
792
+ GLOB_JSON5,
793
+ GLOB_JSONC,
794
+ GLOB_MARKDOWN,
795
+ ...options?.ignores ? [...options.ignores] : []
796
+ ]
797
+ })),
798
+ // disable typecheck for js and jsx files
799
+ {
800
+ ...tsEslint.configs.disableTypeChecked,
801
+ files: [
802
+ GLOB_JS,
803
+ GLOB_JSX
804
+ ],
805
+ ignores: commonIgnores
806
+ },
807
+ // actual config
808
+ {
809
+ files: [
810
+ GLOB_TS,
811
+ GLOB_TSX,
812
+ GLOB_VUE
813
+ ],
814
+ ignores: commonIgnores,
815
+ languageOptions,
816
+ name: "typescript-eslint/custom",
817
+ plugins: {
818
+ "@typescript-eslint": tsEslint.plugin,
819
+ ...options?.plugins && options.plugins
820
+ },
821
+ rules: {
822
+ "@typescript-eslint/consistent-type-imports": [
823
+ "error",
824
+ {
825
+ disallowTypeAnnotations: false,
826
+ fixStyle: "inline-type-imports",
827
+ prefer: "type-imports"
828
+ }
829
+ ],
830
+ "@typescript-eslint/naming-convention": [
831
+ "error",
832
+ {
833
+ format: ["PascalCase"],
834
+ selector: ["interface", "typeAlias"]
835
+ }
836
+ ],
837
+ "@typescript-eslint/no-unsafe-argument": "off",
838
+ "@typescript-eslint/no-unsafe-assignment": "off",
839
+ "@typescript-eslint/no-unsafe-call": "off",
840
+ "@typescript-eslint/no-unsafe-member-access": "off",
841
+ "@typescript-eslint/no-unsafe-return": "off",
842
+ "@typescript-eslint/no-unused-expressions": ["error", { allowTernary: true }],
843
+ ...options?.rules && options.rules
844
+ }
845
+ }
846
+ ];
847
+ };
848
+
849
+ // src/eslintConfigs/unicorn.ts
850
+ var unicorn = async (options = {}) => {
851
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
852
+ const pluginUnicorn = await interopDefault(import("eslint-plugin-unicorn"));
853
+ return [
854
+ {
855
+ ignores: commonIgnores,
856
+ name: "unicorn/ignores"
857
+ },
858
+ {
859
+ files: [
860
+ GLOB_SRC,
861
+ GLOB_VUE
862
+ ],
863
+ ignores: commonIgnores,
864
+ name: "unicorn/custom",
865
+ plugins: {
866
+ unicorn: pluginUnicorn,
867
+ ...options?.plugins && options.plugins
868
+ },
869
+ rules: {
870
+ ...pluginUnicorn.configs["flat/recommended"].rules,
871
+ "unicorn/filename-case": [
872
+ "error",
873
+ {
874
+ cases: {
875
+ camelCase: true,
876
+ pascalCase: true
877
+ }
878
+ }
879
+ ]
880
+ },
881
+ ...options?.rules && options.rules
882
+ }
883
+ ];
884
+ };
885
+
886
+ // src/eslintConfigs/vitest.ts
887
+ var vitest = async (options = {}) => {
888
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
889
+ const [pluginVitest, pluginImport, pluginUnicorn, tsEslint] = await Promise.all([
890
+ interopDefault(import("@vitest/eslint-plugin")),
891
+ interopDefault(import("eslint-plugin-import-x")),
892
+ interopDefault(import("eslint-plugin-unicorn")),
893
+ interopDefault(import("typescript-eslint"))
894
+ ]);
895
+ return [
896
+ {
897
+ ignores: commonIgnores,
898
+ name: "vitest/ignores"
899
+ },
900
+ {
901
+ files: [
902
+ ...GLOBS_TESTS
903
+ ],
904
+ ignores: commonIgnores,
905
+ name: "vitest/custom",
906
+ plugins: {
907
+ "@typescript-eslint": tsEslint.plugin,
908
+ "import-x": pluginImport,
909
+ "unicorn": pluginUnicorn,
910
+ "vitest": pluginVitest,
911
+ ...options?.plugins && options.plugins
912
+ },
913
+ rules: {
914
+ ...pluginVitest.configs.all.rules,
915
+ ...pluginVitest.configs.recommended.rules,
916
+ // ref: https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/unbound-method.md
917
+ // todo: disable when https://github.com/vitest-dev/eslint-plugin-vitest/issues/482 is done
918
+ "@typescript-eslint/unbound-method": "off",
919
+ "import-x/no-extraneous-dependencies": [
920
+ "error",
921
+ {
922
+ devDependencies: [...GLOBS_TESTS, ...GLOBS_TESTS_E2E],
923
+ optionalDependencies: false,
924
+ peerDependencies: false
925
+ }
926
+ ],
927
+ "vitest/consistent-test-filename": [
928
+ "error",
929
+ { pattern: String.raw`.*\.spec\.[tj]sx?$` }
930
+ ],
931
+ "vitest/max-expects": ["error", { max: 12 }],
932
+ "vitest/no-hooks": "off",
933
+ ...options?.rules && options.rules
934
+ }
935
+ }
936
+ ];
937
+ };
938
+
939
+ // src/eslintConfigs/vue.ts
940
+ var vue = async (options = {}) => {
941
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
942
+ const [pluginImport, pluginUnicorn, pluginVue, parserVue, tsEslint] = await Promise.all([
943
+ interopDefault(import("eslint-plugin-import-x")),
944
+ interopDefault(import("eslint-plugin-unicorn")),
945
+ interopDefault(import("eslint-plugin-vue")),
946
+ interopDefault(import("vue-eslint-parser")),
947
+ interopDefault(import("typescript-eslint"))
948
+ ]);
949
+ return [
950
+ {
951
+ ignores: commonIgnores,
952
+ name: "vue/ignores"
953
+ },
954
+ ...pluginVue.configs["flat/recommended"],
955
+ {
956
+ files: [
957
+ GLOB_VUE
958
+ ],
959
+ ignores: commonIgnores,
960
+ languageOptions: {
961
+ parser: parserVue,
962
+ parserOptions: {
963
+ extraFileExtensions: [".vue"],
964
+ parser: tsEslint.parser,
965
+ sourceType: "module"
966
+ }
967
+ },
968
+ name: "vue/custom",
969
+ plugins: {
970
+ "@typescript-eslint": tsEslint.plugin,
971
+ "import-x": pluginImport,
972
+ "unicorn": pluginUnicorn,
973
+ "vue": pluginVue,
974
+ ...options?.plugins && options.plugins
975
+ },
976
+ rules: {
977
+ "@typescript-eslint/no-unused-expressions": [
978
+ "error",
979
+ { allowTernary: true }
980
+ ],
981
+ // ref: https://github.com/un-ts/eslint-plugin-import-x/issues/90
982
+ "@typescript-eslint/no-unused-vars": [
983
+ "error",
984
+ {
985
+ args: "after-used",
986
+ ignoreRestSiblings: false,
987
+ vars: "all"
988
+ }
989
+ ],
990
+ // use PascalCase for vue-components because its recommended
991
+ "unicorn/filename-case": [
992
+ "error",
993
+ {
994
+ cases: {
995
+ pascalCase: true
996
+ }
997
+ }
998
+ ],
999
+ // play nicely with vue and allow abbreviation `props`
1000
+ // see rule vue/require-macro-variable-name
1001
+ "unicorn/prevent-abbreviations": [
1002
+ "error",
1003
+ {
1004
+ allowList: {
1005
+ // ref: https://eslint.vuejs.org/rules/require-macro-variable-name.html#vue-require-macro-variable-name
1006
+ props: true
1007
+ }
1008
+ }
1009
+ ],
1010
+ "vue/array-bracket-newline": ["error", "consistent"],
1011
+ "vue/array-bracket-spacing": ["error", "always"],
1012
+ "vue/array-element-newline": [
1013
+ "error",
1014
+ {
1015
+ consistent: true,
1016
+ multiline: true
1017
+ }
1018
+ ],
1019
+ "vue/arrow-spacing": "error",
1020
+ "vue/attribute-hyphenation": [
1021
+ "error",
1022
+ "always",
1023
+ {
1024
+ ignore: []
1025
+ }
1026
+ ],
1027
+ "vue/attributes-order": [
1028
+ "error",
1029
+ {
1030
+ alphabetical: false,
1031
+ order: [
1032
+ "DEFINITION",
1033
+ "LIST_RENDERING",
1034
+ "CONDITIONALS",
1035
+ "RENDER_MODIFIERS",
1036
+ "GLOBAL",
1037
+ ["UNIQUE", "SLOT"],
1038
+ "TWO_WAY_BINDING",
1039
+ "OTHER_DIRECTIVES",
1040
+ "OTHER_ATTR",
1041
+ "EVENTS",
1042
+ "CONTENT"
1043
+ ]
1044
+ }
1045
+ ],
1046
+ "vue/block-lang": ["error", { script: { lang: "ts" } }],
1047
+ "vue/block-order": [
1048
+ "error",
1049
+ {
1050
+ order: [
1051
+ "template",
1052
+ "script:not([setup])",
1053
+ "script[setup]",
1054
+ "i18n",
1055
+ "style"
1056
+ ]
1057
+ }
1058
+ ],
1059
+ "vue/brace-style": ["error", "1tbs"],
1060
+ "vue/component-api-style": ["error", ["script-setup"]],
1061
+ "vue/component-name-in-template-casing": [
1062
+ "error",
1063
+ "kebab-case",
1064
+ {
1065
+ globals: [
1066
+ "RouterLink",
1067
+ "RouterView"
1068
+ ],
1069
+ ignores: [],
1070
+ registeredComponentsOnly: true
1071
+ }
1072
+ ],
1073
+ "vue/custom-event-name-casing": "error",
1074
+ "vue/define-emits-declaration": ["error", "type-based"],
1075
+ "vue/define-macros-order": [
1076
+ "error",
1077
+ {
1078
+ defineExposeLast: true,
1079
+ order: [
1080
+ "defineOptions",
1081
+ "defineProps",
1082
+ "defineEmits",
1083
+ "defineSlots",
1084
+ "defineModel"
1085
+ ]
1086
+ }
1087
+ ],
1088
+ "vue/define-props-declaration": "error",
1089
+ "vue/func-call-spacing": ["error", "never"],
1090
+ "vue/html-button-has-type": "error",
1091
+ "vue/html-comment-content-spacing": [
1092
+ "error",
1093
+ "always",
1094
+ { exceptions: [] }
1095
+ ],
1096
+ "vue/multiline-ternary": ["error", "always-multiline"],
1097
+ "vue/no-multiple-objects-in-class": "warn",
1098
+ "vue/no-root-v-if": "error",
1099
+ "vue/no-template-target-blank": "error",
1100
+ "vue/no-undef-components": [
1101
+ "error",
1102
+ {
1103
+ ignorePatterns: [
1104
+ // ref: https://router.vuejs.org/guide/#Registering-the-router-plugin
1105
+ "RouterLink",
1106
+ "RouterView"
1107
+ ]
1108
+ }
1109
+ ],
1110
+ "vue/no-undef-properties": "error",
1111
+ "vue/no-unused-refs": "error",
1112
+ "vue/no-use-v-else-with-v-for": "error",
1113
+ "vue/no-useless-mustaches": "error",
1114
+ "vue/no-useless-v-bind": "error",
1115
+ "vue/no-v-html": "error",
1116
+ "vue/no-v-text": "error",
1117
+ "vue/object-curly-spacing": ["error", "always"],
1118
+ "vue/padding-line-between-blocks": "error",
1119
+ "vue/prefer-define-options": "error",
1120
+ "vue/prefer-separate-static-class": "error",
1121
+ "vue/prefer-template": "error",
1122
+ "vue/prefer-true-attribute-shorthand": ["error", "always"],
1123
+ // set to vue recommended defaults
1124
+ "vue/require-macro-variable-name": [
1125
+ "error",
1126
+ {
1127
+ defineEmits: "emit",
1128
+ defineProps: "props",
1129
+ defineSlots: "slots",
1130
+ useAttrs: "attrs",
1131
+ useSlots: "slots"
1132
+ }
1133
+ ],
1134
+ "vue/require-typed-ref": "error",
1135
+ "vue/space-infix-ops": ["error", { int32Hint: false }],
1136
+ "vue/template-curly-spacing": ["error", "never"],
1137
+ "vue/v-for-delimiter-style": ["error", "in"],
1138
+ "vue/v-on-event-hyphenation": [
1139
+ "error",
1140
+ "always",
1141
+ {
1142
+ autofix: true,
1143
+ ignore: []
1144
+ }
1145
+ ],
1146
+ "vue/valid-define-options": "error",
1147
+ ...options?.rules && options.rules
1148
+ }
1149
+ }
1150
+ ];
1151
+ };
1152
+
1153
+ // src/eslintConfigs/vueAccessibility.ts
1154
+ var vueAccessibility = async (options = {}) => {
1155
+ const commonIgnores = [...GLOBS_EXCLUDE, ...options.ignores ?? []];
1156
+ const pluginVueA11y = await interopDefault(import("eslint-plugin-vuejs-accessibility"));
1157
+ return [
1158
+ {
1159
+ ignores: commonIgnores,
1160
+ name: "vuejs-accessibility/ignores"
1161
+ },
1162
+ ...pluginVueA11y.configs["flat/recommended"],
1163
+ {
1164
+ files: [
1165
+ GLOB_VUE
1166
+ ],
1167
+ ignores: commonIgnores,
1168
+ name: "vuejs-accessibility/custom",
1169
+ plugins: {
1170
+ vueAccessibility: pluginVueA11y,
1171
+ ...options?.plugins && options.plugins
1172
+ },
1173
+ ...options?.rules && { rules: options.rules }
1174
+ }
1175
+ ];
1176
+ };
1177
+ export {
1178
+ GLOBS_EXCLUDE,
1179
+ GLOBS_TESTS,
1180
+ GLOBS_TESTS_E2E,
1181
+ GLOB_CSS,
1182
+ GLOB_HTML,
1183
+ GLOB_JS,
1184
+ GLOB_JSON,
1185
+ GLOB_JSON5,
1186
+ GLOB_JSONC,
1187
+ GLOB_JSX,
1188
+ GLOB_LESS,
1189
+ GLOB_MARKDOWN,
1190
+ GLOB_POSTCSS,
1191
+ GLOB_SCSS,
1192
+ GLOB_SRC,
1193
+ GLOB_SRC_EXT,
1194
+ GLOB_STORYBOOK,
1195
+ GLOB_STYLE,
1196
+ GLOB_TS,
1197
+ GLOB_TSX,
1198
+ GLOB_VUE,
1199
+ combine,
1200
+ defaults,
1201
+ importX,
1202
+ jsdoc,
1203
+ jsonc,
1204
+ perfectionist,
1205
+ playwright,
1206
+ regexp,
1207
+ storybook,
1208
+ stylistic,
1209
+ tailwindCss,
1210
+ testingLibrary,
1211
+ typescript,
1212
+ unicorn,
1213
+ vitest,
1214
+ vue,
1215
+ vueAccessibility
1216
+ };