@2030/eslint-config 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js DELETED
@@ -1,2641 +0,0 @@
1
- // src/factory.ts
2
- import { FlatConfigComposer } from "eslint-flat-config-utils";
3
- import { isPackageExists as isPackageExists4 } from "local-pkg";
4
-
5
- // src/globs.ts
6
- var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
7
- var GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
8
- var GLOB_JS = "**/*.?([cm])js";
9
- var GLOB_JSX = "**/*.?([cm])jsx";
10
- var GLOB_TS = "**/*.?([cm])ts";
11
- var GLOB_TSX = "**/*.?([cm])tsx";
12
- var GLOB_STYLE = "**/*.{c,le,sc}ss";
13
- var GLOB_CSS = "**/*.css";
14
- var GLOB_POSTCSS = "**/*.{p,post}css";
15
- var GLOB_LESS = "**/*.less";
16
- var GLOB_SCSS = "**/*.scss";
17
- var GLOB_JSON = "**/*.json";
18
- var GLOB_JSON5 = "**/*.json5";
19
- var GLOB_JSONC = "**/*.jsonc";
20
- var GLOB_MARKDOWN = "**/*.md";
21
- var GLOB_MARKDOWN_IN_MARKDOWN = "**/*.md/*.md";
22
- var GLOB_SVELTE = "**/*.svelte";
23
- var GLOB_VUE = "**/*.vue";
24
- var GLOB_YAML = "**/*.y?(a)ml";
25
- var GLOB_TOML = "**/*.toml";
26
- var GLOB_XML = "**/*.xml";
27
- var GLOB_SVG = "**/*.svg";
28
- var GLOB_HTML = "**/*.htm?(l)";
29
- var GLOB_ASTRO = "**/*.astro";
30
- var GLOB_ASTRO_TS = "**/*.astro/*.ts";
31
- var GLOB_GRAPHQL = "**/*.{g,graph}ql";
32
- var GLOB_MARKDOWN_CODE = `${GLOB_MARKDOWN}/${GLOB_SRC}`;
33
- var GLOB_TESTS = [
34
- `**/__tests__/**/*.${GLOB_SRC_EXT}`,
35
- `**/*.spec.${GLOB_SRC_EXT}`,
36
- `**/*.test.${GLOB_SRC_EXT}`,
37
- `**/*.bench.${GLOB_SRC_EXT}`,
38
- `**/*.benchmark.${GLOB_SRC_EXT}`
39
- ];
40
- var GLOB_ALL_SRC = [
41
- GLOB_SRC,
42
- GLOB_STYLE,
43
- GLOB_JSON,
44
- GLOB_JSON5,
45
- GLOB_MARKDOWN,
46
- GLOB_SVELTE,
47
- GLOB_VUE,
48
- GLOB_YAML,
49
- GLOB_XML,
50
- GLOB_HTML
51
- ];
52
- var GLOB_EXCLUDE = [
53
- "**/node_modules",
54
- "**/dist",
55
- "**/package-lock.json",
56
- "**/yarn.lock",
57
- "**/pnpm-lock.yaml",
58
- "**/bun.lockb",
59
- "**/output",
60
- "**/coverage",
61
- "**/temp",
62
- "**/.temp",
63
- "**/tmp",
64
- "**/.tmp",
65
- "**/.history",
66
- "**/.vitepress/cache",
67
- "**/.nuxt",
68
- "**/.next",
69
- "**/.svelte-kit",
70
- "**/.vercel",
71
- "**/.changeset",
72
- "**/.idea",
73
- "**/.cache",
74
- "**/.output",
75
- "**/.vite-inspect",
76
- "**/.yarn",
77
- "**/vite.config.*.timestamp-*",
78
- "**/CHANGELOG*.md",
79
- "**/*.min.*",
80
- "**/LICENSE*",
81
- "**/__snapshots__",
82
- "**/auto-import?(s).d.ts",
83
- "**/components.d.ts"
84
- ];
85
-
86
- // src/utils.ts
87
- import process from "node:process";
88
- import { fileURLToPath } from "node:url";
89
- import { isPackageExists } from "local-pkg";
90
- var scopeUrl = fileURLToPath(new URL(".", import.meta.url));
91
- var isCwdInScope = isPackageExists("@jun2030/eslint-config");
92
- var parserPlain = {
93
- meta: {
94
- name: "parser-plain"
95
- },
96
- parseForESLint: (code) => ({
97
- ast: {
98
- body: [],
99
- comments: [],
100
- loc: { end: code.length, start: 0 },
101
- range: [0, code.length],
102
- tokens: [],
103
- type: "Program"
104
- },
105
- scopeManager: null,
106
- services: { isPlain: true },
107
- visitorKeys: {
108
- Program: []
109
- }
110
- })
111
- };
112
- async function combine(...configs2) {
113
- const resolved = await Promise.all(configs2);
114
- return resolved.flat();
115
- }
116
- function renameRules(rules, map) {
117
- return Object.fromEntries(
118
- Object.entries(rules).map(([key, value]) => {
119
- for (const [from, to] of Object.entries(map)) {
120
- if (key.startsWith(`${from}/`))
121
- return [to + key.slice(from.length), value];
122
- }
123
- return [key, value];
124
- })
125
- );
126
- }
127
- function renamePluginInConfigs(configs2, map) {
128
- return configs2.map((i) => {
129
- const clone = { ...i };
130
- if (clone.rules)
131
- clone.rules = renameRules(clone.rules, map);
132
- if (clone.plugins) {
133
- clone.plugins = Object.fromEntries(
134
- Object.entries(clone.plugins).map(([key, value]) => {
135
- if (key in map)
136
- return [map[key], value];
137
- return [key, value];
138
- })
139
- );
140
- }
141
- return clone;
142
- });
143
- }
144
- function toArray(value) {
145
- return Array.isArray(value) ? value : [value];
146
- }
147
- async function interopDefault(m) {
148
- const resolved = await m;
149
- return resolved.default || resolved;
150
- }
151
- function isPackageInScope(name) {
152
- return isPackageExists(name, { paths: [scopeUrl] });
153
- }
154
- async function ensurePackages(packages) {
155
- if (process.env.CI || process.stdout.isTTY === false || isCwdInScope === false)
156
- return;
157
- const nonExistingPackages = packages.filter((i) => i && !isPackageInScope(i));
158
- if (nonExistingPackages.length === 0)
159
- return;
160
- const p = await import("@clack/prompts");
161
- const result = await p.confirm({
162
- message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`
163
- });
164
- if (result)
165
- await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
166
- }
167
- function isInEditorEnv() {
168
- if (process.env.CI)
169
- return false;
170
- if (isInGitHooksOrLintStaged())
171
- return false;
172
- return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM);
173
- }
174
- function isInGitHooksOrLintStaged() {
175
- return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged"));
176
- }
177
-
178
- // src/configs/astro.ts
179
- async function astro(options = {}) {
180
- const {
181
- files = [GLOB_ASTRO],
182
- overrides = {},
183
- stylistic: stylistic2 = true
184
- } = options;
185
- const [
186
- pluginAstro,
187
- parserAstro,
188
- parserTs
189
- ] = await Promise.all([
190
- interopDefault(import("eslint-plugin-astro")),
191
- interopDefault(import("astro-eslint-parser")),
192
- interopDefault(import("@typescript-eslint/parser"))
193
- ]);
194
- return [
195
- {
196
- name: "jun/astro/setup",
197
- plugins: {
198
- astro: pluginAstro
199
- }
200
- },
201
- {
202
- files,
203
- languageOptions: {
204
- globals: pluginAstro.environments.astro.globals,
205
- parser: parserAstro,
206
- parserOptions: {
207
- extraFileExtensions: [".astro"],
208
- parser: parserTs
209
- },
210
- sourceType: "module"
211
- },
212
- name: "jun/astro/rules",
213
- processor: "astro/client-side-ts",
214
- rules: {
215
- // use recommended rules
216
- "astro/missing-client-only-directive-value": "error",
217
- "astro/no-conflict-set-directives": "error",
218
- "astro/no-deprecated-astro-canonicalurl": "error",
219
- "astro/no-deprecated-astro-fetchcontent": "error",
220
- "astro/no-deprecated-astro-resolve": "error",
221
- "astro/no-deprecated-getentrybyslug": "error",
222
- "astro/no-set-html-directive": "off",
223
- "astro/no-unused-define-vars-in-style": "error",
224
- "astro/semi": "off",
225
- "astro/valid-compile": "error",
226
- ...stylistic2 ? {
227
- "style/indent": "off",
228
- "style/jsx-closing-tag-location": "off",
229
- "style/jsx-one-expression-per-line": "off",
230
- "style/no-multiple-empty-lines": "off"
231
- } : {},
232
- ...overrides
233
- }
234
- }
235
- ];
236
- }
237
-
238
- // src/configs/command.ts
239
- import createCommand from "eslint-plugin-command/config";
240
- async function command() {
241
- return [
242
- {
243
- ...createCommand(),
244
- name: "jun/command/rules"
245
- }
246
- ];
247
- }
248
-
249
- // src/plugins.ts
250
- import { default as default2 } from "@eslint-community/eslint-plugin-eslint-comments";
251
- import { default as default3 } from "eslint-plugin-antfu";
252
- import * as pluginImport from "eslint-plugin-import-x";
253
- import { default as default4 } from "eslint-plugin-n";
254
- import { default as default5 } from "eslint-plugin-perfectionist";
255
- import { default as default6 } from "eslint-plugin-unicorn";
256
- import { default as default7 } from "eslint-plugin-unused-imports";
257
-
258
- // src/configs/comments.ts
259
- async function comments() {
260
- return [
261
- {
262
- name: "jun/eslint-comments/rules",
263
- plugins: {
264
- "eslint-comments": default2
265
- },
266
- rules: {
267
- "eslint-comments/no-aggregating-enable": "error",
268
- "eslint-comments/no-duplicate-disable": "error",
269
- "eslint-comments/no-unlimited-disable": "error",
270
- "eslint-comments/no-unused-enable": "error"
271
- }
272
- }
273
- ];
274
- }
275
-
276
- // src/configs/disables.ts
277
- async function disables() {
278
- return [
279
- {
280
- files: [`**/scripts/${GLOB_SRC}`],
281
- name: "jun/disables/scripts",
282
- rules: {
283
- "jun/no-top-level-await": "off",
284
- "no-console": "off",
285
- "ts/explicit-function-return-type": "off"
286
- }
287
- },
288
- {
289
- files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
290
- name: "jun/disables/cli",
291
- rules: {
292
- "jun/no-top-level-await": "off",
293
- "no-console": "off"
294
- }
295
- },
296
- {
297
- files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
298
- name: "jun/disables/bin",
299
- rules: {
300
- "jun/no-import-dist": "off",
301
- "jun/no-import-node-modules-by-path": "off"
302
- }
303
- },
304
- {
305
- files: ["**/*.d.?([cm])ts"],
306
- name: "jun/disables/dts",
307
- rules: {
308
- "eslint-comments/no-unlimited-disable": "off",
309
- "import/no-duplicates": "off",
310
- "no-restricted-syntax": "off",
311
- "unused-imports/no-unused-vars": "off"
312
- }
313
- },
314
- {
315
- files: ["**/*.js", "**/*.cjs"],
316
- name: "jun/disables/cjs",
317
- rules: {
318
- "ts/no-require-imports": "off"
319
- }
320
- },
321
- {
322
- files: [`**/*.config.${GLOB_SRC_EXT}`, `**/*.config.*.${GLOB_SRC_EXT}`],
323
- name: "jun/disables/config-files",
324
- rules: {
325
- "jun/no-top-level-await": "off",
326
- "no-console": "off",
327
- "ts/explicit-function-return-type": "off"
328
- }
329
- }
330
- ];
331
- }
332
-
333
- // src/configs/formatters.ts
334
- import { isPackageExists as isPackageExists2 } from "local-pkg";
335
-
336
- // src/configs/stylistic.ts
337
- var StylisticConfigDefaults = {
338
- indent: 2,
339
- jsx: true,
340
- quotes: "single",
341
- semi: false
342
- };
343
- async function stylistic(options = {}) {
344
- const {
345
- indent,
346
- jsx: jsx2,
347
- lessOpinionated = false,
348
- overrides = {},
349
- quotes,
350
- semi
351
- } = {
352
- ...StylisticConfigDefaults,
353
- ...options
354
- };
355
- const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
356
- const config = pluginStylistic.configs.customize({
357
- flat: true,
358
- indent,
359
- jsx: jsx2,
360
- pluginName: "style",
361
- quotes,
362
- semi
363
- });
364
- return [
365
- {
366
- name: "jun/stylistic/rules",
367
- plugins: {
368
- jun: default3,
369
- style: pluginStylistic
370
- },
371
- rules: {
372
- ...config.rules,
373
- "jun/consistent-chaining": "error",
374
- "jun/consistent-list-newline": "error",
375
- ...lessOpinionated ? {
376
- curly: ["error", "all"]
377
- } : {
378
- "jun/curly": "error",
379
- "jun/if-newline": "error",
380
- "jun/top-level-function": "error"
381
- },
382
- ...overrides
383
- }
384
- }
385
- ];
386
- }
387
-
388
- // src/configs/formatters.ts
389
- function mergePrettierOptions(options, overrides = {}) {
390
- return {
391
- ...options,
392
- ...overrides,
393
- plugins: [
394
- ...overrides.plugins || [],
395
- ...options.plugins || []
396
- ]
397
- };
398
- }
399
- async function formatters(options = {}, stylistic2 = {}) {
400
- if (options === true) {
401
- const isPrettierPluginXmlInScope = isPackageInScope("@prettier/plugin-xml");
402
- options = {
403
- astro: isPackageInScope("prettier-plugin-astro"),
404
- css: true,
405
- graphql: true,
406
- html: true,
407
- markdown: true,
408
- slidev: isPackageExists2("@slidev/cli"),
409
- svg: isPrettierPluginXmlInScope,
410
- xml: isPrettierPluginXmlInScope
411
- };
412
- }
413
- await ensurePackages([
414
- "eslint-plugin-format",
415
- options.markdown && options.slidev ? "prettier-plugin-slidev" : void 0,
416
- options.astro ? "prettier-plugin-astro" : void 0,
417
- options.xml || options.svg ? "@prettier/plugin-xml" : void 0
418
- ]);
419
- if (options.slidev && options.markdown !== true && options.markdown !== "prettier")
420
- throw new Error("`slidev` option only works when `markdown` is enabled with `prettier`");
421
- const {
422
- indent,
423
- quotes,
424
- semi
425
- } = {
426
- ...StylisticConfigDefaults,
427
- ...stylistic2
428
- };
429
- const prettierOptions = Object.assign(
430
- {
431
- endOfLine: "auto",
432
- printWidth: 120,
433
- semi,
434
- singleQuote: quotes === "single",
435
- tabWidth: typeof indent === "number" ? indent : 2,
436
- trailingComma: "all",
437
- useTabs: indent === "tab"
438
- },
439
- options.prettierOptions || {}
440
- );
441
- const prettierXmlOptions = {
442
- xmlQuoteAttributes: "double",
443
- xmlSelfClosingSpace: true,
444
- xmlSortAttributesByKey: false,
445
- xmlWhitespaceSensitivity: "ignore"
446
- };
447
- const dprintOptions = Object.assign(
448
- {
449
- indentWidth: typeof indent === "number" ? indent : 2,
450
- quoteStyle: quotes === "single" ? "preferSingle" : "preferDouble",
451
- useTabs: indent === "tab"
452
- },
453
- options.dprintOptions || {}
454
- );
455
- const pluginFormat = await interopDefault(import("eslint-plugin-format"));
456
- const configs2 = [
457
- {
458
- name: "jun/formatter/setup",
459
- plugins: {
460
- format: pluginFormat
461
- }
462
- }
463
- ];
464
- if (options.css) {
465
- configs2.push(
466
- {
467
- files: [GLOB_CSS, GLOB_POSTCSS],
468
- languageOptions: {
469
- parser: parserPlain
470
- },
471
- name: "jun/formatter/css",
472
- rules: {
473
- "format/prettier": [
474
- "error",
475
- mergePrettierOptions(prettierOptions, {
476
- parser: "css"
477
- })
478
- ]
479
- }
480
- },
481
- {
482
- files: [GLOB_SCSS],
483
- languageOptions: {
484
- parser: parserPlain
485
- },
486
- name: "jun/formatter/scss",
487
- rules: {
488
- "format/prettier": [
489
- "error",
490
- mergePrettierOptions(prettierOptions, {
491
- parser: "scss"
492
- })
493
- ]
494
- }
495
- },
496
- {
497
- files: [GLOB_LESS],
498
- languageOptions: {
499
- parser: parserPlain
500
- },
501
- name: "jun/formatter/less",
502
- rules: {
503
- "format/prettier": [
504
- "error",
505
- mergePrettierOptions(prettierOptions, {
506
- parser: "less"
507
- })
508
- ]
509
- }
510
- }
511
- );
512
- }
513
- if (options.html) {
514
- configs2.push({
515
- files: [GLOB_HTML],
516
- languageOptions: {
517
- parser: parserPlain
518
- },
519
- name: "jun/formatter/html",
520
- rules: {
521
- "format/prettier": [
522
- "error",
523
- mergePrettierOptions(prettierOptions, {
524
- parser: "html"
525
- })
526
- ]
527
- }
528
- });
529
- }
530
- if (options.xml) {
531
- configs2.push({
532
- files: [GLOB_XML],
533
- languageOptions: {
534
- parser: parserPlain
535
- },
536
- name: "jun/formatter/xml",
537
- rules: {
538
- "format/prettier": [
539
- "error",
540
- mergePrettierOptions({ ...prettierXmlOptions, ...prettierOptions }, {
541
- parser: "xml",
542
- plugins: [
543
- "@prettier/plugin-xml"
544
- ]
545
- })
546
- ]
547
- }
548
- });
549
- }
550
- if (options.svg) {
551
- configs2.push({
552
- files: [GLOB_SVG],
553
- languageOptions: {
554
- parser: parserPlain
555
- },
556
- name: "jun/formatter/svg",
557
- rules: {
558
- "format/prettier": [
559
- "error",
560
- mergePrettierOptions({ ...prettierXmlOptions, ...prettierOptions }, {
561
- parser: "xml",
562
- plugins: [
563
- "@prettier/plugin-xml"
564
- ]
565
- })
566
- ]
567
- }
568
- });
569
- }
570
- if (options.markdown) {
571
- const formater = options.markdown === true ? "prettier" : options.markdown;
572
- const GLOB_SLIDEV = !options.slidev ? [] : options.slidev === true ? ["**/slides.md"] : options.slidev.files;
573
- configs2.push({
574
- files: [GLOB_MARKDOWN],
575
- ignores: GLOB_SLIDEV,
576
- languageOptions: {
577
- parser: parserPlain
578
- },
579
- name: "jun/formatter/markdown",
580
- rules: {
581
- [`format/${formater}`]: [
582
- "error",
583
- formater === "prettier" ? mergePrettierOptions(prettierOptions, {
584
- embeddedLanguageFormatting: "off",
585
- parser: "markdown"
586
- }) : {
587
- ...dprintOptions,
588
- language: "markdown"
589
- }
590
- ]
591
- }
592
- });
593
- if (options.slidev) {
594
- configs2.push({
595
- files: GLOB_SLIDEV,
596
- languageOptions: {
597
- parser: parserPlain
598
- },
599
- name: "jun/formatter/slidev",
600
- rules: {
601
- "format/prettier": [
602
- "error",
603
- mergePrettierOptions(prettierOptions, {
604
- embeddedLanguageFormatting: "off",
605
- parser: "slidev",
606
- plugins: [
607
- "prettier-plugin-slidev"
608
- ]
609
- })
610
- ]
611
- }
612
- });
613
- }
614
- }
615
- if (options.astro) {
616
- configs2.push({
617
- files: [GLOB_ASTRO],
618
- languageOptions: {
619
- parser: parserPlain
620
- },
621
- name: "jun/formatter/astro",
622
- rules: {
623
- "format/prettier": [
624
- "error",
625
- mergePrettierOptions(prettierOptions, {
626
- parser: "astro",
627
- plugins: [
628
- "prettier-plugin-astro"
629
- ]
630
- })
631
- ]
632
- }
633
- });
634
- configs2.push({
635
- files: [GLOB_ASTRO, GLOB_ASTRO_TS],
636
- name: "jun/formatter/astro/disables",
637
- rules: {
638
- "style/arrow-parens": "off",
639
- "style/block-spacing": "off",
640
- "style/comma-dangle": "off",
641
- "style/indent": "off",
642
- "style/no-multi-spaces": "off",
643
- "style/quotes": "off",
644
- "style/semi": "off"
645
- }
646
- });
647
- }
648
- if (options.graphql) {
649
- configs2.push({
650
- files: [GLOB_GRAPHQL],
651
- languageOptions: {
652
- parser: parserPlain
653
- },
654
- name: "jun/formatter/graphql",
655
- rules: {
656
- "format/prettier": [
657
- "error",
658
- mergePrettierOptions(prettierOptions, {
659
- parser: "graphql"
660
- })
661
- ]
662
- }
663
- });
664
- }
665
- return configs2;
666
- }
667
-
668
- // src/configs/ignores.ts
669
- async function ignores(userIgnores = []) {
670
- return [
671
- {
672
- ignores: [
673
- ...GLOB_EXCLUDE,
674
- ...userIgnores
675
- ],
676
- name: "jun/ignores"
677
- }
678
- ];
679
- }
680
-
681
- // src/configs/imports.ts
682
- async function imports(options = {}) {
683
- const {
684
- stylistic: stylistic2 = true
685
- } = options;
686
- return [
687
- {
688
- name: "jun/imports/rules",
689
- plugins: {
690
- import: pluginImport,
691
- jun: default3
692
- },
693
- rules: {
694
- "import/first": "error",
695
- "import/no-duplicates": "error",
696
- "import/no-mutable-exports": "error",
697
- "import/no-named-default": "error",
698
- "import/no-self-import": "error",
699
- "import/no-webpack-loader-syntax": "error",
700
- "jun/import-dedupe": "error",
701
- "jun/no-import-dist": "error",
702
- "jun/no-import-node-modules-by-path": "error",
703
- ...stylistic2 ? {
704
- "import/newline-after-import": ["error", { count: 1 }]
705
- } : {}
706
- }
707
- }
708
- ];
709
- }
710
-
711
- // src/configs/javascript.ts
712
- import globals from "globals";
713
- async function javascript(options = {}) {
714
- const {
715
- isInEditor = false,
716
- overrides = {}
717
- } = options;
718
- return [
719
- {
720
- languageOptions: {
721
- ecmaVersion: 2022,
722
- globals: {
723
- ...globals.browser,
724
- ...globals.es2021,
725
- ...globals.node,
726
- document: "readonly",
727
- navigator: "readonly",
728
- window: "readonly"
729
- },
730
- parserOptions: {
731
- ecmaFeatures: {
732
- jsx: true
733
- },
734
- ecmaVersion: 2022,
735
- sourceType: "module"
736
- },
737
- sourceType: "module"
738
- },
739
- linterOptions: {
740
- reportUnusedDisableDirectives: true
741
- },
742
- name: "jun/javascript/setup"
743
- },
744
- {
745
- name: "jun/javascript/rules",
746
- plugins: {
747
- "jun": default3,
748
- "unused-imports": default7
749
- },
750
- rules: {
751
- "accessor-pairs": ["error", { enforceForClassMembers: true, setWithoutGet: true }],
752
- "array-callback-return": "error",
753
- "block-scoped-var": "error",
754
- "constructor-super": "error",
755
- "default-case-last": "error",
756
- "dot-notation": ["error", { allowKeywords: true }],
757
- "eqeqeq": ["error", "smart"],
758
- "jun/no-top-level-await": "error",
759
- "new-cap": ["error", { capIsNew: false, newIsCap: true, properties: true }],
760
- "no-alert": "error",
761
- "no-array-constructor": "error",
762
- "no-async-promise-executor": "error",
763
- "no-caller": "error",
764
- "no-case-declarations": "error",
765
- "no-class-assign": "error",
766
- "no-compare-neg-zero": "error",
767
- "no-cond-assign": ["error", "always"],
768
- "no-console": ["error", { allow: ["warn", "error"] }],
769
- "no-const-assign": "error",
770
- "no-control-regex": "error",
771
- "no-debugger": "error",
772
- "no-delete-var": "error",
773
- "no-dupe-args": "error",
774
- "no-dupe-class-members": "error",
775
- "no-dupe-keys": "error",
776
- "no-duplicate-case": "error",
777
- "no-empty": ["error", { allowEmptyCatch: true }],
778
- "no-empty-character-class": "error",
779
- "no-empty-pattern": "error",
780
- "no-eval": "error",
781
- "no-ex-assign": "error",
782
- "no-extend-native": "error",
783
- "no-extra-bind": "error",
784
- "no-extra-boolean-cast": "error",
785
- "no-fallthrough": "error",
786
- "no-func-assign": "error",
787
- "no-global-assign": "error",
788
- "no-implied-eval": "error",
789
- "no-import-assign": "error",
790
- "no-invalid-regexp": "error",
791
- "no-irregular-whitespace": "error",
792
- "no-iterator": "error",
793
- "no-labels": ["error", { allowLoop: false, allowSwitch: false }],
794
- "no-lone-blocks": "error",
795
- "no-loss-of-precision": "error",
796
- "no-misleading-character-class": "error",
797
- "no-multi-str": "error",
798
- "no-new": "error",
799
- "no-new-func": "error",
800
- "no-new-native-nonconstructor": "error",
801
- "no-new-wrappers": "error",
802
- "no-obj-calls": "error",
803
- "no-octal": "error",
804
- "no-octal-escape": "error",
805
- "no-proto": "error",
806
- "no-prototype-builtins": "error",
807
- "no-redeclare": ["error", { builtinGlobals: false }],
808
- "no-regex-spaces": "error",
809
- "no-restricted-globals": [
810
- "error",
811
- { message: "Use `globalThis` instead.", name: "global" },
812
- { message: "Use `globalThis` instead.", name: "self" }
813
- ],
814
- "no-restricted-properties": [
815
- "error",
816
- { message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.", property: "__proto__" },
817
- { message: "Use `Object.defineProperty` instead.", property: "__defineGetter__" },
818
- { message: "Use `Object.defineProperty` instead.", property: "__defineSetter__" },
819
- { message: "Use `Object.getOwnPropertyDescriptor` instead.", property: "__lookupGetter__" },
820
- { message: "Use `Object.getOwnPropertyDescriptor` instead.", property: "__lookupSetter__" }
821
- ],
822
- "no-restricted-syntax": [
823
- "error",
824
- "TSEnumDeclaration[const=true]",
825
- "TSExportAssignment"
826
- ],
827
- "no-self-assign": ["error", { props: true }],
828
- "no-self-compare": "error",
829
- "no-sequences": "error",
830
- "no-shadow-restricted-names": "error",
831
- "no-sparse-arrays": "error",
832
- "no-template-curly-in-string": "error",
833
- "no-this-before-super": "error",
834
- "no-throw-literal": "error",
835
- "no-undef": "error",
836
- "no-undef-init": "error",
837
- "no-unexpected-multiline": "error",
838
- "no-unmodified-loop-condition": "error",
839
- "no-unneeded-ternary": ["error", { defaultAssignment: false }],
840
- "no-unreachable": "error",
841
- "no-unreachable-loop": "error",
842
- "no-unsafe-finally": "error",
843
- "no-unsafe-negation": "error",
844
- "no-unused-expressions": ["error", {
845
- allowShortCircuit: true,
846
- allowTaggedTemplates: true,
847
- allowTernary: true
848
- }],
849
- "no-unused-vars": ["error", {
850
- args: "none",
851
- caughtErrors: "none",
852
- ignoreRestSiblings: true,
853
- vars: "all"
854
- }],
855
- "no-use-before-define": ["error", { classes: false, functions: false, variables: true }],
856
- "no-useless-backreference": "error",
857
- "no-useless-call": "error",
858
- "no-useless-catch": "error",
859
- "no-useless-computed-key": "error",
860
- "no-useless-constructor": "error",
861
- "no-useless-rename": "error",
862
- "no-useless-return": "error",
863
- "no-var": "error",
864
- "no-with": "error",
865
- "object-shorthand": [
866
- "error",
867
- "always",
868
- {
869
- avoidQuotes: true,
870
- ignoreConstructors: false
871
- }
872
- ],
873
- "one-var": ["error", { initialized: "never" }],
874
- "prefer-arrow-callback": [
875
- "error",
876
- {
877
- allowNamedFunctions: false,
878
- allowUnboundThis: true
879
- }
880
- ],
881
- "prefer-const": [
882
- "error",
883
- {
884
- destructuring: "all",
885
- ignoreReadBeforeAssign: true
886
- }
887
- ],
888
- "prefer-exponentiation-operator": "error",
889
- "prefer-promise-reject-errors": "error",
890
- "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
891
- "prefer-rest-params": "error",
892
- "prefer-spread": "error",
893
- "prefer-template": "error",
894
- "symbol-description": "error",
895
- "unicode-bom": ["error", "never"],
896
- "unused-imports/no-unused-imports": isInEditor ? "off" : "error",
897
- "unused-imports/no-unused-vars": [
898
- "error",
899
- {
900
- args: "after-used",
901
- argsIgnorePattern: "^_",
902
- ignoreRestSiblings: true,
903
- vars: "all",
904
- varsIgnorePattern: "^_"
905
- }
906
- ],
907
- "use-isnan": ["error", { enforceForIndexOf: true, enforceForSwitchCase: true }],
908
- "valid-typeof": ["error", { requireStringLiterals: true }],
909
- "vars-on-top": "error",
910
- "yoda": ["error", "never"],
911
- ...overrides
912
- }
913
- }
914
- ];
915
- }
916
-
917
- // src/configs/jsdoc.ts
918
- async function jsdoc(options = {}) {
919
- const {
920
- stylistic: stylistic2 = true
921
- } = options;
922
- return [
923
- {
924
- name: "jun/jsdoc/rules",
925
- plugins: {
926
- jsdoc: await interopDefault(import("eslint-plugin-jsdoc"))
927
- },
928
- rules: {
929
- "jsdoc/check-access": "warn",
930
- "jsdoc/check-param-names": "warn",
931
- "jsdoc/check-property-names": "warn",
932
- "jsdoc/check-types": "warn",
933
- "jsdoc/empty-tags": "warn",
934
- "jsdoc/implements-on-classes": "warn",
935
- "jsdoc/no-defaults": "warn",
936
- "jsdoc/no-multi-asterisks": "warn",
937
- "jsdoc/require-param-name": "warn",
938
- "jsdoc/require-property": "warn",
939
- "jsdoc/require-property-description": "warn",
940
- "jsdoc/require-property-name": "warn",
941
- "jsdoc/require-returns-check": "warn",
942
- "jsdoc/require-returns-description": "warn",
943
- "jsdoc/require-yields-check": "warn",
944
- ...stylistic2 ? {
945
- "jsdoc/check-alignment": "warn",
946
- "jsdoc/multiline-blocks": "warn"
947
- } : {}
948
- }
949
- }
950
- ];
951
- }
952
-
953
- // src/configs/jsonc.ts
954
- async function jsonc(options = {}) {
955
- const {
956
- files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
957
- overrides = {},
958
- stylistic: stylistic2 = true
959
- } = options;
960
- const {
961
- indent = 2
962
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
963
- const [
964
- pluginJsonc,
965
- parserJsonc
966
- ] = await Promise.all([
967
- interopDefault(import("eslint-plugin-jsonc")),
968
- interopDefault(import("jsonc-eslint-parser"))
969
- ]);
970
- return [
971
- {
972
- name: "jun/jsonc/setup",
973
- plugins: {
974
- jsonc: pluginJsonc
975
- }
976
- },
977
- {
978
- files,
979
- languageOptions: {
980
- parser: parserJsonc
981
- },
982
- name: "jun/jsonc/rules",
983
- rules: {
984
- "jsonc/no-bigint-literals": "error",
985
- "jsonc/no-binary-expression": "error",
986
- "jsonc/no-binary-numeric-literals": "error",
987
- "jsonc/no-dupe-keys": "error",
988
- "jsonc/no-escape-sequence-in-identifier": "error",
989
- "jsonc/no-floating-decimal": "error",
990
- "jsonc/no-hexadecimal-numeric-literals": "error",
991
- "jsonc/no-infinity": "error",
992
- "jsonc/no-multi-str": "error",
993
- "jsonc/no-nan": "error",
994
- "jsonc/no-number-props": "error",
995
- "jsonc/no-numeric-separators": "error",
996
- "jsonc/no-octal": "error",
997
- "jsonc/no-octal-escape": "error",
998
- "jsonc/no-octal-numeric-literals": "error",
999
- "jsonc/no-parenthesized": "error",
1000
- "jsonc/no-plus-sign": "error",
1001
- "jsonc/no-regexp-literals": "error",
1002
- "jsonc/no-sparse-arrays": "error",
1003
- "jsonc/no-template-literals": "error",
1004
- "jsonc/no-undefined-value": "error",
1005
- "jsonc/no-unicode-codepoint-escapes": "error",
1006
- "jsonc/no-useless-escape": "error",
1007
- "jsonc/space-unary-ops": "error",
1008
- "jsonc/valid-json-number": "error",
1009
- "jsonc/vue-custom-block/no-parsing-error": "error",
1010
- ...stylistic2 ? {
1011
- "jsonc/array-bracket-spacing": ["error", "never"],
1012
- "jsonc/comma-dangle": ["error", "never"],
1013
- "jsonc/comma-style": ["error", "last"],
1014
- "jsonc/indent": ["error", indent],
1015
- "jsonc/key-spacing": ["error", { afterColon: true, beforeColon: false }],
1016
- "jsonc/object-curly-newline": ["error", { consistent: true, multiline: true }],
1017
- "jsonc/object-curly-spacing": ["error", "always"],
1018
- "jsonc/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
1019
- "jsonc/quote-props": "error",
1020
- "jsonc/quotes": "error"
1021
- } : {},
1022
- ...overrides
1023
- }
1024
- }
1025
- ];
1026
- }
1027
-
1028
- // src/configs/jsx.ts
1029
- async function jsx() {
1030
- return [
1031
- {
1032
- files: [GLOB_JSX, GLOB_TSX],
1033
- languageOptions: {
1034
- parserOptions: {
1035
- ecmaFeatures: {
1036
- jsx: true
1037
- }
1038
- }
1039
- },
1040
- name: "jun/jsx/setup"
1041
- }
1042
- ];
1043
- }
1044
-
1045
- // src/configs/markdown.ts
1046
- import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
1047
- async function markdown(options = {}) {
1048
- const {
1049
- componentExts = [],
1050
- files = [GLOB_MARKDOWN],
1051
- overrides = {}
1052
- } = options;
1053
- const markdown2 = await interopDefault(import("@eslint/markdown"));
1054
- return [
1055
- {
1056
- name: "jun/markdown/setup",
1057
- plugins: {
1058
- markdown: markdown2
1059
- }
1060
- },
1061
- {
1062
- files,
1063
- ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
1064
- name: "jun/markdown/processor",
1065
- // `eslint-plugin-markdown` only creates virtual files for code blocks,
1066
- // but not the markdown file itself. We use `eslint-merge-processors` to
1067
- // add a pass-through processor for the markdown file itself.
1068
- processor: mergeProcessors([
1069
- markdown2.processors.markdown,
1070
- processorPassThrough
1071
- ])
1072
- },
1073
- {
1074
- files,
1075
- languageOptions: {
1076
- parser: parserPlain
1077
- },
1078
- name: "jun/markdown/parser"
1079
- },
1080
- {
1081
- files: [
1082
- GLOB_MARKDOWN_CODE,
1083
- ...componentExts.map((ext) => `${GLOB_MARKDOWN}/**/*.${ext}`)
1084
- ],
1085
- languageOptions: {
1086
- parserOptions: {
1087
- ecmaFeatures: {
1088
- impliedStrict: true
1089
- }
1090
- }
1091
- },
1092
- name: "jun/markdown/disables",
1093
- rules: {
1094
- "import/newline-after-import": "off",
1095
- "jun/no-top-level-await": "off",
1096
- "no-alert": "off",
1097
- "no-console": "off",
1098
- "no-labels": "off",
1099
- "no-lone-blocks": "off",
1100
- "no-restricted-syntax": "off",
1101
- "no-undef": "off",
1102
- "no-unused-expressions": "off",
1103
- "no-unused-labels": "off",
1104
- "no-unused-vars": "off",
1105
- "node/prefer-global/process": "off",
1106
- "style/comma-dangle": "off",
1107
- "style/eol-last": "off",
1108
- "ts/consistent-type-imports": "off",
1109
- "ts/explicit-function-return-type": "off",
1110
- "ts/no-namespace": "off",
1111
- "ts/no-redeclare": "off",
1112
- "ts/no-require-imports": "off",
1113
- "ts/no-unused-expressions": "off",
1114
- "ts/no-unused-vars": "off",
1115
- "ts/no-use-before-define": "off",
1116
- "unicode-bom": "off",
1117
- "unused-imports/no-unused-imports": "off",
1118
- "unused-imports/no-unused-vars": "off",
1119
- ...overrides
1120
- }
1121
- }
1122
- ];
1123
- }
1124
-
1125
- // src/configs/node.ts
1126
- async function node() {
1127
- return [
1128
- {
1129
- name: "jun/node/rules",
1130
- plugins: {
1131
- node: default4
1132
- },
1133
- rules: {
1134
- "node/handle-callback-err": ["error", "^(err|error)$"],
1135
- "node/no-deprecated-api": "error",
1136
- "node/no-exports-assign": "error",
1137
- "node/no-new-require": "error",
1138
- "node/no-path-concat": "error",
1139
- "node/prefer-global/buffer": ["error", "never"],
1140
- "node/prefer-global/process": ["error", "never"],
1141
- "node/process-exit-as-throw": "error"
1142
- }
1143
- }
1144
- ];
1145
- }
1146
-
1147
- // src/configs/perfectionist.ts
1148
- async function perfectionist() {
1149
- return [
1150
- {
1151
- name: "jun/perfectionist/setup",
1152
- plugins: {
1153
- perfectionist: default5
1154
- },
1155
- rules: {
1156
- "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
1157
- "perfectionist/sort-imports": ["error", {
1158
- groups: [
1159
- "type",
1160
- ["parent-type", "sibling-type", "index-type"],
1161
- "builtin",
1162
- "external",
1163
- ["internal", "internal-type"],
1164
- ["parent", "sibling", "index"],
1165
- "side-effect",
1166
- "object",
1167
- "unknown"
1168
- ],
1169
- newlinesBetween: "ignore",
1170
- order: "asc",
1171
- type: "natural"
1172
- }],
1173
- "perfectionist/sort-named-exports": ["error", { order: "asc", type: "natural" }],
1174
- "perfectionist/sort-named-imports": ["error", { order: "asc", type: "natural" }]
1175
- }
1176
- }
1177
- ];
1178
- }
1179
-
1180
- // src/configs/react.ts
1181
- import { isPackageExists as isPackageExists3 } from "local-pkg";
1182
- var ReactRefreshAllowConstantExportPackages = [
1183
- "vite"
1184
- ];
1185
- var RemixPackages = [
1186
- "@remix-run/node",
1187
- "@remix-run/react",
1188
- "@remix-run/serve",
1189
- "@remix-run/dev"
1190
- ];
1191
- var NextJsPackages = [
1192
- "next"
1193
- ];
1194
- async function react(options = {}) {
1195
- const {
1196
- files = [GLOB_SRC],
1197
- overrides = {}
1198
- } = options;
1199
- await ensurePackages([
1200
- "@eslint-react/eslint-plugin",
1201
- "eslint-plugin-react-hooks",
1202
- "eslint-plugin-react-refresh"
1203
- ]);
1204
- const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1205
- const isTypeAware = !!tsconfigPath;
1206
- const [
1207
- pluginReact,
1208
- pluginReactHooks,
1209
- pluginReactRefresh,
1210
- parserTs
1211
- ] = await Promise.all([
1212
- interopDefault(import("@eslint-react/eslint-plugin")),
1213
- interopDefault(import("eslint-plugin-react-hooks")),
1214
- interopDefault(import("eslint-plugin-react-refresh")),
1215
- interopDefault(import("@typescript-eslint/parser"))
1216
- ]);
1217
- const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some((i) => isPackageExists3(i));
1218
- const isUsingRemix = RemixPackages.some((i) => isPackageExists3(i));
1219
- const isUsingNext = NextJsPackages.some((i) => isPackageExists3(i));
1220
- const plugins = pluginReact.configs.all.plugins;
1221
- return [
1222
- {
1223
- name: "jun/react/setup",
1224
- plugins: {
1225
- "react": plugins["@eslint-react"],
1226
- "react-dom": plugins["@eslint-react/dom"],
1227
- "react-hooks": pluginReactHooks,
1228
- "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1229
- "react-naming-convention": plugins["@eslint-react/naming-convention"],
1230
- "react-refresh": pluginReactRefresh
1231
- }
1232
- },
1233
- {
1234
- files,
1235
- languageOptions: {
1236
- parser: parserTs,
1237
- parserOptions: {
1238
- ecmaFeatures: {
1239
- jsx: true
1240
- },
1241
- ...isTypeAware ? { project: tsconfigPath } : {}
1242
- },
1243
- sourceType: "module"
1244
- },
1245
- name: "jun/react/rules",
1246
- rules: {
1247
- // recommended rules from @eslint-react/dom
1248
- "react-dom/no-children-in-void-dom-elements": "warn",
1249
- "react-dom/no-dangerously-set-innerhtml": "warn",
1250
- "react-dom/no-dangerously-set-innerhtml-with-children": "error",
1251
- "react-dom/no-find-dom-node": "error",
1252
- "react-dom/no-missing-button-type": "warn",
1253
- "react-dom/no-missing-iframe-sandbox": "warn",
1254
- "react-dom/no-namespace": "error",
1255
- "react-dom/no-render-return-value": "error",
1256
- "react-dom/no-script-url": "warn",
1257
- "react-dom/no-unsafe-iframe-sandbox": "warn",
1258
- "react-dom/no-unsafe-target-blank": "warn",
1259
- // recommended rules react-hooks
1260
- "react-hooks/exhaustive-deps": "warn",
1261
- "react-hooks/rules-of-hooks": "error",
1262
- // react refresh
1263
- "react-refresh/only-export-components": [
1264
- "warn",
1265
- {
1266
- allowConstantExport: isAllowConstantExport,
1267
- allowExportNames: [
1268
- ...isUsingNext ? [
1269
- "dynamic",
1270
- "dynamicParams",
1271
- "revalidate",
1272
- "fetchCache",
1273
- "runtime",
1274
- "preferredRegion",
1275
- "maxDuration",
1276
- "config",
1277
- "generateStaticParams",
1278
- "metadata",
1279
- "generateMetadata",
1280
- "viewport",
1281
- "generateViewport"
1282
- ] : [],
1283
- ...isUsingRemix ? [
1284
- "meta",
1285
- "links",
1286
- "headers",
1287
- "loader",
1288
- "action"
1289
- ] : []
1290
- ]
1291
- }
1292
- ],
1293
- // recommended rules from @eslint-react
1294
- "react/ensure-forward-ref-using-ref": "warn",
1295
- "react/no-access-state-in-setstate": "error",
1296
- "react/no-array-index-key": "warn",
1297
- "react/no-children-count": "warn",
1298
- "react/no-children-for-each": "warn",
1299
- "react/no-children-map": "warn",
1300
- "react/no-children-only": "warn",
1301
- "react/no-children-prop": "warn",
1302
- "react/no-children-to-array": "warn",
1303
- "react/no-clone-element": "warn",
1304
- "react/no-comment-textnodes": "warn",
1305
- "react/no-component-will-mount": "error",
1306
- "react/no-component-will-receive-props": "error",
1307
- "react/no-component-will-update": "error",
1308
- "react/no-create-ref": "error",
1309
- "react/no-direct-mutation-state": "error",
1310
- "react/no-duplicate-key": "error",
1311
- "react/no-implicit-key": "error",
1312
- "react/no-missing-key": "error",
1313
- "react/no-nested-components": "warn",
1314
- "react/no-redundant-should-component-update": "error",
1315
- "react/no-set-state-in-component-did-mount": "warn",
1316
- "react/no-set-state-in-component-did-update": "warn",
1317
- "react/no-set-state-in-component-will-update": "warn",
1318
- "react/no-string-refs": "error",
1319
- "react/no-unsafe-component-will-mount": "warn",
1320
- "react/no-unsafe-component-will-receive-props": "warn",
1321
- "react/no-unsafe-component-will-update": "warn",
1322
- "react/no-unstable-context-value": "error",
1323
- "react/no-unstable-default-props": "error",
1324
- "react/no-unused-class-component-members": "warn",
1325
- "react/no-unused-state": "warn",
1326
- "react/no-useless-fragment": "warn",
1327
- "react/prefer-destructuring-assignment": "warn",
1328
- "react/prefer-shorthand-boolean": "warn",
1329
- "react/prefer-shorthand-fragment": "warn",
1330
- ...isTypeAware ? {
1331
- "react/no-leaked-conditional-rendering": "warn"
1332
- } : {},
1333
- // overrides
1334
- ...overrides
1335
- }
1336
- }
1337
- ];
1338
- }
1339
-
1340
- // src/configs/regexp.ts
1341
- import { configs } from "eslint-plugin-regexp";
1342
- async function regexp(options = {}) {
1343
- const config = configs["flat/recommended"];
1344
- const rules = {
1345
- ...config.rules
1346
- };
1347
- if (options.level === "warn") {
1348
- for (const key in rules) {
1349
- if (rules[key] === "error")
1350
- rules[key] = "warn";
1351
- }
1352
- }
1353
- return [
1354
- {
1355
- ...config,
1356
- name: "jun/regexp/rules",
1357
- rules: {
1358
- ...rules,
1359
- ...options.overrides
1360
- }
1361
- }
1362
- ];
1363
- }
1364
-
1365
- // src/configs/solid.ts
1366
- async function solid(options = {}) {
1367
- const {
1368
- files = [GLOB_JSX, GLOB_TSX],
1369
- overrides = {},
1370
- typescript: typescript2 = true
1371
- } = options;
1372
- await ensurePackages([
1373
- "eslint-plugin-solid"
1374
- ]);
1375
- const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1376
- const isTypeAware = !!tsconfigPath;
1377
- const [
1378
- pluginSolid,
1379
- parserTs
1380
- ] = await Promise.all([
1381
- interopDefault(import("eslint-plugin-solid")),
1382
- interopDefault(import("@typescript-eslint/parser"))
1383
- ]);
1384
- return [
1385
- {
1386
- name: "jun/solid/setup",
1387
- plugins: {
1388
- solid: pluginSolid
1389
- }
1390
- },
1391
- {
1392
- files,
1393
- languageOptions: {
1394
- parser: parserTs,
1395
- parserOptions: {
1396
- ecmaFeatures: {
1397
- jsx: true
1398
- },
1399
- ...isTypeAware ? { project: tsconfigPath } : {}
1400
- },
1401
- sourceType: "module"
1402
- },
1403
- name: "jun/solid/rules",
1404
- rules: {
1405
- // reactivity
1406
- "solid/components-return-once": "warn",
1407
- "solid/event-handlers": ["error", {
1408
- // if true, don't warn on ambiguously named event handlers like `onclick` or `onchange`
1409
- ignoreCase: false,
1410
- // if true, warn when spreading event handlers onto JSX. Enable for Solid < v1.6.
1411
- warnOnSpread: false
1412
- }],
1413
- // these rules are mostly style suggestions
1414
- "solid/imports": "error",
1415
- // identifier usage is important
1416
- "solid/jsx-no-duplicate-props": "error",
1417
- "solid/jsx-no-script-url": "error",
1418
- "solid/jsx-no-undef": "error",
1419
- "solid/jsx-uses-vars": "error",
1420
- "solid/no-destructure": "error",
1421
- // security problems
1422
- "solid/no-innerhtml": ["error", { allowStatic: true }],
1423
- "solid/no-react-deps": "error",
1424
- "solid/no-react-specific-props": "error",
1425
- "solid/no-unknown-namespaces": "error",
1426
- "solid/prefer-for": "error",
1427
- "solid/reactivity": "warn",
1428
- "solid/self-closing-comp": "error",
1429
- "solid/style-prop": ["error", { styleProps: ["style", "css"] }],
1430
- ...typescript2 ? {
1431
- "solid/jsx-no-undef": ["error", { typescriptEnabled: true }],
1432
- "solid/no-unknown-namespaces": "off"
1433
- } : {},
1434
- // overrides
1435
- ...overrides
1436
- }
1437
- }
1438
- ];
1439
- }
1440
-
1441
- // src/configs/sort.ts
1442
- async function sortPackageJson() {
1443
- return [
1444
- {
1445
- files: ["**/package.json"],
1446
- name: "jun/sort/package-json",
1447
- rules: {
1448
- "jsonc/sort-array-values": [
1449
- "error",
1450
- {
1451
- order: { type: "asc" },
1452
- pathPattern: "^files$"
1453
- }
1454
- ],
1455
- "jsonc/sort-keys": [
1456
- "error",
1457
- {
1458
- order: [
1459
- "publisher",
1460
- "name",
1461
- "displayName",
1462
- "type",
1463
- "version",
1464
- "private",
1465
- "packageManager",
1466
- "description",
1467
- "author",
1468
- "contributors",
1469
- "license",
1470
- "funding",
1471
- "homepage",
1472
- "repository",
1473
- "bugs",
1474
- "keywords",
1475
- "categories",
1476
- "sideEffects",
1477
- "exports",
1478
- "main",
1479
- "module",
1480
- "unpkg",
1481
- "jsdelivr",
1482
- "types",
1483
- "typesVersions",
1484
- "bin",
1485
- "icon",
1486
- "files",
1487
- "engines",
1488
- "activationEvents",
1489
- "contributes",
1490
- "scripts",
1491
- "peerDependencies",
1492
- "peerDependenciesMeta",
1493
- "dependencies",
1494
- "optionalDependencies",
1495
- "devDependencies",
1496
- "pnpm",
1497
- "overrides",
1498
- "resolutions",
1499
- "husky",
1500
- "simple-git-hooks",
1501
- "lint-staged",
1502
- "eslintConfig"
1503
- ],
1504
- pathPattern: "^$"
1505
- },
1506
- {
1507
- order: { type: "asc" },
1508
- pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
1509
- },
1510
- {
1511
- order: { type: "asc" },
1512
- pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
1513
- },
1514
- {
1515
- order: [
1516
- "types",
1517
- "import",
1518
- "require",
1519
- "default"
1520
- ],
1521
- pathPattern: "^exports.*$"
1522
- },
1523
- {
1524
- order: [
1525
- // client hooks only
1526
- "pre-commit",
1527
- "prepare-commit-msg",
1528
- "commit-msg",
1529
- "post-commit",
1530
- "pre-rebase",
1531
- "post-rewrite",
1532
- "post-checkout",
1533
- "post-merge",
1534
- "pre-push",
1535
- "pre-auto-gc"
1536
- ],
1537
- pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
1538
- }
1539
- ]
1540
- }
1541
- }
1542
- ];
1543
- }
1544
- function sortTsconfig() {
1545
- return [
1546
- {
1547
- files: ["**/tsconfig.json", "**/tsconfig.*.json"],
1548
- name: "jun/sort/tsconfig-json",
1549
- rules: {
1550
- "jsonc/sort-keys": [
1551
- "error",
1552
- {
1553
- order: [
1554
- "extends",
1555
- "compilerOptions",
1556
- "references",
1557
- "files",
1558
- "include",
1559
- "exclude"
1560
- ],
1561
- pathPattern: "^$"
1562
- },
1563
- {
1564
- order: [
1565
- /* Projects */
1566
- "incremental",
1567
- "composite",
1568
- "tsBuildInfoFile",
1569
- "disableSourceOfProjectReferenceRedirect",
1570
- "disableSolutionSearching",
1571
- "disableReferencedProjectLoad",
1572
- /* Language and Environment */
1573
- "target",
1574
- "jsx",
1575
- "jsxFactory",
1576
- "jsxFragmentFactory",
1577
- "jsxImportSource",
1578
- "lib",
1579
- "moduleDetection",
1580
- "noLib",
1581
- "reactNamespace",
1582
- "useDefineForClassFields",
1583
- "emitDecoratorMetadata",
1584
- "experimentalDecorators",
1585
- /* Modules */
1586
- "baseUrl",
1587
- "rootDir",
1588
- "rootDirs",
1589
- "customConditions",
1590
- "module",
1591
- "moduleResolution",
1592
- "moduleSuffixes",
1593
- "noResolve",
1594
- "paths",
1595
- "resolveJsonModule",
1596
- "resolvePackageJsonExports",
1597
- "resolvePackageJsonImports",
1598
- "typeRoots",
1599
- "types",
1600
- "allowArbitraryExtensions",
1601
- "allowImportingTsExtensions",
1602
- "allowUmdGlobalAccess",
1603
- /* JavaScript Support */
1604
- "allowJs",
1605
- "checkJs",
1606
- "maxNodeModuleJsDepth",
1607
- /* Type Checking */
1608
- "strict",
1609
- "strictBindCallApply",
1610
- "strictFunctionTypes",
1611
- "strictNullChecks",
1612
- "strictPropertyInitialization",
1613
- "allowUnreachableCode",
1614
- "allowUnusedLabels",
1615
- "alwaysStrict",
1616
- "exactOptionalPropertyTypes",
1617
- "noFallthroughCasesInSwitch",
1618
- "noImplicitAny",
1619
- "noImplicitOverride",
1620
- "noImplicitReturns",
1621
- "noImplicitThis",
1622
- "noPropertyAccessFromIndexSignature",
1623
- "noUncheckedIndexedAccess",
1624
- "noUnusedLocals",
1625
- "noUnusedParameters",
1626
- "useUnknownInCatchVariables",
1627
- /* Emit */
1628
- "declaration",
1629
- "declarationDir",
1630
- "declarationMap",
1631
- "downlevelIteration",
1632
- "emitBOM",
1633
- "emitDeclarationOnly",
1634
- "importHelpers",
1635
- "importsNotUsedAsValues",
1636
- "inlineSourceMap",
1637
- "inlineSources",
1638
- "mapRoot",
1639
- "newLine",
1640
- "noEmit",
1641
- "noEmitHelpers",
1642
- "noEmitOnError",
1643
- "outDir",
1644
- "outFile",
1645
- "preserveConstEnums",
1646
- "preserveValueImports",
1647
- "removeComments",
1648
- "sourceMap",
1649
- "sourceRoot",
1650
- "stripInternal",
1651
- /* Interop Constraints */
1652
- "allowSyntheticDefaultImports",
1653
- "esModuleInterop",
1654
- "forceConsistentCasingInFileNames",
1655
- "isolatedDeclarations",
1656
- "isolatedModules",
1657
- "preserveSymlinks",
1658
- "verbatimModuleSyntax",
1659
- /* Completeness */
1660
- "skipDefaultLibCheck",
1661
- "skipLibCheck"
1662
- ],
1663
- pathPattern: "^compilerOptions$"
1664
- }
1665
- ]
1666
- }
1667
- }
1668
- ];
1669
- }
1670
-
1671
- // src/configs/svelte.ts
1672
- async function svelte(options = {}) {
1673
- const {
1674
- files = [GLOB_SVELTE],
1675
- overrides = {},
1676
- stylistic: stylistic2 = true
1677
- } = options;
1678
- const {
1679
- indent = 2,
1680
- quotes = "single"
1681
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1682
- await ensurePackages([
1683
- "eslint-plugin-svelte"
1684
- ]);
1685
- const [
1686
- pluginSvelte,
1687
- parserSvelte
1688
- ] = await Promise.all([
1689
- interopDefault(import("eslint-plugin-svelte")),
1690
- interopDefault(import("svelte-eslint-parser"))
1691
- ]);
1692
- return [
1693
- {
1694
- name: "jun/svelte/setup",
1695
- plugins: {
1696
- svelte: pluginSvelte
1697
- }
1698
- },
1699
- {
1700
- files,
1701
- languageOptions: {
1702
- parser: parserSvelte,
1703
- parserOptions: {
1704
- extraFileExtensions: [".svelte"],
1705
- parser: options.typescript ? await interopDefault(import("@typescript-eslint/parser")) : null
1706
- }
1707
- },
1708
- name: "jun/svelte/rules",
1709
- processor: pluginSvelte.processors[".svelte"],
1710
- rules: {
1711
- "import/no-mutable-exports": "off",
1712
- "no-undef": "off",
1713
- // incompatible with most recent (attribute-form) generic types RFC
1714
- "no-unused-vars": ["error", {
1715
- args: "none",
1716
- caughtErrors: "none",
1717
- ignoreRestSiblings: true,
1718
- vars: "all",
1719
- varsIgnorePattern: "^(\\$\\$Props$|\\$\\$Events$|\\$\\$Slots$)"
1720
- }],
1721
- "svelte/comment-directive": "error",
1722
- "svelte/no-at-debug-tags": "warn",
1723
- "svelte/no-at-html-tags": "error",
1724
- "svelte/no-dupe-else-if-blocks": "error",
1725
- "svelte/no-dupe-style-properties": "error",
1726
- "svelte/no-dupe-use-directives": "error",
1727
- "svelte/no-dynamic-slot-name": "error",
1728
- "svelte/no-export-load-in-svelte-module-in-kit-pages": "error",
1729
- "svelte/no-inner-declarations": "error",
1730
- "svelte/no-not-function-handler": "error",
1731
- "svelte/no-object-in-text-mustaches": "error",
1732
- "svelte/no-reactive-functions": "error",
1733
- "svelte/no-reactive-literals": "error",
1734
- "svelte/no-shorthand-style-property-overrides": "error",
1735
- "svelte/no-unknown-style-directive-property": "error",
1736
- "svelte/no-unused-svelte-ignore": "error",
1737
- "svelte/no-useless-mustaches": "error",
1738
- "svelte/require-store-callbacks-use-set-param": "error",
1739
- "svelte/system": "error",
1740
- "svelte/valid-each-key": "error",
1741
- "unused-imports/no-unused-vars": [
1742
- "error",
1743
- {
1744
- args: "after-used",
1745
- argsIgnorePattern: "^_",
1746
- vars: "all",
1747
- varsIgnorePattern: "^(_|\\$\\$Props$|\\$\\$Events$|\\$\\$Slots$)"
1748
- }
1749
- ],
1750
- ...stylistic2 ? {
1751
- "style/indent": "off",
1752
- // superseded by svelte/indent
1753
- "style/no-trailing-spaces": "off",
1754
- // superseded by svelte/no-trailing-spaces
1755
- "svelte/derived-has-same-inputs-outputs": "error",
1756
- "svelte/html-closing-bracket-spacing": "error",
1757
- "svelte/html-quotes": ["error", { prefer: quotes }],
1758
- "svelte/indent": ["error", { alignAttributesVertically: true, indent }],
1759
- "svelte/mustache-spacing": "error",
1760
- "svelte/no-spaces-around-equal-signs-in-attribute": "error",
1761
- "svelte/no-trailing-spaces": "error",
1762
- "svelte/spaced-html-comment": "error"
1763
- } : {},
1764
- ...overrides
1765
- }
1766
- }
1767
- ];
1768
- }
1769
-
1770
- // src/configs/test.ts
1771
- var _pluginTest;
1772
- async function test(options = {}) {
1773
- const {
1774
- files = GLOB_TESTS,
1775
- isInEditor = false,
1776
- overrides = {}
1777
- } = options;
1778
- const [
1779
- pluginVitest,
1780
- pluginNoOnlyTests
1781
- ] = await Promise.all([
1782
- interopDefault(import("@vitest/eslint-plugin")),
1783
- // @ts-expect-error missing types
1784
- interopDefault(import("eslint-plugin-no-only-tests"))
1785
- ]);
1786
- _pluginTest = _pluginTest || {
1787
- ...pluginVitest,
1788
- rules: {
1789
- ...pluginVitest.rules,
1790
- // extend `test/no-only-tests` rule
1791
- ...pluginNoOnlyTests.rules
1792
- }
1793
- };
1794
- return [
1795
- {
1796
- name: "jun/test/setup",
1797
- plugins: {
1798
- test: _pluginTest
1799
- }
1800
- },
1801
- {
1802
- files,
1803
- name: "jun/test/rules",
1804
- rules: {
1805
- "test/consistent-test-it": ["error", { fn: "it", withinDescribe: "it" }],
1806
- "test/no-identical-title": "error",
1807
- "test/no-import-node-test": "error",
1808
- "test/no-only-tests": isInEditor ? "off" : "error",
1809
- "test/prefer-hooks-in-order": "error",
1810
- "test/prefer-lowercase-title": "error",
1811
- // Disables
1812
- ...{
1813
- "jun/no-top-level-await": "off",
1814
- "no-unused-expressions": "off",
1815
- "node/prefer-global/process": "off",
1816
- "ts/explicit-function-return-type": "off"
1817
- },
1818
- ...overrides
1819
- }
1820
- }
1821
- ];
1822
- }
1823
-
1824
- // src/configs/toml.ts
1825
- async function toml(options = {}) {
1826
- const {
1827
- files = [GLOB_TOML],
1828
- overrides = {},
1829
- stylistic: stylistic2 = true
1830
- } = options;
1831
- const {
1832
- indent = 2
1833
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1834
- const [
1835
- pluginToml,
1836
- parserToml
1837
- ] = await Promise.all([
1838
- interopDefault(import("eslint-plugin-toml")),
1839
- interopDefault(import("toml-eslint-parser"))
1840
- ]);
1841
- return [
1842
- {
1843
- name: "jun/toml/setup",
1844
- plugins: {
1845
- toml: pluginToml
1846
- }
1847
- },
1848
- {
1849
- files,
1850
- languageOptions: {
1851
- parser: parserToml
1852
- },
1853
- name: "jun/toml/rules",
1854
- rules: {
1855
- "style/spaced-comment": "off",
1856
- "toml/comma-style": "error",
1857
- "toml/keys-order": "error",
1858
- "toml/no-space-dots": "error",
1859
- "toml/no-unreadable-number-separator": "error",
1860
- "toml/precision-of-fractional-seconds": "error",
1861
- "toml/precision-of-integer": "error",
1862
- "toml/tables-order": "error",
1863
- "toml/vue-custom-block/no-parsing-error": "error",
1864
- ...stylistic2 ? {
1865
- "toml/array-bracket-newline": "error",
1866
- "toml/array-bracket-spacing": "error",
1867
- "toml/array-element-newline": "error",
1868
- "toml/indent": ["error", indent === "tab" ? 2 : indent],
1869
- "toml/inline-table-curly-spacing": "error",
1870
- "toml/key-spacing": "error",
1871
- "toml/padding-line-between-pairs": "error",
1872
- "toml/padding-line-between-tables": "error",
1873
- "toml/quoted-keys": "error",
1874
- "toml/spaced-comment": "error",
1875
- "toml/table-bracket-spacing": "error"
1876
- } : {},
1877
- ...overrides
1878
- }
1879
- }
1880
- ];
1881
- }
1882
-
1883
- // src/configs/typescript.ts
1884
- import process2 from "node:process";
1885
- async function typescript(options = {}) {
1886
- const {
1887
- componentExts = [],
1888
- overrides = {},
1889
- overridesTypeAware = {},
1890
- parserOptions = {},
1891
- type = "app"
1892
- } = options;
1893
- const files = options.files ?? [
1894
- GLOB_TS,
1895
- GLOB_TSX,
1896
- ...componentExts.map((ext) => `**/*.${ext}`)
1897
- ];
1898
- const filesTypeAware = options.filesTypeAware ?? [GLOB_TS, GLOB_TSX];
1899
- const ignoresTypeAware = options.ignoresTypeAware ?? [
1900
- `${GLOB_MARKDOWN}/**`,
1901
- GLOB_ASTRO_TS
1902
- ];
1903
- const tsconfigPath = options?.tsconfigPath ? options.tsconfigPath : void 0;
1904
- const isTypeAware = !!tsconfigPath;
1905
- const typeAwareRules = {
1906
- "dot-notation": "off",
1907
- "no-implied-eval": "off",
1908
- "ts/await-thenable": "error",
1909
- "ts/dot-notation": ["error", { allowKeywords: true }],
1910
- "ts/no-floating-promises": "error",
1911
- "ts/no-for-in-array": "error",
1912
- "ts/no-implied-eval": "error",
1913
- "ts/no-misused-promises": "error",
1914
- "ts/no-unnecessary-type-assertion": "error",
1915
- "ts/no-unsafe-argument": "error",
1916
- "ts/no-unsafe-assignment": "error",
1917
- "ts/no-unsafe-call": "error",
1918
- "ts/no-unsafe-member-access": "error",
1919
- "ts/no-unsafe-return": "error",
1920
- "ts/promise-function-async": "error",
1921
- "ts/restrict-plus-operands": "error",
1922
- "ts/restrict-template-expressions": "error",
1923
- "ts/return-await": ["error", "in-try-catch"],
1924
- "ts/strict-boolean-expressions": ["error", { allowNullableBoolean: true, allowNullableObject: true }],
1925
- "ts/switch-exhaustiveness-check": "error",
1926
- "ts/unbound-method": "error"
1927
- };
1928
- const [
1929
- pluginTs,
1930
- parserTs
1931
- ] = await Promise.all([
1932
- interopDefault(import("@typescript-eslint/eslint-plugin")),
1933
- interopDefault(import("@typescript-eslint/parser"))
1934
- ]);
1935
- function makeParser(typeAware, files2, ignores2) {
1936
- return {
1937
- files: files2,
1938
- ...ignores2 ? { ignores: ignores2 } : {},
1939
- languageOptions: {
1940
- parser: parserTs,
1941
- parserOptions: {
1942
- extraFileExtensions: componentExts.map((ext) => `.${ext}`),
1943
- sourceType: "module",
1944
- ...typeAware ? {
1945
- projectService: {
1946
- allowDefaultProject: ["./*.js"],
1947
- defaultProject: tsconfigPath
1948
- },
1949
- tsconfigRootDir: process2.cwd()
1950
- } : {},
1951
- ...parserOptions
1952
- }
1953
- },
1954
- name: `jun/typescript/${typeAware ? "type-aware-parser" : "parser"}`
1955
- };
1956
- }
1957
- return [
1958
- {
1959
- // Install the plugins without globs, so they can be configured separately.
1960
- name: "jun/typescript/setup",
1961
- plugins: {
1962
- jun: default3,
1963
- ts: pluginTs
1964
- }
1965
- },
1966
- // assign type-aware parser for type-aware files and type-unaware parser for the rest
1967
- ...isTypeAware ? [
1968
- makeParser(false, files),
1969
- makeParser(true, filesTypeAware, ignoresTypeAware)
1970
- ] : [
1971
- makeParser(false, files)
1972
- ],
1973
- {
1974
- files,
1975
- name: "jun/typescript/rules",
1976
- rules: {
1977
- ...renameRules(
1978
- pluginTs.configs["eslint-recommended"].overrides[0].rules,
1979
- { "@typescript-eslint": "ts" }
1980
- ),
1981
- ...renameRules(
1982
- pluginTs.configs.strict.rules,
1983
- { "@typescript-eslint": "ts" }
1984
- ),
1985
- "no-dupe-class-members": "off",
1986
- "no-redeclare": "off",
1987
- "no-use-before-define": "off",
1988
- "no-useless-constructor": "off",
1989
- "ts/ban-ts-comment": ["error", { "ts-expect-error": "allow-with-description" }],
1990
- "ts/consistent-type-definitions": ["error", "interface"],
1991
- "ts/consistent-type-imports": ["error", {
1992
- disallowTypeAnnotations: false,
1993
- prefer: "type-imports"
1994
- }],
1995
- "ts/method-signature-style": ["error", "property"],
1996
- // https://www.totaltypescript.com/method-shorthand-syntax-considered-harmful
1997
- "ts/no-dupe-class-members": "error",
1998
- "ts/no-dynamic-delete": "off",
1999
- "ts/no-empty-object-type": ["error", { allowInterfaces: "always" }],
2000
- "ts/no-explicit-any": "off",
2001
- "ts/no-extraneous-class": "off",
2002
- "ts/no-import-type-side-effects": "error",
2003
- "ts/no-invalid-void-type": "off",
2004
- "ts/no-non-null-assertion": "off",
2005
- "ts/no-redeclare": ["error", { builtinGlobals: false }],
2006
- "ts/no-require-imports": "error",
2007
- "ts/no-unused-expressions": ["error", {
2008
- allowShortCircuit: true,
2009
- allowTaggedTemplates: true,
2010
- allowTernary: true
2011
- }],
2012
- "ts/no-unused-vars": "off",
2013
- "ts/no-use-before-define": ["error", { classes: false, functions: false, variables: true }],
2014
- "ts/no-useless-constructor": "off",
2015
- "ts/no-wrapper-object-types": "error",
2016
- "ts/triple-slash-reference": "off",
2017
- "ts/unified-signatures": "off",
2018
- ...type === "lib" ? {
2019
- "ts/explicit-function-return-type": ["error", {
2020
- allowExpressions: true,
2021
- allowHigherOrderFunctions: true,
2022
- allowIIFEs: true
2023
- }]
2024
- } : {},
2025
- ...overrides
2026
- }
2027
- },
2028
- ...isTypeAware ? [{
2029
- files: filesTypeAware,
2030
- ignores: ignoresTypeAware,
2031
- name: "jun/typescript/rules-type-aware",
2032
- rules: {
2033
- ...typeAwareRules,
2034
- ...overridesTypeAware
2035
- }
2036
- }] : []
2037
- ];
2038
- }
2039
-
2040
- // src/configs/unicorn.ts
2041
- async function unicorn(options = {}) {
2042
- return [
2043
- {
2044
- name: "jun/unicorn/rules",
2045
- plugins: {
2046
- unicorn: default6
2047
- },
2048
- rules: {
2049
- ...options.allRecommended ? default6.configs["flat/recommended"].rules : {
2050
- "unicorn/consistent-empty-array-spread": "error",
2051
- "unicorn/error-message": "error",
2052
- "unicorn/escape-case": "error",
2053
- "unicorn/new-for-builtins": "error",
2054
- "unicorn/no-instanceof-array": "error",
2055
- "unicorn/no-new-array": "error",
2056
- "unicorn/no-new-buffer": "error",
2057
- "unicorn/number-literal-case": "error",
2058
- "unicorn/prefer-dom-node-text-content": "error",
2059
- "unicorn/prefer-includes": "error",
2060
- "unicorn/prefer-node-protocol": "error",
2061
- "unicorn/prefer-number-properties": "error",
2062
- "unicorn/prefer-string-starts-ends-with": "error",
2063
- "unicorn/prefer-type-error": "error",
2064
- "unicorn/throw-new-error": "error"
2065
- }
2066
- }
2067
- }
2068
- ];
2069
- }
2070
-
2071
- // src/configs/unocss.ts
2072
- async function unocss(options = {}) {
2073
- const {
2074
- attributify = true,
2075
- strict = false
2076
- } = options;
2077
- await ensurePackages([
2078
- "@unocss/eslint-plugin"
2079
- ]);
2080
- const [
2081
- pluginUnoCSS
2082
- ] = await Promise.all([
2083
- interopDefault(import("@unocss/eslint-plugin"))
2084
- ]);
2085
- return [
2086
- {
2087
- name: "jun/unocss",
2088
- plugins: {
2089
- unocss: pluginUnoCSS
2090
- },
2091
- rules: {
2092
- "unocss/order": "warn",
2093
- ...attributify ? {
2094
- "unocss/order-attributify": "warn"
2095
- } : {},
2096
- ...strict ? {
2097
- "unocss/blocklist": "error"
2098
- } : {}
2099
- }
2100
- }
2101
- ];
2102
- }
2103
-
2104
- // src/configs/vue.ts
2105
- import { mergeProcessors as mergeProcessors2 } from "eslint-merge-processors";
2106
- async function vue(options = {}) {
2107
- const {
2108
- files = [GLOB_VUE],
2109
- overrides = {},
2110
- stylistic: stylistic2 = true,
2111
- vueVersion = 3
2112
- } = options;
2113
- const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
2114
- const {
2115
- indent = 2
2116
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
2117
- const [
2118
- pluginVue,
2119
- parserVue,
2120
- processorVueBlocks
2121
- ] = await Promise.all([
2122
- // @ts-expect-error missing types
2123
- interopDefault(import("eslint-plugin-vue")),
2124
- interopDefault(import("vue-eslint-parser")),
2125
- interopDefault(import("eslint-processor-vue-blocks"))
2126
- ]);
2127
- return [
2128
- {
2129
- // This allows Vue plugin to work with auto imports
2130
- // https://github.com/vuejs/eslint-plugin-vue/pull/2422
2131
- languageOptions: {
2132
- globals: {
2133
- computed: "readonly",
2134
- defineEmits: "readonly",
2135
- defineExpose: "readonly",
2136
- defineProps: "readonly",
2137
- onMounted: "readonly",
2138
- onUnmounted: "readonly",
2139
- reactive: "readonly",
2140
- ref: "readonly",
2141
- shallowReactive: "readonly",
2142
- shallowRef: "readonly",
2143
- toRef: "readonly",
2144
- toRefs: "readonly",
2145
- watch: "readonly",
2146
- watchEffect: "readonly"
2147
- }
2148
- },
2149
- name: "jun/vue/setup",
2150
- plugins: {
2151
- vue: pluginVue
2152
- }
2153
- },
2154
- {
2155
- files,
2156
- languageOptions: {
2157
- parser: parserVue,
2158
- parserOptions: {
2159
- ecmaFeatures: {
2160
- jsx: true
2161
- },
2162
- extraFileExtensions: [".vue"],
2163
- parser: options.typescript ? await interopDefault(import("@typescript-eslint/parser")) : null,
2164
- sourceType: "module"
2165
- }
2166
- },
2167
- name: "jun/vue/rules",
2168
- processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors2([
2169
- pluginVue.processors[".vue"],
2170
- processorVueBlocks({
2171
- ...sfcBlocks,
2172
- blocks: {
2173
- styles: true,
2174
- ...sfcBlocks.blocks
2175
- }
2176
- })
2177
- ]),
2178
- rules: {
2179
- ...pluginVue.configs.base.rules,
2180
- ...vueVersion === 2 ? {
2181
- ...pluginVue.configs.essential.rules,
2182
- ...pluginVue.configs["strongly-recommended"].rules,
2183
- ...pluginVue.configs.recommended.rules
2184
- } : {
2185
- ...pluginVue.configs["vue3-essential"].rules,
2186
- ...pluginVue.configs["vue3-strongly-recommended"].rules,
2187
- ...pluginVue.configs["vue3-recommended"].rules
2188
- },
2189
- "jun/no-top-level-await": "off",
2190
- "node/prefer-global/process": "off",
2191
- "ts/explicit-function-return-type": "off",
2192
- "vue/block-order": ["error", {
2193
- order: ["script", "template", "style"]
2194
- }],
2195
- "vue/component-name-in-template-casing": ["error", "PascalCase"],
2196
- "vue/component-options-name-casing": ["error", "PascalCase"],
2197
- // this is deprecated
2198
- "vue/component-tags-order": "off",
2199
- "vue/custom-event-name-casing": ["error", "camelCase"],
2200
- "vue/define-macros-order": ["error", {
2201
- order: ["defineOptions", "defineProps", "defineEmits", "defineSlots"]
2202
- }],
2203
- "vue/dot-location": ["error", "property"],
2204
- "vue/dot-notation": ["error", { allowKeywords: true }],
2205
- "vue/eqeqeq": ["error", "smart"],
2206
- "vue/html-indent": ["error", indent],
2207
- "vue/html-quotes": ["error", "double"],
2208
- "vue/max-attributes-per-line": "off",
2209
- "vue/multi-word-component-names": "off",
2210
- "vue/no-dupe-keys": "off",
2211
- "vue/no-empty-pattern": "error",
2212
- "vue/no-irregular-whitespace": "error",
2213
- "vue/no-loss-of-precision": "error",
2214
- "vue/no-restricted-syntax": [
2215
- "error",
2216
- "DebuggerStatement",
2217
- "LabeledStatement",
2218
- "WithStatement"
2219
- ],
2220
- "vue/no-restricted-v-bind": ["error", "/^v-/"],
2221
- "vue/no-setup-props-reactivity-loss": "off",
2222
- "vue/no-sparse-arrays": "error",
2223
- "vue/no-unused-refs": "error",
2224
- "vue/no-useless-v-bind": "error",
2225
- "vue/no-v-html": "off",
2226
- "vue/object-shorthand": [
2227
- "error",
2228
- "always",
2229
- {
2230
- avoidQuotes: true,
2231
- ignoreConstructors: false
2232
- }
2233
- ],
2234
- "vue/prefer-separate-static-class": "error",
2235
- "vue/prefer-template": "error",
2236
- "vue/prop-name-casing": ["error", "camelCase"],
2237
- "vue/require-default-prop": "off",
2238
- "vue/require-prop-types": "off",
2239
- "vue/space-infix-ops": "error",
2240
- "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
2241
- ...stylistic2 ? {
2242
- "vue/array-bracket-spacing": ["error", "never"],
2243
- "vue/arrow-spacing": ["error", { after: true, before: true }],
2244
- "vue/block-spacing": ["error", "always"],
2245
- "vue/block-tag-newline": ["error", {
2246
- multiline: "always",
2247
- singleline: "always"
2248
- }],
2249
- "vue/brace-style": ["error", "1tbs", { allowSingleLine: true }],
2250
- "vue/comma-dangle": ["error", "always-multiline"],
2251
- "vue/comma-spacing": ["error", { after: true, before: false }],
2252
- "vue/comma-style": ["error", "last"],
2253
- "vue/html-comment-content-spacing": ["error", "always", {
2254
- exceptions: ["-"]
2255
- }],
2256
- "vue/key-spacing": ["error", { afterColon: true, beforeColon: false }],
2257
- "vue/keyword-spacing": ["error", { after: true, before: true }],
2258
- "vue/object-curly-newline": "off",
2259
- "vue/object-curly-spacing": ["error", "always"],
2260
- "vue/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
2261
- "vue/operator-linebreak": ["error", "before"],
2262
- "vue/padding-line-between-blocks": ["error", "always"],
2263
- "vue/quote-props": ["error", "consistent-as-needed"],
2264
- "vue/space-in-parens": ["error", "never"],
2265
- "vue/template-curly-spacing": "error"
2266
- } : {},
2267
- ...overrides
2268
- }
2269
- }
2270
- ];
2271
- }
2272
-
2273
- // src/configs/yaml.ts
2274
- async function yaml(options = {}) {
2275
- const {
2276
- files = [GLOB_YAML],
2277
- overrides = {},
2278
- stylistic: stylistic2 = true
2279
- } = options;
2280
- const {
2281
- indent = 2,
2282
- quotes = "single"
2283
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
2284
- const [
2285
- pluginYaml,
2286
- parserYaml
2287
- ] = await Promise.all([
2288
- interopDefault(import("eslint-plugin-yml")),
2289
- interopDefault(import("yaml-eslint-parser"))
2290
- ]);
2291
- return [
2292
- {
2293
- name: "jun/yaml/setup",
2294
- plugins: {
2295
- yaml: pluginYaml
2296
- }
2297
- },
2298
- {
2299
- files,
2300
- languageOptions: {
2301
- parser: parserYaml
2302
- },
2303
- name: "jun/yaml/rules",
2304
- rules: {
2305
- "style/spaced-comment": "off",
2306
- "yaml/block-mapping": "error",
2307
- "yaml/block-sequence": "error",
2308
- "yaml/no-empty-key": "error",
2309
- "yaml/no-empty-sequence-entry": "error",
2310
- "yaml/no-irregular-whitespace": "error",
2311
- "yaml/plain-scalar": "error",
2312
- "yaml/vue-custom-block/no-parsing-error": "error",
2313
- ...stylistic2 ? {
2314
- "yaml/block-mapping-question-indicator-newline": "error",
2315
- "yaml/block-sequence-hyphen-indicator-newline": "error",
2316
- "yaml/flow-mapping-curly-newline": "error",
2317
- "yaml/flow-mapping-curly-spacing": "error",
2318
- "yaml/flow-sequence-bracket-newline": "error",
2319
- "yaml/flow-sequence-bracket-spacing": "error",
2320
- "yaml/indent": ["error", indent === "tab" ? 2 : indent],
2321
- "yaml/key-spacing": "error",
2322
- "yaml/no-tab-indent": "error",
2323
- "yaml/quotes": ["error", { avoidEscape: false, prefer: quotes }],
2324
- "yaml/spaced-comment": "error"
2325
- } : {},
2326
- ...overrides
2327
- }
2328
- }
2329
- ];
2330
- }
2331
-
2332
- // src/factory.ts
2333
- var flatConfigProps = [
2334
- "name",
2335
- "languageOptions",
2336
- "linterOptions",
2337
- "processor",
2338
- "plugins",
2339
- "rules",
2340
- "settings"
2341
- ];
2342
- var VuePackages = [
2343
- "vue",
2344
- "nuxt",
2345
- "vitepress",
2346
- "@slidev/cli"
2347
- ];
2348
- var defaultPluginRenaming = {
2349
- "@eslint-react": "react",
2350
- "@eslint-react/dom": "react-dom",
2351
- "@eslint-react/hooks-extra": "react-hooks-extra",
2352
- "@eslint-react/naming-convention": "react-naming-convention",
2353
- "@stylistic": "style",
2354
- "@typescript-eslint": "ts",
2355
- "import-x": "import",
2356
- "n": "node",
2357
- "vitest": "test",
2358
- "yml": "yaml"
2359
- };
2360
- function jun(options = {}, ...userConfigs) {
2361
- const {
2362
- astro: enableAstro = false,
2363
- autoRenamePlugins = true,
2364
- componentExts = [],
2365
- gitignore: enableGitignore = true,
2366
- jsx: enableJsx = true,
2367
- react: enableReact = false,
2368
- regexp: enableRegexp = true,
2369
- solid: enableSolid = false,
2370
- svelte: enableSvelte = false,
2371
- typescript: enableTypeScript = isPackageExists4("typescript"),
2372
- unicorn: enableUnicorn = true,
2373
- unocss: enableUnoCSS = false,
2374
- vue: enableVue = VuePackages.some((i) => isPackageExists4(i))
2375
- } = options;
2376
- let isInEditor = options.isInEditor;
2377
- if (isInEditor == null) {
2378
- isInEditor = isInEditorEnv();
2379
- if (isInEditor)
2380
- console.log("[@jun2030/eslint-config] Detected running in editor, some rules are disabled.");
2381
- }
2382
- const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2383
- if (stylisticOptions && !("jsx" in stylisticOptions))
2384
- stylisticOptions.jsx = enableJsx;
2385
- const configs2 = [];
2386
- if (enableGitignore) {
2387
- if (typeof enableGitignore !== "boolean") {
2388
- configs2.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2389
- name: "jun/gitignore",
2390
- ...enableGitignore
2391
- })]));
2392
- } else {
2393
- configs2.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2394
- name: "jun/gitignore",
2395
- strict: false
2396
- })]));
2397
- }
2398
- }
2399
- const typescriptOptions = resolveSubOptions(options, "typescript");
2400
- const tsconfigPath = "tsconfigPath" in typescriptOptions ? typescriptOptions.tsconfigPath : void 0;
2401
- configs2.push(
2402
- ignores(options.ignores),
2403
- javascript({
2404
- isInEditor,
2405
- overrides: getOverrides(options, "javascript")
2406
- }),
2407
- comments(),
2408
- node(),
2409
- jsdoc({
2410
- stylistic: stylisticOptions
2411
- }),
2412
- imports({
2413
- stylistic: stylisticOptions
2414
- }),
2415
- command(),
2416
- // Optional plugins (installed but not enabled by default)
2417
- perfectionist()
2418
- );
2419
- if (enableUnicorn) {
2420
- configs2.push(unicorn(enableUnicorn === true ? {} : enableUnicorn));
2421
- }
2422
- if (enableVue) {
2423
- componentExts.push("vue");
2424
- }
2425
- if (enableJsx) {
2426
- configs2.push(jsx());
2427
- }
2428
- if (enableTypeScript) {
2429
- configs2.push(typescript({
2430
- ...typescriptOptions,
2431
- componentExts,
2432
- overrides: getOverrides(options, "typescript"),
2433
- type: options.type
2434
- }));
2435
- }
2436
- if (stylisticOptions) {
2437
- configs2.push(stylistic({
2438
- ...stylisticOptions,
2439
- lessOpinionated: options.lessOpinionated,
2440
- overrides: getOverrides(options, "stylistic")
2441
- }));
2442
- }
2443
- if (enableRegexp) {
2444
- configs2.push(regexp(typeof enableRegexp === "boolean" ? {} : enableRegexp));
2445
- }
2446
- if (options.test ?? true) {
2447
- configs2.push(test({
2448
- isInEditor,
2449
- overrides: getOverrides(options, "test")
2450
- }));
2451
- }
2452
- if (enableVue) {
2453
- configs2.push(vue({
2454
- ...resolveSubOptions(options, "vue"),
2455
- overrides: getOverrides(options, "vue"),
2456
- stylistic: stylisticOptions,
2457
- typescript: !!enableTypeScript
2458
- }));
2459
- }
2460
- if (enableReact) {
2461
- configs2.push(react({
2462
- overrides: getOverrides(options, "react"),
2463
- tsconfigPath
2464
- }));
2465
- }
2466
- if (enableSolid) {
2467
- configs2.push(solid({
2468
- overrides: getOverrides(options, "solid"),
2469
- tsconfigPath,
2470
- typescript: !!enableTypeScript
2471
- }));
2472
- }
2473
- if (enableSvelte) {
2474
- configs2.push(svelte({
2475
- overrides: getOverrides(options, "svelte"),
2476
- stylistic: stylisticOptions,
2477
- typescript: !!enableTypeScript
2478
- }));
2479
- }
2480
- if (enableUnoCSS) {
2481
- configs2.push(unocss({
2482
- ...resolveSubOptions(options, "unocss"),
2483
- overrides: getOverrides(options, "unocss")
2484
- }));
2485
- }
2486
- if (enableAstro) {
2487
- configs2.push(astro({
2488
- overrides: getOverrides(options, "astro"),
2489
- stylistic: stylisticOptions
2490
- }));
2491
- }
2492
- if (options.jsonc ?? true) {
2493
- configs2.push(
2494
- jsonc({
2495
- overrides: getOverrides(options, "jsonc"),
2496
- stylistic: stylisticOptions
2497
- }),
2498
- sortPackageJson(),
2499
- sortTsconfig()
2500
- );
2501
- }
2502
- if (options.yaml ?? true) {
2503
- configs2.push(yaml({
2504
- overrides: getOverrides(options, "yaml"),
2505
- stylistic: stylisticOptions
2506
- }));
2507
- }
2508
- if (options.toml ?? true) {
2509
- configs2.push(toml({
2510
- overrides: getOverrides(options, "toml"),
2511
- stylistic: stylisticOptions
2512
- }));
2513
- }
2514
- if (options.markdown ?? true) {
2515
- configs2.push(
2516
- markdown(
2517
- {
2518
- componentExts,
2519
- overrides: getOverrides(options, "markdown")
2520
- }
2521
- )
2522
- );
2523
- }
2524
- if (options.formatters) {
2525
- configs2.push(formatters(
2526
- options.formatters,
2527
- typeof stylisticOptions === "boolean" ? {} : stylisticOptions
2528
- ));
2529
- }
2530
- configs2.push(
2531
- disables()
2532
- );
2533
- if ("files" in options) {
2534
- throw new Error('[@jun2030/eslint-config] The first argument should not contain the "files" property as the options are supposed to be global. Place it in the second or later config instead.');
2535
- }
2536
- const fusedConfig = flatConfigProps.reduce((acc, key) => {
2537
- if (key in options)
2538
- acc[key] = options[key];
2539
- return acc;
2540
- }, {});
2541
- if (Object.keys(fusedConfig).length)
2542
- configs2.push([fusedConfig]);
2543
- let composer = new FlatConfigComposer();
2544
- composer = composer.append(
2545
- ...configs2,
2546
- ...userConfigs
2547
- );
2548
- if (autoRenamePlugins) {
2549
- composer = composer.renamePlugins(defaultPluginRenaming);
2550
- }
2551
- return composer;
2552
- }
2553
- function resolveSubOptions(options, key) {
2554
- return typeof options[key] === "boolean" ? {} : options[key] || {};
2555
- }
2556
- function getOverrides(options, key) {
2557
- const sub = resolveSubOptions(options, key);
2558
- return {
2559
- ...options.overrides?.[key],
2560
- ..."overrides" in sub ? sub.overrides : {}
2561
- };
2562
- }
2563
-
2564
- // src/index.ts
2565
- var src_default = jun;
2566
- export {
2567
- GLOB_ALL_SRC,
2568
- GLOB_ASTRO,
2569
- GLOB_ASTRO_TS,
2570
- GLOB_CSS,
2571
- GLOB_EXCLUDE,
2572
- GLOB_GRAPHQL,
2573
- GLOB_HTML,
2574
- GLOB_JS,
2575
- GLOB_JSON,
2576
- GLOB_JSON5,
2577
- GLOB_JSONC,
2578
- GLOB_JSX,
2579
- GLOB_LESS,
2580
- GLOB_MARKDOWN,
2581
- GLOB_MARKDOWN_CODE,
2582
- GLOB_MARKDOWN_IN_MARKDOWN,
2583
- GLOB_POSTCSS,
2584
- GLOB_SCSS,
2585
- GLOB_SRC,
2586
- GLOB_SRC_EXT,
2587
- GLOB_STYLE,
2588
- GLOB_SVELTE,
2589
- GLOB_SVG,
2590
- GLOB_TESTS,
2591
- GLOB_TOML,
2592
- GLOB_TS,
2593
- GLOB_TSX,
2594
- GLOB_VUE,
2595
- GLOB_XML,
2596
- GLOB_YAML,
2597
- StylisticConfigDefaults,
2598
- astro,
2599
- combine,
2600
- command,
2601
- comments,
2602
- src_default as default,
2603
- defaultPluginRenaming,
2604
- disables,
2605
- ensurePackages,
2606
- formatters,
2607
- getOverrides,
2608
- ignores,
2609
- imports,
2610
- interopDefault,
2611
- isInEditorEnv,
2612
- isInGitHooksOrLintStaged,
2613
- isPackageInScope,
2614
- javascript,
2615
- jsdoc,
2616
- jsonc,
2617
- jsx,
2618
- jun,
2619
- markdown,
2620
- node,
2621
- parserPlain,
2622
- perfectionist,
2623
- react,
2624
- regexp,
2625
- renamePluginInConfigs,
2626
- renameRules,
2627
- resolveSubOptions,
2628
- solid,
2629
- sortPackageJson,
2630
- sortTsconfig,
2631
- stylistic,
2632
- svelte,
2633
- test,
2634
- toArray,
2635
- toml,
2636
- typescript,
2637
- unicorn,
2638
- unocss,
2639
- vue,
2640
- yaml
2641
- };