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