@liwo/eslint-config 0.0.1

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