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