@biscuittin/eslint-config 0.0.2

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,1706 @@
1
+ import pluginESLintComments from '@eslint-community/eslint-plugin-eslint-comments';
2
+ import pluginReact from '@eslint-react/eslint-plugin';
3
+ import { eslint_plugin_jsx_a11y_minimal } from '@eslint-sukka/eslint-plugin-react-jsx-a11y';
4
+ import pluginJson from '@eslint/json';
5
+ import pluginNextJs from '@next/eslint-plugin-next';
6
+ import pluginStylisticJsx from '@stylistic/eslint-plugin-jsx';
7
+ import pluginAntfu from 'eslint-plugin-antfu';
8
+ import pluginAutofix from 'eslint-plugin-autofix';
9
+ import pluginFormat from 'eslint-plugin-format';
10
+ import pluginImportX from 'eslint-plugin-import-x';
11
+ import pluginJsonc from 'eslint-plugin-jsonc';
12
+ import pluginNode from 'eslint-plugin-n';
13
+ import pluginPerfectionist from 'eslint-plugin-perfectionist';
14
+ import * as pluginReactCompiler from 'eslint-plugin-react-compiler';
15
+ import pluginReactHooks from 'eslint-plugin-react-hooks';
16
+ import pluginReactPreferFunctionComponent from 'eslint-plugin-react-prefer-function-component';
17
+ import pluginReactRefresh from 'eslint-plugin-react-refresh';
18
+ import * as pluginRegexp from 'eslint-plugin-regexp';
19
+ import pluginTailwindCSS from 'eslint-plugin-tailwindcss';
20
+ import pluginUnicorn from 'eslint-plugin-unicorn';
21
+ import pluginUnusedImports from 'eslint-plugin-unused-imports';
22
+ import { plugin, parser, configs } from 'typescript-eslint';
23
+ import fs from 'node:fs';
24
+ import path from 'node:path';
25
+ import process from 'node:process';
26
+ import { findUp } from 'find-up';
27
+ import fsp from 'node:fs/promises';
28
+ import parserJsonc from 'jsonc-eslint-parser';
29
+ import gitignore from 'eslint-config-flat-gitignore';
30
+ import js from '@eslint/js';
31
+ import globals from 'globals';
32
+ export { default as globals } from 'globals';
33
+ import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
34
+ import { FlatConfigComposer } from 'eslint-flat-config-utils';
35
+ import { isPackageExists } from 'local-pkg';
36
+
37
+ async function combine(...configs) {
38
+ const resolved = await Promise.all(configs);
39
+ return resolved.flat();
40
+ }
41
+
42
+ function getFlatConfigName(module) {
43
+ return {
44
+ base: `@biscuittin/eslint-config/${module}`,
45
+ setup: `@biscuittin/eslint-config/${module}/setup`,
46
+ rules: `@biscuittin/eslint-config/${module}/rules`,
47
+ stylistic: `@biscuittin/eslint-config/${module}/stylistic`,
48
+ commonjs: `@biscuittin/eslint-config/${module}/commonjs`,
49
+ module: `@biscuittin/eslint-config/${module}/module`,
50
+ script: `@biscuittin/eslint-config/${module}/script`
51
+ };
52
+ }
53
+
54
+ var __defProp = Object.defineProperty;
55
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
56
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
57
+ const SKIP_TIME = 2e4;
58
+ class Cache {
59
+ constructor() {
60
+ /**
61
+ * Initialize this cache instance.
62
+ */
63
+ __publicField(this, "map", /* @__PURE__ */ new Map());
64
+ }
65
+ /**
66
+ * Get the cached value of the given key.
67
+ */
68
+ get(key) {
69
+ const entry = this.map.get(key);
70
+ const now = Date.now();
71
+ if (!entry) return null;
72
+ if (entry.expire > now) {
73
+ entry.expire = now + SKIP_TIME;
74
+ return entry.value;
75
+ }
76
+ this.map.delete(key);
77
+ return null;
78
+ }
79
+ /**
80
+ * Set the value of the given key.
81
+ */
82
+ set(key, value) {
83
+ const entry = this.map.get(key);
84
+ const expire = Date.now() + SKIP_TIME;
85
+ if (!entry) {
86
+ this.map.set(key, { value, expire });
87
+ return;
88
+ }
89
+ entry.value = value;
90
+ entry.expire = expire;
91
+ }
92
+ }
93
+ const cache = new Cache();
94
+ function readPackageJson(directory) {
95
+ const filePath = path.join(directory, "package.json");
96
+ try {
97
+ const text = fs.readFileSync(filePath, "utf8");
98
+ const data = JSON.parse(text);
99
+ if (data && typeof data === "object") {
100
+ data["filePath"] = filePath;
101
+ return data;
102
+ }
103
+ } catch {
104
+ }
105
+ return null;
106
+ }
107
+ function getPackageJson(startPath = "a.js") {
108
+ const startDirectory = path.dirname(path.resolve(startPath));
109
+ let directory = startDirectory;
110
+ let previousDirectory = "";
111
+ let data = null;
112
+ do {
113
+ data = cache.get(directory);
114
+ if (data) {
115
+ if (directory !== startDirectory) {
116
+ cache.set(startDirectory, data);
117
+ }
118
+ return data;
119
+ }
120
+ data = readPackageJson(directory);
121
+ if (data) {
122
+ cache.set(directory, data);
123
+ cache.set(startDirectory, data);
124
+ return data;
125
+ }
126
+ previousDirectory = directory;
127
+ directory = path.resolve(directory, "..");
128
+ } while (directory !== previousDirectory);
129
+ cache.set(startDirectory, null);
130
+ return null;
131
+ }
132
+
133
+ function isInGitHooksOrLintStaged() {
134
+ return !!((process.env["GIT_PARAMS"] ?? "") || (process.env["VSCODE_GIT_COMMAND"] ?? "") || process.env["npm_lifecycle_script"]?.startsWith("lint-staged"));
135
+ }
136
+
137
+ function isInEditorEnv() {
138
+ if (process.env["CI"] ?? "") return false;
139
+ if (isInGitHooksOrLintStaged()) return false;
140
+ return !!((process.env["VSCODE_PID"] ?? "") || (process.env["VSCODE_CWD"] ?? "") || (process.env["JETBRAINS_IDE"] ?? "") || (process.env["VIM"] ?? "") || (process.env["NVIM"] ?? ""));
141
+ }
142
+
143
+ async function loadLocalFile(name, cwd = process.cwd()) {
144
+ const path = await findUp(name, { cwd });
145
+ if (!path || !fs.existsSync(path)) return null;
146
+ return JSON.parse(await fsp.readFile(path, "utf8"));
147
+ }
148
+
149
+ function memo(function_, key) {
150
+ var _a;
151
+ let _key = key;
152
+ if (_key === undefined || !_key) {
153
+ if (typeof function_.toString !== "function") throw new TypeError("memo() requires a key!");
154
+ _key = function_.toString();
155
+ }
156
+ globalThis.__ESLINT_PLUGIN_MEMO__ ?? (globalThis.__ESLINT_PLUGIN_MEMO__ = {});
157
+ (_a = globalThis.__ESLINT_PLUGIN_MEMO__)[_key] || (_a[_key] = function_);
158
+ return globalThis.__ESLINT_PLUGIN_MEMO__[_key];
159
+ }
160
+
161
+ const reactPlugins = pluginReact.configs.all.plugins;
162
+ const plugins = {
163
+ pluginAntfu: memo(pluginAntfu, "eslint-plugin-antfu"),
164
+ pluginAutofix: memo(pluginAutofix, "eslint-plugin-autofix"),
165
+ pluginESLintComments: memo(
166
+ pluginESLintComments,
167
+ "eslint-plugin-eslint-comments"
168
+ ),
169
+ pluginFormat: memo(pluginFormat, "eslint-plugin-format"),
170
+ pluginImportX: memo(pluginImportX, "eslint-plugin-import-x"),
171
+ pluginJson: memo(pluginJson, "eslint-plugin-json"),
172
+ pluginJsonc: memo(pluginJsonc, "eslint-plugin-jsonc"),
173
+ pluginJsxA11y: memo(eslint_plugin_jsx_a11y_minimal, "eslint-plugin-react-jsx-a11y"),
174
+ pluginNextJs: memo(pluginNextJs, "eslint-plugin-next"),
175
+ pluginNode: memo(pluginNode, "eslint-plugin-n"),
176
+ pluginPerfectionist: memo(pluginPerfectionist, "eslint-plugin-perfectionist"),
177
+ pluginReact: memo(
178
+ reactPlugins["@eslint-react"],
179
+ "eslint-plugin-react-x"
180
+ ),
181
+ pluginReactCompiler: memo(
182
+ pluginReactCompiler,
183
+ "eslint-plugin-react-compiler"
184
+ ),
185
+ pluginReactDebug: memo(
186
+ reactPlugins["@eslint-react/debug"],
187
+ "eslint-plugin-react-debug"
188
+ ),
189
+ pluginReactDom: memo(
190
+ reactPlugins["@eslint-react/dom"],
191
+ "eslint-plugin-react-dom"
192
+ ),
193
+ pluginReactHooks: memo(pluginReactHooks, "eslint-plugin-react-hooks"),
194
+ pluginReactHooksExtra: memo(
195
+ reactPlugins["@eslint-react/hooks-extra"],
196
+ "eslint-plugin-react-hooks-extra"
197
+ ),
198
+ pluginReactHooksNamingConvention: memo(
199
+ reactPlugins["@eslint-react/naming-convention"],
200
+ "eslint-plugin-react-naming-convention"
201
+ ),
202
+ pluginReactPreferFunctionComponent: memo(
203
+ pluginReactPreferFunctionComponent,
204
+ "eslint-plugin-react-prefer-function-component"
205
+ ),
206
+ pluginReactRefresh: memo(pluginReactRefresh, "eslint-plugin-react-refresh"),
207
+ pluginReactWebApi: memo(
208
+ reactPlugins["@eslint-react/web-api"],
209
+ "eslint-plugin-react-web-api"
210
+ ),
211
+ pluginRegexp: memo(pluginRegexp, "eslint-plugin-regexp"),
212
+ pluginStylisticJsx: memo(pluginStylisticJsx, "eslint-plugin-jsx"),
213
+ pluginTailwindCSS: memo(pluginTailwindCSS, "eslint-plugin-tailwindcss"),
214
+ pluginTypescript: memo(plugin, "typescript-eslint"),
215
+ pluginUnicorn: memo(pluginUnicorn, "eslint-plugin-unicorn"),
216
+ pluginUnusedImports: memo(pluginUnusedImports, "eslint-plugin-unused-imports")
217
+ };
218
+
219
+ const name$e = getFlatConfigName("eslint-comments");
220
+ function comments() {
221
+ return [
222
+ {
223
+ name: name$e.setup,
224
+ plugins: {
225
+ "@eslint-community/eslint-comments": plugins["pluginESLintComments"]
226
+ }
227
+ },
228
+ {
229
+ name: name$e.rules,
230
+ rules: {
231
+ "@eslint-community/eslint-comments/disable-enable-pair": [
232
+ "error",
233
+ { allowWholeFile: true }
234
+ ],
235
+ "@eslint-community/eslint-comments/no-aggregating-enable": "error",
236
+ "@eslint-community/eslint-comments/no-duplicate-disable": "error",
237
+ "@eslint-community/eslint-comments/no-unlimited-disable": "error",
238
+ "@eslint-community/eslint-comments/no-unused-enable": "error",
239
+ "@eslint-community/eslint-comments/require-description": "error"
240
+ }
241
+ }
242
+ ];
243
+ }
244
+
245
+ const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
246
+ const GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
247
+ const GLOB_JS = "**/*.?([cm])js";
248
+ const GLOB_JSX = "**/*.?([cm])jsx";
249
+ const GLOB_TS = "**/*.?([cm])ts";
250
+ const GLOB_TSX = "**/*.?([cm])tsx";
251
+ const GLOB_STYLE = "**/*.{c,le,sc}ss";
252
+ const GLOB_POSTCSS = "**/*.{p,post}css";
253
+ const GLOB_JSON = "**/*.json";
254
+ const GLOB_JSON5 = "**/*.json5";
255
+ const GLOB_JSONC = "**/*.jsonc";
256
+ const GLOB_MARKDOWN = "**/*.md";
257
+ const GLOB_SVELTE = "**/*.svelte";
258
+ const GLOB_VUE = "**/*.vue";
259
+ const GLOB_YAML = "**/*.y?(a)ml";
260
+ const GLOB_TOML = "**/*.toml";
261
+ const GLOB_XML = "**/*.xml";
262
+ const GLOB_HTML = "**/*.htm?(l)";
263
+ const GLOB_SVG = "**/*.svg";
264
+ const GLOB_ASTRO = "**/*.astro";
265
+ const GLOB_ALL_SRC = [
266
+ GLOB_SRC,
267
+ GLOB_STYLE,
268
+ GLOB_POSTCSS,
269
+ GLOB_JSON,
270
+ GLOB_JSON5,
271
+ GLOB_JSONC,
272
+ GLOB_MARKDOWN,
273
+ GLOB_SVELTE,
274
+ GLOB_VUE,
275
+ GLOB_YAML,
276
+ GLOB_TOML,
277
+ GLOB_XML,
278
+ GLOB_HTML,
279
+ GLOB_SVG,
280
+ GLOB_ASTRO
281
+ ];
282
+ const GLOB_EXCLUDE = [
283
+ "**/node_modules",
284
+ "**/dist",
285
+ "**/package-lock.json",
286
+ "**/yarn.lock",
287
+ "**/pnpm-lock.yaml",
288
+ "**/bun.lockb",
289
+ "**/output",
290
+ "**/coverage",
291
+ "**/temp",
292
+ "**/.temp",
293
+ "**/tmp",
294
+ "**/.tmp",
295
+ "**/.history",
296
+ "**/.vitepress/cache",
297
+ "**/.nuxt",
298
+ "**/.next",
299
+ "**/.svelte-kit",
300
+ "**/.vercel",
301
+ "**/.changeset",
302
+ "**/.idea",
303
+ "**/.cache",
304
+ "**/.output",
305
+ "**/.vite-inspect",
306
+ "**/.yarn",
307
+ "**/vite.config.*.timestamp-*",
308
+ "**/CHANGELOG*.md",
309
+ "**/*.min.*",
310
+ "**/LICENSE*",
311
+ "**/__snapshots__",
312
+ "**/auto-import?(s).d.ts",
313
+ "**/components.d.ts"
314
+ ];
315
+
316
+ const name$d = getFlatConfigName("disables");
317
+ function disables() {
318
+ return [
319
+ {
320
+ name: name$d.script,
321
+ files: [`**/scripts/${GLOB_SRC}`],
322
+ rules: {
323
+ "antfu/no-top-level-await": "off",
324
+ "no-console": "off",
325
+ "@typescript-eslint/explicit-function-return-type": "off"
326
+ }
327
+ },
328
+ {
329
+ name: `${name$d.base}/cli`,
330
+ files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
331
+ rules: {
332
+ "antfu/no-top-level-await": "off",
333
+ "no-console": "off"
334
+ }
335
+ },
336
+ {
337
+ name: `${name$d.base}/bin`,
338
+ files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
339
+ rules: {
340
+ "antfu/no-import-dist": "off",
341
+ "antfu/no-import-node-modules-by-path": "off"
342
+ }
343
+ },
344
+ {
345
+ name: `${name$d.base}/dts`,
346
+ files: ["**/*.d.?([cm])ts"],
347
+ rules: {
348
+ "@typescript-eslint/no-empty-object-type": ["error", { allowInterfaces: "always" }],
349
+ "@eslint-community/eslint-comments/no-unlimited-disable": "off",
350
+ "import-x/no-duplicates": "off",
351
+ "no-restricted-syntax": "off",
352
+ "unused-imports/no-unused-vars": "off"
353
+ }
354
+ },
355
+ {
356
+ name: name$d.commonjs,
357
+ files: ["**/*.js", "**/*.cjs"],
358
+ rules: {
359
+ "@typescript-eslint/no-require-imports": "off"
360
+ }
361
+ },
362
+ {
363
+ name: `${name$d.base}/config-files`,
364
+ files: [`**/*.config.${GLOB_SRC_EXT}`, `**/*.config.*.${GLOB_SRC_EXT}`],
365
+ rules: {
366
+ "antfu/no-top-level-await": "off",
367
+ "no-console": "off",
368
+ "@typescript-eslint/explicit-function-return-type": "off"
369
+ }
370
+ }
371
+ ];
372
+ }
373
+
374
+ const parsers = {
375
+ parserJsonc,
376
+ parserPlain: pluginFormat.parserPlain,
377
+ parserTypescript: parser
378
+ };
379
+
380
+ const quoteStyleMap = {
381
+ single: "preferSingle",
382
+ double: "preferDouble"
383
+ };
384
+ const trailingCommasMap = {
385
+ none: "never",
386
+ all: "always",
387
+ multiline: "onlyMultiLine"
388
+ };
389
+ const name$c = getFlatConfigName("formatters");
390
+ async function formatters(options = {}) {
391
+ const {
392
+ dprintConfigPath = "dprint.json",
393
+ printWidth = 120,
394
+ indentWidth = 2,
395
+ useTabs = false,
396
+ semi = false,
397
+ quotes = "single",
398
+ jsxQuotes = "double",
399
+ trailingComma = "multiline",
400
+ endOfLine = "lf",
401
+ extraJsonFiles = []
402
+ } = options;
403
+ const dprintConfig = await loadLocalFile(dprintConfigPath);
404
+ function hasPlugin(name2) {
405
+ return dprintConfig?.plugins.some((url) => url.includes(name2)) ?? false;
406
+ }
407
+ function getPluginUrl(name2) {
408
+ return dprintConfig?.plugins.find((url) => url.includes(name2)) ?? name2;
409
+ }
410
+ const lineWidth = printWidth;
411
+ const newLineKind = endOfLine;
412
+ const lineBreak = newLineKind === "lf" ? "lf" : "crlf";
413
+ return [
414
+ {
415
+ name: name$c.setup,
416
+ plugins: {
417
+ format: plugins["pluginFormat"]
418
+ }
419
+ },
420
+ {
421
+ name: `${name$c.rules}/typescript`,
422
+ files: [GLOB_SRC],
423
+ rules: hasPlugin("typescript") ? {
424
+ "format/dprint": ["error", {
425
+ language: getPluginUrl("typescript"),
426
+ languageOptions: {
427
+ lineWidth,
428
+ indentWidth,
429
+ useTabs,
430
+ newLineKind,
431
+ semiColons: semi ? "always" : "asi",
432
+ quoteStyle: quoteStyleMap[quotes],
433
+ "jsx.quoteStyle": quoteStyleMap[jsxQuotes],
434
+ trailingCommas: trailingCommasMap[trailingComma],
435
+ ...dprintConfig?.typescript
436
+ }
437
+ }]
438
+ } : {}
439
+ },
440
+ {
441
+ name: `${name$c.rules}/json`,
442
+ files: [GLOB_JSON, GLOB_JSON5, GLOB_JSONC, ...extraJsonFiles],
443
+ rules: hasPlugin("json") ? {
444
+ // dprint handles the indent
445
+ "jsonc/indent": "off",
446
+ "format/dprint": ["error", {
447
+ language: getPluginUrl("json"),
448
+ languageOptions: {
449
+ lineWidth,
450
+ indentWidth,
451
+ useTabs,
452
+ newLineKind,
453
+ ...dprintConfig?.json
454
+ }
455
+ }]
456
+ } : {}
457
+ },
458
+ {
459
+ name: `${name$c.rules}/markdown`,
460
+ files: [GLOB_MARKDOWN],
461
+ languageOptions: {
462
+ parser: parsers["parserPlain"]
463
+ },
464
+ rules: hasPlugin("markdown") ? {
465
+ "format/dprint": ["error", {
466
+ language: getPluginUrl("markdown"),
467
+ languageOptions: {
468
+ lineWidth,
469
+ newLineKind,
470
+ ...dprintConfig?.markdown
471
+ }
472
+ }]
473
+ } : {}
474
+ },
475
+ {
476
+ name: `${name$c.rules}/malva`,
477
+ files: [GLOB_STYLE, GLOB_POSTCSS],
478
+ languageOptions: {
479
+ parser: parsers["parserPlain"]
480
+ },
481
+ rules: hasPlugin("malva") ? {
482
+ "format/dprint": ["error", {
483
+ language: getPluginUrl("malva"),
484
+ languageOptions: {
485
+ printWidth,
486
+ useTabs,
487
+ indentWidth,
488
+ lineBreak,
489
+ trailingComma: trailingComma === "all" ? true : false,
490
+ ...dprintConfig?.malva
491
+ }
492
+ }]
493
+ } : {}
494
+ },
495
+ {
496
+ name: `${name$c.rules}/markup`,
497
+ files: [GLOB_HTML, GLOB_VUE, GLOB_SVELTE, GLOB_ASTRO],
498
+ languageOptions: {
499
+ parser: parsers["parserPlain"]
500
+ },
501
+ rules: hasPlugin("markup") ? {
502
+ "format/dprint": ["error", {
503
+ language: getPluginUrl("markup"),
504
+ languageOptions: {
505
+ printWidth,
506
+ useTabs,
507
+ indentWidth,
508
+ lineBreak,
509
+ ...dprintConfig?.markup
510
+ }
511
+ }]
512
+ } : {}
513
+ },
514
+ {
515
+ name: `${name$c.rules}/yaml`,
516
+ files: [GLOB_YAML],
517
+ languageOptions: {
518
+ parser: parsers["parserPlain"]
519
+ },
520
+ rules: hasPlugin("yaml") ? {
521
+ "format/dprint": ["error", {
522
+ language: getPluginUrl("yaml"),
523
+ languageOptions: {
524
+ printWidth,
525
+ indentWidth,
526
+ lineBreak,
527
+ quotes: quoteStyleMap[quotes],
528
+ trailingComma: trailingComma === "none" ? false : true,
529
+ ...dprintConfig?.yaml
530
+ }
531
+ }]
532
+ } : {}
533
+ }
534
+ ];
535
+ }
536
+
537
+ const name$b = getFlatConfigName("ignores");
538
+ function ignores(userIgnores = []) {
539
+ return [
540
+ {
541
+ name: `${name$b.base}/files`,
542
+ ignores: [...GLOB_EXCLUDE, ...userIgnores]
543
+ },
544
+ gitignore({ name: `${name$b.base}/gitignore` })
545
+ ];
546
+ }
547
+
548
+ const name$a = getFlatConfigName("imports");
549
+ const files$6 = [GLOB_SRC];
550
+ function imports(options = {}) {
551
+ const {
552
+ tsconfigRootDir = process.cwd()
553
+ } = options;
554
+ return [
555
+ {
556
+ name: name$a.setup,
557
+ files: files$6,
558
+ plugins: {
559
+ "import-x": plugins["pluginImportX"],
560
+ "unused-imports": plugins["pluginUnusedImports"],
561
+ antfu: plugins["pluginAntfu"],
562
+ perfectionist: plugins["pluginPerfectionist"]
563
+ },
564
+ languageOptions: {
565
+ sourceType: "module",
566
+ ecmaVersion: "latest"
567
+ }
568
+ },
569
+ {
570
+ name: name$a.rules,
571
+ files: files$6,
572
+ rules: {
573
+ // eslint-plugin-import-x
574
+ // https://github.com/un-ts/eslint-plugin-import-x
575
+ ...pluginImportX.configs.recommended.rules,
576
+ // Copied from SukkaW/eslint-config-sukka
577
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/bbca2d568d738a1d287c473804ea8ccbf00d3c86/packages/eslint-config-sukka/src/modules/javascript.ts#L122
578
+ "import-x/newline-after-import": ["error", { considerComments: false }],
579
+ "import-x/no-absolute-path": "error",
580
+ "import-x/no-empty-named-blocks": "error",
581
+ "import-x/no-mutable-exports": "error",
582
+ "import-x/no-useless-path-segments": "warn",
583
+ "import-x/no-webpack-loader-syntax": "error",
584
+ // prevent monorepo sibling imports
585
+ "import-x/no-relative-packages": "warn",
586
+ // eslint-plugin-unused-imports
587
+ // https://github.com/sweepline/eslint-plugin-unused-imports
588
+ "unused-imports/no-unused-imports": "error",
589
+ // eslint-plugin-antfu
590
+ // https://github.com/antfu/eslint-plugin-antfu
591
+ "antfu/import-dedupe": "error",
592
+ "antfu/no-import-dist": "error",
593
+ "antfu/no-import-node-modules-by-path": "error"
594
+ }
595
+ },
596
+ {
597
+ name: name$a.stylistic,
598
+ files: files$6,
599
+ rules: {
600
+ // rules that conflict with eslint-plugin-perfectionist are disabled.
601
+ "sort-imports": "off",
602
+ // eslint-plugin-perfectionist
603
+ // https://github.com/azat-io/eslint-plugin-perfectionist
604
+ "perfectionist/sort-imports": ["error", {
605
+ groups: [
606
+ "type",
607
+ ["builtin", "external"],
608
+ "internal-type",
609
+ "internal",
610
+ ["parent-type", "sibling-type", "index-type"],
611
+ ["parent", "sibling", "index"],
612
+ "object",
613
+ "unknown"
614
+ ],
615
+ tsconfigRootDir,
616
+ order: "asc",
617
+ type: "natural"
618
+ }],
619
+ "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
620
+ "perfectionist/sort-named-imports": ["error", { order: "asc", type: "natural" }],
621
+ "perfectionist/sort-named-exports": ["error", { order: "asc", type: "natural" }]
622
+ }
623
+ }
624
+ ];
625
+ }
626
+
627
+ const name$9 = getFlatConfigName("javascript");
628
+ const files$5 = [GLOB_SRC];
629
+ const commonjsGlobalsOffList = Object.keys(globals.commonjs).map((key) => ({ [key]: "off" }));
630
+ const commonjsGlobalsOff = Object.assign({}, ...commonjsGlobalsOffList);
631
+ function javascript(options = {}) {
632
+ const { env = { browser: true }, module = true } = options;
633
+ const sourceType = module ? "module" : "commonjs";
634
+ return [
635
+ {
636
+ name: name$9.setup,
637
+ files: files$5,
638
+ plugins: {
639
+ "import-x": plugins["pluginImportX"],
640
+ "unused-imports": plugins["pluginUnusedImports"],
641
+ autofix: plugins["pluginAutofix"],
642
+ antfu: plugins["pluginAntfu"]
643
+ },
644
+ linterOptions: {
645
+ reportUnusedDisableDirectives: true
646
+ },
647
+ languageOptions: {
648
+ // https://eslint.org/docs/latest/use/configure/language-options
649
+ sourceType,
650
+ ecmaVersion: "latest",
651
+ parserOptions: {
652
+ // https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options
653
+ ecmaFeatures: {
654
+ impliedStrict: true
655
+ }
656
+ },
657
+ globals: {
658
+ // https://eslint.org/docs/latest/use/configure/language-options#specifying-globals
659
+ ...globals.es2025,
660
+ ...module ? {} : globals.commonjs,
661
+ ...env.browser ? globals.browser : {},
662
+ ...env.customGlobals
663
+ }
664
+ },
665
+ settings: {
666
+ "import-x/extensions": [".js", ".jsx", ".cjs", ".mjs"]
667
+ }
668
+ },
669
+ {
670
+ name: name$9.commonjs,
671
+ files: ["**/*.cjs"],
672
+ languageOptions: {
673
+ sourceType: "commonjs",
674
+ globals: {
675
+ ...globals.commonjs
676
+ }
677
+ }
678
+ },
679
+ {
680
+ name: name$9.module,
681
+ files: ["**/*.mjs"],
682
+ languageOptions: {
683
+ sourceType: "module",
684
+ globals: {
685
+ ...commonjsGlobalsOff
686
+ }
687
+ }
688
+ },
689
+ {
690
+ name: name$9.rules,
691
+ files: files$5,
692
+ rules: {
693
+ ...js.configs.recommended.rules,
694
+ // Copied from SukkaW/eslint-config-sukka
695
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L451
696
+ "no-unused-vars": [
697
+ "error",
698
+ {
699
+ vars: "all",
700
+ varsIgnorePattern: "^_",
701
+ args: "after-used",
702
+ argsIgnorePattern: "^_",
703
+ ignoreRestSiblings: true
704
+ }
705
+ ],
706
+ "unused-imports/no-unused-vars": "off",
707
+ // disallow use of arguments.caller or arguments.callee
708
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L191
709
+ "no-caller": "off",
710
+ "autofix/no-caller": "error",
711
+ // disallow usage of __proto__ property
712
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L275
713
+ "no-proto": "off",
714
+ "autofix/no-proto": "error",
715
+ // disallow unnecessary catch clauses
716
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L343
717
+ "no-useless-catch": "off",
718
+ "autofix/no-useless-catch": "error",
719
+ // disallow useless string concatenation
720
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L348
721
+ "no-useless-concat": "off",
722
+ "autofix/no-useless-concat": "error",
723
+ // require use of the second argument for parseInt()
724
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L382
725
+ radix: "off",
726
+ "autofix/radix": "error",
727
+ // ensure that the results of typeof are compared against a valid string
728
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L478
729
+ "valid-typeof": "off",
730
+ "autofix/valid-typeof": ["error", { requireStringLiterals: true }],
731
+ // disallow new operators with global non-constructor functions
732
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L483
733
+ "no-new-native-nonconstructor": "off",
734
+ "autofix/no-new-native-nonconstructor": "error",
735
+ // disallow use of Object.prototypes builtins directly
736
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3b1c6e5098bd92459237b637a3a63aa60d4cb326/packages/eslint-config-sukka/src/modules/javascript.ts#L1069
737
+ "no-prototype-builtins": "off",
738
+ "autofix/no-prototype-builtins": "error",
739
+ // eslint-plugin-antfu
740
+ // https://github.com/antfu/eslint-plugin-antfu
741
+ "antfu/no-top-level-await": "error",
742
+ "antfu/top-level-function": "error"
743
+ }
744
+ }
745
+ ];
746
+ }
747
+
748
+ const name$8 = getFlatConfigName("json");
749
+ const jsoncRecommendedWithJsonRuleList = pluginJsonc.configs["flat/recommended-with-json"].map(
750
+ (config) => config.rules
751
+ );
752
+ const jsoncRecommendedWithJsonRules = Object.assign(
753
+ {},
754
+ ...jsoncRecommendedWithJsonRuleList
755
+ );
756
+ function json(options = {}) {
757
+ const { extraFiles = [], stylistic = { indentWidth: 2 } } = options;
758
+ const { indentWidth = 2 } = typeof stylistic === "object" ? stylistic : { indentWidth: 2 };
759
+ const files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC, ...extraFiles];
760
+ return [
761
+ {
762
+ name: name$8.setup,
763
+ files,
764
+ plugins: {
765
+ json: plugins["pluginJson"],
766
+ jsonc: plugins["pluginJsonc"]
767
+ },
768
+ languageOptions: {
769
+ parser: parsers["parserJsonc"]
770
+ }
771
+ },
772
+ {
773
+ name: name$8.rules,
774
+ files,
775
+ rules: {
776
+ // @eslint/json
777
+ // https://github.com/eslint/json
778
+ "json/no-duplicate-keys": "error",
779
+ "json/no-empty-keys": "error",
780
+ "json/no-unsafe-values": "error",
781
+ "json/no-unnormalized-keys": "error",
782
+ "json/top-level-interop": "error",
783
+ // eslint-plugin-jsonc
784
+ // https://github.com/ota-meshi/eslint-plugin-jsonc
785
+ // flat/recommended-with-json
786
+ ...jsoncRecommendedWithJsonRules
787
+ }
788
+ },
789
+ {
790
+ name: name$8.stylistic,
791
+ files,
792
+ rules: stylistic ? {
793
+ // Copied from antfu/eslint-config
794
+ // Ref: https://github.com/antfu/eslint-config/blob/5d0c2a5ef25a7bc3a2d6d55c1ce157cc47b0bf55/src/configs/jsonc.ts#L70
795
+ "jsonc/array-bracket-spacing": ["error", "never"],
796
+ "jsonc/comma-dangle": ["error", "never"],
797
+ "jsonc/comma-style": ["error", "last"],
798
+ "jsonc/indent": ["error", indentWidth],
799
+ "jsonc/key-spacing": ["error", { afterColon: true, beforeColon: false }],
800
+ "jsonc/object-curly-newline": ["error", { consistent: true, multiline: true }],
801
+ "jsonc/object-curly-spacing": ["error", "always"],
802
+ "jsonc/object-property-newline": [
803
+ "error",
804
+ { allowMultiplePropertiesPerLine: true }
805
+ ],
806
+ "jsonc/quote-props": "error",
807
+ "jsonc/quotes": "error"
808
+ } : {}
809
+ },
810
+ {
811
+ name: `${name$8.base}/package-json`,
812
+ files: ["**/package.json"],
813
+ // Copied from antfu/eslint-config
814
+ // Ref: https://github.com/antfu/eslint-config/blob/5d0c2a5ef25a7bc3a2d6d55c1ce157cc47b0bf55/src/configs/sort.ts#L13
815
+ rules: {
816
+ "jsonc/sort-array-values": [
817
+ "error",
818
+ {
819
+ order: { type: "asc" },
820
+ pathPattern: "^files$"
821
+ }
822
+ ],
823
+ "jsonc/sort-keys": [
824
+ "error",
825
+ {
826
+ order: [
827
+ "publisher",
828
+ "name",
829
+ "displayName",
830
+ "type",
831
+ "version",
832
+ "private",
833
+ "packageManager",
834
+ "description",
835
+ "author",
836
+ "contributors",
837
+ "license",
838
+ "funding",
839
+ "homepage",
840
+ "repository",
841
+ "bugs",
842
+ "keywords",
843
+ "categories",
844
+ "sideEffects",
845
+ "exports",
846
+ "main",
847
+ "module",
848
+ "unpkg",
849
+ "jsdelivr",
850
+ "types",
851
+ "typesVersions",
852
+ "bin",
853
+ "icon",
854
+ "files",
855
+ "engines",
856
+ "activationEvents",
857
+ "contributes",
858
+ "publishConfig",
859
+ "scripts",
860
+ "peerDependencies",
861
+ "peerDependenciesMeta",
862
+ "dependencies",
863
+ "optionalDependencies",
864
+ "devDependencies",
865
+ "pnpm",
866
+ "overrides",
867
+ "resolutions",
868
+ "husky",
869
+ "simple-git-hooks",
870
+ "lint-staged",
871
+ "eslintConfig"
872
+ ],
873
+ pathPattern: "^$"
874
+ },
875
+ {
876
+ order: { type: "asc" },
877
+ pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
878
+ },
879
+ {
880
+ order: { type: "asc" },
881
+ pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
882
+ },
883
+ {
884
+ order: ["types", "import", "require", "default"],
885
+ pathPattern: "^exports.*$"
886
+ },
887
+ {
888
+ order: [
889
+ // client hooks only
890
+ "pre-commit",
891
+ "prepare-commit-msg",
892
+ "commit-msg",
893
+ "post-commit",
894
+ "pre-rebase",
895
+ "post-rewrite",
896
+ "post-checkout",
897
+ "post-merge",
898
+ "pre-push",
899
+ "pre-auto-gc"
900
+ ],
901
+ pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
902
+ }
903
+ ]
904
+ }
905
+ },
906
+ {
907
+ name: `${name$8.base}/tsconfig-json`,
908
+ files: ["**/tsconfig.json", "**/tsconfig.*.json"],
909
+ // Copied from antfu/eslint-config
910
+ // Ref: https://github.com/antfu/eslint-config/blob/5d0c2a5ef25a7bc3a2d6d55c1ce157cc47b0bf55/src/configs/sort.ts#L121
911
+ rules: {
912
+ "jsonc/sort-keys": [
913
+ "error",
914
+ {
915
+ order: ["extends", "compilerOptions", "references", "files", "include", "exclude"],
916
+ pathPattern: "^$"
917
+ },
918
+ {
919
+ order: [
920
+ /* Projects */
921
+ "incremental",
922
+ "composite",
923
+ "tsBuildInfoFile",
924
+ "disableSourceOfProjectReferenceRedirect",
925
+ "disableSolutionSearching",
926
+ "disableReferencedProjectLoad",
927
+ /* Language and Environment */
928
+ "target",
929
+ "jsx",
930
+ "jsxFactory",
931
+ "jsxFragmentFactory",
932
+ "jsxImportSource",
933
+ "lib",
934
+ "moduleDetection",
935
+ "noLib",
936
+ "reactNamespace",
937
+ "useDefineForClassFields",
938
+ "emitDecoratorMetadata",
939
+ "experimentalDecorators",
940
+ /* Modules */
941
+ "baseUrl",
942
+ "rootDir",
943
+ "rootDirs",
944
+ "customConditions",
945
+ "module",
946
+ "moduleResolution",
947
+ "moduleSuffixes",
948
+ "noResolve",
949
+ "paths",
950
+ "resolveJsonModule",
951
+ "resolvePackageJsonExports",
952
+ "resolvePackageJsonImports",
953
+ "typeRoots",
954
+ "types",
955
+ "allowArbitraryExtensions",
956
+ "allowImportingTsExtensions",
957
+ "allowUmdGlobalAccess",
958
+ /* JavaScript Support */
959
+ "allowJs",
960
+ "checkJs",
961
+ "maxNodeModuleJsDepth",
962
+ /* Type Checking */
963
+ "strict",
964
+ "strictBindCallApply",
965
+ "strictFunctionTypes",
966
+ "strictNullChecks",
967
+ "strictPropertyInitialization",
968
+ "allowUnreachableCode",
969
+ "allowUnusedLabels",
970
+ "alwaysStrict",
971
+ "exactOptionalPropertyTypes",
972
+ "noFallthroughCasesInSwitch",
973
+ "noImplicitAny",
974
+ "noImplicitOverride",
975
+ "noImplicitReturns",
976
+ "noImplicitThis",
977
+ "noPropertyAccessFromIndexSignature",
978
+ "noUncheckedIndexedAccess",
979
+ "noUnusedLocals",
980
+ "noUnusedParameters",
981
+ "useUnknownInCatchVariables",
982
+ /* Emit */
983
+ "declaration",
984
+ "declarationDir",
985
+ "declarationMap",
986
+ "downlevelIteration",
987
+ "emitBOM",
988
+ "emitDeclarationOnly",
989
+ "importHelpers",
990
+ "importsNotUsedAsValues",
991
+ "inlineSourceMap",
992
+ "inlineSources",
993
+ "mapRoot",
994
+ "newLine",
995
+ "noEmit",
996
+ "noEmitHelpers",
997
+ "noEmitOnError",
998
+ "outDir",
999
+ "outFile",
1000
+ "preserveConstEnums",
1001
+ "preserveValueImports",
1002
+ "removeComments",
1003
+ "sourceMap",
1004
+ "sourceRoot",
1005
+ "stripInternal",
1006
+ /* Interop Constraints */
1007
+ "allowSyntheticDefaultImports",
1008
+ "esModuleInterop",
1009
+ "forceConsistentCasingInFileNames",
1010
+ "isolatedDeclarations",
1011
+ "isolatedModules",
1012
+ "preserveSymlinks",
1013
+ "verbatimModuleSyntax",
1014
+ /* Completeness */
1015
+ "skipDefaultLibCheck",
1016
+ "skipLibCheck"
1017
+ ],
1018
+ pathPattern: "^compilerOptions$"
1019
+ }
1020
+ ]
1021
+ }
1022
+ }
1023
+ ];
1024
+ }
1025
+
1026
+ const name$7 = getFlatConfigName("jsx");
1027
+ function jsx() {
1028
+ return [
1029
+ {
1030
+ name: name$7.setup,
1031
+ files: [GLOB_JSX, GLOB_TSX],
1032
+ languageOptions: {
1033
+ parserOptions: {
1034
+ ecmaFeatures: {
1035
+ jsx: true
1036
+ }
1037
+ }
1038
+ }
1039
+ }
1040
+ ];
1041
+ }
1042
+
1043
+ const name$6 = getFlatConfigName("next-js");
1044
+ const files$4 = [GLOB_SRC];
1045
+ function nextJs() {
1046
+ return [
1047
+ {
1048
+ name: name$6.setup,
1049
+ files: files$4,
1050
+ plugins: {
1051
+ "@next/next": plugins["pluginNextJs"],
1052
+ "react-refresh": plugins["pluginReactRefresh"]
1053
+ }
1054
+ },
1055
+ {
1056
+ name: name$6.rules,
1057
+ files: files$4,
1058
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- Next.js ESLint plugin missing types
1059
+ rules: {
1060
+ // @next/eslint-plugin-next
1061
+ // https://www.npmjs.com/package/@next/eslint-plugin-next
1062
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Next.js ESLint plugin missing types
1063
+ ...pluginNextJs?.configs?.recommended?.rules,
1064
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Next.js ESLint plugin missing types
1065
+ ...pluginNextJs?.configs["core-web-vitals"].rules,
1066
+ // eslint-plugin-react-refresh
1067
+ // https://github.com/ArnaudBarre/eslint-plugin-react-refresh
1068
+ "react-refresh/only-export-components": ["warn", {
1069
+ allowExportNames: [
1070
+ "config",
1071
+ "generateStaticParams",
1072
+ "metadata",
1073
+ "generateMetadata",
1074
+ "viewport",
1075
+ "generateViewport"
1076
+ ]
1077
+ }]
1078
+ }
1079
+ }
1080
+ ];
1081
+ }
1082
+
1083
+ const name$5 = getFlatConfigName("node-js");
1084
+ const isModule = getPackageJson()?.type === "module";
1085
+ function nodeJs(options = {}) {
1086
+ const { module = isModule, extraFiles = [] } = options;
1087
+ const files = [GLOB_JS, ...extraFiles];
1088
+ return [
1089
+ {
1090
+ name: name$5.setup,
1091
+ files,
1092
+ plugins: {
1093
+ node: plugins["pluginNode"]
1094
+ },
1095
+ languageOptions: {
1096
+ sourceType: module ? "module" : "commonjs",
1097
+ ecmaVersion: "latest",
1098
+ parserOptions: {
1099
+ ecmaFeatures: {
1100
+ impliedStrict: true
1101
+ }
1102
+ },
1103
+ globals: {
1104
+ ...globals.es2025,
1105
+ ...globals.node,
1106
+ ...module ? {
1107
+ __dirname: "off",
1108
+ __filename: "off",
1109
+ exports: "off",
1110
+ module: "off",
1111
+ require: "off"
1112
+ } : {
1113
+ ...globals.commonjs,
1114
+ __dirname: "readonly",
1115
+ __filename: "readonly"
1116
+ }
1117
+ }
1118
+ }
1119
+ },
1120
+ {
1121
+ name: name$5.rules,
1122
+ files,
1123
+ rules: {
1124
+ // eslint-plugin-n
1125
+ // pluginNode.configs.commons
1126
+ // Ref: https://github.com/eslint-community/eslint-plugin-n/blob/ccf5f9e482c32f2fd2d5f78649d7f837a5db8870/lib/configs/_commons.js#L6
1127
+ "node/no-deprecated-api": "error",
1128
+ "node/no-extraneous-import": "error",
1129
+ "node/no-extraneous-require": "error",
1130
+ "node/no-exports-assign": "error",
1131
+ "node/no-missing-import": "error",
1132
+ "node/no-missing-require": "error",
1133
+ "node/no-process-exit": "error",
1134
+ "node/no-unpublished-bin": "error",
1135
+ "node/no-unpublished-import": "error",
1136
+ "node/no-unpublished-require": "error",
1137
+ "node/no-unsupported-features/es-builtins": "error",
1138
+ "node/no-unsupported-features/es-syntax": ["error", { ignores: ["modules"] }],
1139
+ "node/no-unsupported-features/node-builtins": "error",
1140
+ "node/process-exit-as-throw": "error",
1141
+ "node/hashbang": "error",
1142
+ // Require error handling in callbacks
1143
+ "node/handle-callback-err": ["error", "^error$"],
1144
+ // Disallow `new` operators with calls to `require`
1145
+ "node/no-new-require": "error",
1146
+ // Disallow string concatenation with `__dirname` and `__filename`
1147
+ "node/no-path-concat": "error",
1148
+ // Bundler specific rules
1149
+ "node/prefer-global/buffer": ["error", "never"],
1150
+ "node/prefer-global/console": ["error", "always"],
1151
+ "node/prefer-global/process": ["error", "never"],
1152
+ "node/prefer-global/text-decoder": ["error", "always"],
1153
+ "node/prefer-global/text-encoder": ["error", "always"],
1154
+ "node/prefer-global/url": ["error", "always"],
1155
+ "node/prefer-global/url-search-params": ["error", "always"],
1156
+ ...!module && {
1157
+ strict: ["error", "global"],
1158
+ "node/no-unsupported-features/es-syntax": ["error", { ignores: [] }]
1159
+ }
1160
+ }
1161
+ },
1162
+ {
1163
+ name: name$5.commonjs,
1164
+ files: ["*.c[jt]s", ".*.c[jt]s"],
1165
+ languageOptions: {
1166
+ sourceType: "commonjs",
1167
+ globals: {
1168
+ ...globals.commonjs,
1169
+ __dirname: "readonly",
1170
+ __filename: "readonly"
1171
+ }
1172
+ },
1173
+ rules: {
1174
+ strict: ["error", "global"],
1175
+ "node/no-unsupported-features/es-syntax": ["error", { ignores: [] }]
1176
+ }
1177
+ }
1178
+ ];
1179
+ }
1180
+
1181
+ const name$4 = getFlatConfigName("react");
1182
+ const files$3 = [GLOB_SRC];
1183
+ function react(options = {}) {
1184
+ const { stylistic = true, reactCompiler = false } = options;
1185
+ return [
1186
+ {
1187
+ name: name$4.setup,
1188
+ files: files$3,
1189
+ plugins: {
1190
+ "react-hooks": plugins["pluginReactHooks"],
1191
+ "react-compiler": plugins["pluginReactCompiler"],
1192
+ "react-refresh": plugins["pluginReactRefresh"],
1193
+ "react-prefer-function-component": plugins["pluginReactPreferFunctionComponent"],
1194
+ "jsx-a11y": plugins["pluginJsxA11y"],
1195
+ "@stylistic/jsx": plugins["pluginStylisticJsx"],
1196
+ "@eslint-react": plugins["pluginReact"],
1197
+ "@eslint-react/dom": plugins["pluginReactDom"],
1198
+ "@eslint-react/web-api": plugins["pluginReactWebApi"],
1199
+ "@eslint-react/debug": plugins["pluginReactDebug"],
1200
+ "@eslint-react/hooks-extra": plugins["pluginReactHooksExtra"],
1201
+ "@eslint-react/naming-convention": plugins["pluginReactHooksNamingConvention"]
1202
+ },
1203
+ settings: {
1204
+ "react-x": {
1205
+ additionalHooks: {
1206
+ useLayoutEffect: ["useIsomorphicLayoutEffect"]
1207
+ },
1208
+ polymorphicPropName: "as",
1209
+ strictImportCheck: true,
1210
+ version: "detect"
1211
+ }
1212
+ }
1213
+ },
1214
+ {
1215
+ name: name$4.rules,
1216
+ files: files$3,
1217
+ rules: {
1218
+ // eslint-plugin-react-hooks
1219
+ // https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks
1220
+ "react-hooks/rules-of-hooks": "error",
1221
+ "react-hooks/exhaustive-deps": "error",
1222
+ // eslint-plugin-react-compiler
1223
+ // https://github.com/facebook/react/tree/main/compiler/packages/eslint-plugin-react-compiler
1224
+ "react-compiler/react-compiler": reactCompiler ? "error" : "off",
1225
+ // eslint-plugin-react-refresh
1226
+ // https://github.com/ArnaudBarre/eslint-plugin-react-refresh
1227
+ "react-refresh/only-export-components": "warn",
1228
+ // eslint-plugin-react-prefer-function-component
1229
+ // https://github.com/tatethurston/eslint-plugin-react-prefer-function-component
1230
+ "react-prefer-function-component/react-prefer-function-component": "error",
1231
+ // @eslint-sukka/eslint-plugin-react-jsx-a11y
1232
+ // https://github.com/SukkaW/eslint-config-sukka/tree/master/packages/eslint-plugin-react-jsx-a11y
1233
+ // Copied from SukkaW/eslint-config-sukka
1234
+ // Ref: https://github.com/SukkaW/eslint-config-sukka/blob/3a04c31727e0b5bab98fda1a6440f9932fe42dd8/packages/react/src/react.ts#L383
1235
+ "jsx-a11y/alt-text": ["warn", { elements: ["img"], img: ["Image"] }],
1236
+ "jsx-a11y/aria-props": "warn",
1237
+ "jsx-a11y/aria-proptypes": "warn",
1238
+ "jsx-a11y/aria-role": "warn",
1239
+ "jsx-a11y/aria-unsupported-elements": "warn",
1240
+ "jsx-a11y/iframe-has-title": "warn",
1241
+ "jsx-a11y/no-access-key": "warn",
1242
+ "jsx-a11y/role-has-required-aria-props": "warn",
1243
+ "jsx-a11y/role-supports-aria-props": "warn",
1244
+ "jsx-a11y/tabindex-no-positive": "warn",
1245
+ // @eslint-react/eslint-plugin
1246
+ // https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin
1247
+ ...pluginReact.configs.recommended.rules,
1248
+ "@eslint-react/ensure-forward-ref-using-ref": "error",
1249
+ "@eslint-react/no-duplicate-jsx-props": "error",
1250
+ "@eslint-react/no-children-count": "error",
1251
+ "@eslint-react/no-children-for-each": "error",
1252
+ "@eslint-react/no-children-only": "error",
1253
+ "@eslint-react/no-children-to-array": "error",
1254
+ "@eslint-react/no-clone-element": "error",
1255
+ "@eslint-react/no-comment-textnodes": "error",
1256
+ "@eslint-react/no-implicit-key": "error",
1257
+ "@eslint-react/no-missing-component-display-name": "error",
1258
+ "@eslint-react/no-unstable-context-value": "error",
1259
+ "@eslint-react/dom/no-void-elements-with-children": "error",
1260
+ // Update as of 2021: All current versions of major browsers now automatically use the
1261
+ // behavior of rel="noopener" for any target="_blank" link, nullifying this issue.
1262
+ // See: https://chromestatus.com/feature/6140064063029248.
1263
+ // See: https://stackoverflow.com/a/50709724
1264
+ "@eslint-react/dom/no-unsafe-target-blank": "off",
1265
+ "@eslint-react/web-api/no-leaked-interval": "error",
1266
+ "@eslint-react/web-api/no-leaked-resize-observer": "error",
1267
+ "@eslint-react/web-api/no-leaked-timeout": "error",
1268
+ "@eslint-react/hooks-extra/no-unnecessary-use-memo": "error",
1269
+ "@eslint-react/hooks-extra/no-useless-custom-hooks": "error",
1270
+ "@eslint-react/hooks-extra/no-direct-set-state-in-use-effect": "error",
1271
+ "@eslint-react/hooks-extra/no-direct-set-state-in-use-layout-effect": "error"
1272
+ }
1273
+ },
1274
+ {
1275
+ name: name$4.stylistic,
1276
+ files: files$3,
1277
+ rules: stylistic ? {
1278
+ // @eslint-react/eslint-plugin
1279
+ // https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin
1280
+ "@eslint-react/prefer-destructuring-assignment": "error",
1281
+ "@eslint-react/prefer-react-namespace-import": "warn",
1282
+ "@eslint-react/prefer-shorthand-boolean": "error",
1283
+ "@eslint-react/prefer-shorthand-fragment": "off",
1284
+ "@eslint-react/avoid-shorthand-boolean": "off",
1285
+ "@eslint-react/avoid-shorthand-fragment": "error",
1286
+ // @stylistic/eslint-plugin-jsx
1287
+ // https://github.com/eslint-stylistic/eslint-stylistic/tree/main/packages/eslint-plugin-jsx
1288
+ "@stylistic/jsx/jsx-closing-bracket-location": "error",
1289
+ "@stylistic/jsx/jsx-closing-tag-location": "error",
1290
+ "@stylistic/jsx/jsx-curly-brace-presence": [
1291
+ "error",
1292
+ { propElementValues: "always" }
1293
+ ],
1294
+ "@stylistic/jsx/jsx-equals-spacing": "error",
1295
+ "@stylistic/jsx/jsx-first-prop-new-line": ["error", "multiline"],
1296
+ "@stylistic/jsx/jsx-function-call-newline": ["error", "multiline"],
1297
+ "@stylistic/jsx/jsx-max-props-per-line": [
1298
+ "error",
1299
+ { maximum: 1, when: "multiline" }
1300
+ ],
1301
+ "@stylistic/jsx/jsx-one-expression-per-line": ["error", { allow: "non-jsx" }],
1302
+ "@stylistic/jsx/jsx-pascal-case": [
1303
+ "error",
1304
+ { allowNamespace: true, ignore: ["motion"] }
1305
+ ],
1306
+ "@stylistic/jsx/jsx-self-closing-comp": ["error", { component: true, html: true }],
1307
+ "@stylistic/jsx/jsx-tag-spacing": [
1308
+ "error",
1309
+ {
1310
+ afterOpening: "never",
1311
+ beforeClosing: "never",
1312
+ beforeSelfClosing: "always",
1313
+ closingSlash: "never"
1314
+ }
1315
+ ],
1316
+ "@stylistic/jsx/jsx-wrap-multilines": [
1317
+ "error",
1318
+ {
1319
+ arrow: "parens-new-line",
1320
+ assignment: "parens-new-line",
1321
+ condition: "parens-new-line",
1322
+ declaration: "parens-new-line",
1323
+ logical: "parens-new-line",
1324
+ prop: "parens-new-line",
1325
+ propertyValue: "parens-new-line",
1326
+ return: "parens-new-line"
1327
+ }
1328
+ ],
1329
+ "@stylistic/jsx/jsx-sort-props": [
1330
+ "error",
1331
+ {
1332
+ callbacksLast: true,
1333
+ shorthandFirst: true,
1334
+ multiline: "last",
1335
+ reservedFirst: true
1336
+ }
1337
+ ]
1338
+ } : {}
1339
+ }
1340
+ ];
1341
+ }
1342
+
1343
+ const name$3 = getFlatConfigName("regexp");
1344
+ const files$2 = [GLOB_SRC];
1345
+ function regexp() {
1346
+ return [
1347
+ {
1348
+ name: name$3.setup,
1349
+ files: files$2,
1350
+ plugins: {
1351
+ regexp: plugins["pluginRegexp"]
1352
+ }
1353
+ },
1354
+ {
1355
+ name: name$3.rules,
1356
+ files: files$2,
1357
+ rules: {
1358
+ // eslint-plugin-regexp
1359
+ // https://github.com/ota-meshi/eslint-plugin-regexp
1360
+ ...pluginRegexp.configs["flat/recommended"].rules
1361
+ }
1362
+ }
1363
+ ];
1364
+ }
1365
+
1366
+ const name$2 = getFlatConfigName("tailwindcss");
1367
+ const files$1 = [GLOB_SRC, GLOB_STYLE, GLOB_POSTCSS, GLOB_HTML];
1368
+ function tailwindcss() {
1369
+ return [
1370
+ {
1371
+ name: name$2.setup,
1372
+ files: files$1,
1373
+ plugins: {
1374
+ tailwindcss: plugins["pluginTailwindCSS"]
1375
+ },
1376
+ settings: {
1377
+ tailwindcss: {
1378
+ callees: ["classnames", "clsx", "ctl", "cva", "cn", "tv"]
1379
+ }
1380
+ }
1381
+ },
1382
+ {
1383
+ name: name$2.rules,
1384
+ files: files$1,
1385
+ rules: {
1386
+ // eslint-plugin-tailwindcss
1387
+ // https://github.com/francoismassart/eslint-plugin-tailwindcss
1388
+ "tailwindcss/classnames-order": "error",
1389
+ "tailwindcss/enforces-negative-arbitrary-values": "error",
1390
+ "tailwindcss/enforces-shorthand": "warn",
1391
+ "tailwindcss/no-arbitrary-value": "off",
1392
+ "tailwindcss/no-custom-classname": "warn",
1393
+ "tailwindcss/no-contradicting-classname": "error",
1394
+ "tailwindcss/no-unnecessary-arbitrary-value": "error"
1395
+ }
1396
+ }
1397
+ ];
1398
+ }
1399
+
1400
+ const name$1 = getFlatConfigName("typescript");
1401
+ const typescriptStrictTypeCheckedRuleList = configs.strictTypeChecked.map(
1402
+ (config) => config.rules
1403
+ );
1404
+ const typescriptStrictTypeCheckedRules = Object.assign(
1405
+ {},
1406
+ ...typescriptStrictTypeCheckedRuleList
1407
+ );
1408
+ const typescriptStylisticTypeCheckedRuleList = configs.stylisticTypeChecked.map(
1409
+ (config) => config.rules
1410
+ );
1411
+ const typescriptStylisticTypeCheckedRules = Object.assign(
1412
+ {},
1413
+ ...typescriptStylisticTypeCheckedRuleList
1414
+ );
1415
+ function typescript(options = {}) {
1416
+ const {
1417
+ isInEditor = false,
1418
+ tsconfigPath = true,
1419
+ tsconfigRootDir = process.cwd(),
1420
+ allowDefaultProject = [],
1421
+ extraFileExtensions = [],
1422
+ reactTypeCheck = false
1423
+ } = options;
1424
+ const files = [
1425
+ GLOB_TS,
1426
+ GLOB_TSX,
1427
+ ...extraFileExtensions.map((extension) => `**/*${extension}`)
1428
+ ];
1429
+ const tsProjectOptions = tsconfigPath === true ? {
1430
+ projectService: {
1431
+ allowDefaultProject,
1432
+ loadTypeScriptPlugins: isInEditor
1433
+ }
1434
+ } : { project: tsconfigPath };
1435
+ return [
1436
+ {
1437
+ name: name$1.setup,
1438
+ files,
1439
+ plugins: {
1440
+ "import-x": plugins["pluginImportX"],
1441
+ "@typescript-eslint": plugins["pluginTypescript"],
1442
+ antfu: plugins["pluginAntfu"]
1443
+ },
1444
+ languageOptions: {
1445
+ sourceType: "module",
1446
+ ecmaVersion: "latest",
1447
+ parser: parsers["parserTypescript"],
1448
+ parserOptions: {
1449
+ // https://typescript-eslint.io/packages/parser#configuration
1450
+ ecmaVersion: "latest",
1451
+ extraFileExtensions,
1452
+ // Assuming using JSX transform
1453
+ // eslint-disable-next-line unicorn/no-null -- Set to null when using JSX transform
1454
+ jsxPragma: null,
1455
+ ...tsProjectOptions,
1456
+ tsconfigRootDir,
1457
+ warnOnUnsupportedTypeScriptVersion: true
1458
+ }
1459
+ },
1460
+ settings: {
1461
+ "import-x/extensions": [
1462
+ ".js",
1463
+ ".jsx",
1464
+ ".cjs",
1465
+ ".mjs",
1466
+ ".ts",
1467
+ ".tsx",
1468
+ ".cts",
1469
+ ".mts",
1470
+ ...extraFileExtensions
1471
+ ],
1472
+ "import-x/external-module-folders": ["node_modules", "node_modules/@types"],
1473
+ "import-x/parsers": {
1474
+ "@typescript-eslint/parser": [".ts", ".tsx", ".cts", ".mts", ...extraFileExtensions]
1475
+ },
1476
+ "import-x/resolver-next": [
1477
+ // eslint-import-resolver-typescript
1478
+ // https://github.com/import-js/eslint-import-resolver-typescript
1479
+ createTypeScriptImportResolver({
1480
+ alwaysTryTypes: true,
1481
+ project: tsconfigPath === true ? undefined : tsconfigPath,
1482
+ extensions: [
1483
+ ".ts",
1484
+ ".tsx",
1485
+ ".d.ts",
1486
+ ".js",
1487
+ ".jsx",
1488
+ ".json",
1489
+ ".node",
1490
+ ...extraFileExtensions
1491
+ ]
1492
+ })
1493
+ ]
1494
+ }
1495
+ },
1496
+ {
1497
+ name: name$1.rules,
1498
+ files,
1499
+ rules: {
1500
+ // eslint-plugin-import-x
1501
+ // https://github.com/un-ts/eslint-plugin-import-x
1502
+ // TypeScript compilation already ensures that named imports exist in the referenced module
1503
+ ...pluginImportX.configs.typescript.rules,
1504
+ // Contains all of `recommended`, `recommended-type-checked`, and `strict`, along with additional strict rules that require type information.
1505
+ // https://typescript-eslint.io/users/configs#strict-type-checked
1506
+ ...typescriptStrictTypeCheckedRules,
1507
+ // Contains all of `stylistic`, along with additional stylistic rules that require type information.
1508
+ // https://typescript-eslint.io/users/configs#stylistic-type-checked
1509
+ ...typescriptStylisticTypeCheckedRules,
1510
+ // Disallow `@ts-<directive>` comments or require descriptions after directives
1511
+ // https://typescript-eslint.io/rules/ban-ts-comment
1512
+ "@typescript-eslint/ban-ts-comment": [
1513
+ "error",
1514
+ {
1515
+ minimumDescriptionLength: 10,
1516
+ "ts-check": false,
1517
+ "ts-expect-error": "allow-with-description",
1518
+ "ts-ignore": true,
1519
+ "ts-nocheck": true
1520
+ }
1521
+ ],
1522
+ // enforce naming conventions for everything across a codebase
1523
+ // https://typescript-eslint.io/rules/naming-convention
1524
+ "@typescript-eslint/naming-convention": [
1525
+ "warn",
1526
+ // Allow camelCase variables (23.2), PascalCase variables (23.8), and UPPER_CASE variables (23.10)
1527
+ {
1528
+ selector: "variable",
1529
+ format: ["camelCase", "PascalCase", "UPPER_CASE"],
1530
+ leadingUnderscore: "allowSingleOrDouble",
1531
+ trailingUnderscore: "forbid"
1532
+ },
1533
+ // Allow camelCase functions (23.2), and PascalCase functions (23.8)
1534
+ {
1535
+ selector: "function",
1536
+ format: ["camelCase", "PascalCase"],
1537
+ leadingUnderscore: "allowSingleOrDouble",
1538
+ trailingUnderscore: "forbid"
1539
+ },
1540
+ // Airbnb recommends PascalCase for classes (23.3), and although Airbnb does not make TypeScript recommendations,
1541
+ // we are assuming this rule would similarly apply to anything "type like", including interfaces, type aliases, and enums
1542
+ {
1543
+ selector: "typeLike",
1544
+ format: ["PascalCase"],
1545
+ leadingUnderscore: "forbid",
1546
+ trailingUnderscore: "forbid"
1547
+ }
1548
+ ],
1549
+ // Allow number literals to be used in template expressions
1550
+ "@typescript-eslint/restrict-template-expressions": ["error", { allowNumber: true }],
1551
+ // eslint-plugin-antfu
1552
+ // https://github.com/antfu/eslint-plugin-antfu
1553
+ "antfu/no-ts-export-equal": "error"
1554
+ }
1555
+ },
1556
+ {
1557
+ name: `${name$1.base}/react-type-checked`,
1558
+ files,
1559
+ plugins: {
1560
+ "@eslint-react": plugins["pluginReact"],
1561
+ "@eslint-react/dom": plugins["pluginReactDom"]
1562
+ },
1563
+ rules: reactTypeCheck ? {
1564
+ // Disables checking an asynchronous function passed as a JSX attribute expected to be a function that returns `void`
1565
+ "@typescript-eslint/no-misused-promises": ["error", {
1566
+ checksVoidReturn: { attributes: false }
1567
+ }],
1568
+ // @eslint-react/eslint-plugin
1569
+ // https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin
1570
+ // pluginReact.configs.['recommended-typescript'].rules
1571
+ "@eslint-react/dom/no-unknown-property": "off",
1572
+ "@eslint-react/no-duplicate-jsx-props": "off",
1573
+ "@eslint-react/use-jsx-vars": "off",
1574
+ // pluginReact.configs.['recommended-type-checked'].rules
1575
+ // https://eslint-react.xyz/docs/rules/no-leaked-conditional-rendering
1576
+ "@eslint-react/no-leaked-conditional-rendering": "error",
1577
+ "@eslint-react/prefer-read-only-props": "warn"
1578
+ } : {}
1579
+ },
1580
+ {
1581
+ files: ["**/*.cts"],
1582
+ rules: {
1583
+ "@typescript-eslint/no-require-imports": "off"
1584
+ }
1585
+ }
1586
+ ];
1587
+ }
1588
+
1589
+ const name = getFlatConfigName("unicorn");
1590
+ const files = [GLOB_SRC];
1591
+ const allFiles = [...GLOB_ALL_SRC];
1592
+ function unicorn() {
1593
+ return [
1594
+ {
1595
+ name: `${name.setup}/all-src`,
1596
+ files: allFiles,
1597
+ plugins: {
1598
+ unicorn: plugins["pluginUnicorn"]
1599
+ }
1600
+ },
1601
+ {
1602
+ name: `${name.setup}/src`,
1603
+ files,
1604
+ languageOptions: {
1605
+ globals: {
1606
+ ...globals.builtin
1607
+ }
1608
+ }
1609
+ },
1610
+ {
1611
+ name: `${name.rules}/all-src`,
1612
+ files: allFiles,
1613
+ rules: {
1614
+ // Let all files use kebab-case for filenames.
1615
+ // kebab-case forces filenames to be lowercase and hyphen-separated,
1616
+ // some file systems are case-insensitive, so this rule can help prevent
1617
+ // issues with importing files on case-sensitive file systems.
1618
+ "unicorn/filename-case": ["error", {
1619
+ cases: { kebabCase: true },
1620
+ // Ignore case for specific files
1621
+ ignore: ["README.md", "LICENSE.md", "CHANGELOG.md", "CODE_OF_CONDUCT.md"]
1622
+ }]
1623
+ }
1624
+ },
1625
+ {
1626
+ name: `${name.rules}/src`,
1627
+ files,
1628
+ rules: {
1629
+ // eslint-plugin-unicorn
1630
+ // https://github.com/sindresorhus/eslint-plugin-unicorn
1631
+ ...pluginUnicorn.configs["flat/recommended"].rules
1632
+ }
1633
+ }
1634
+ ];
1635
+ }
1636
+
1637
+ function enabled(options, defaults = false) {
1638
+ if (typeof options === "boolean") return options;
1639
+ if (options === undefined) return defaults;
1640
+ if (options.enable) return true;
1641
+ return defaults;
1642
+ }
1643
+ function configOptions(options, defaultOptions) {
1644
+ const isInEditor = isInEditorEnv();
1645
+ if (options === undefined) return { isInEditor };
1646
+ if (typeof options === "boolean") return { isInEditor };
1647
+ return { ...defaultOptions, ...options, isInEditor };
1648
+ }
1649
+ const pluginRenaming = {
1650
+ "import-x": "import"
1651
+ };
1652
+ async function config(options, ...userConfigs) {
1653
+ const configs = [];
1654
+ const enableTypeScript = enabled(options?.typescript, isPackageExists("typescript"));
1655
+ const enableReact = enabled(options?.react, isPackageExists("react"));
1656
+ const importsOption = enableTypeScript ? configOptions(options?.typescript) : {};
1657
+ configs.push(ignores(options?.ignores), comments(), imports(importsOption));
1658
+ if (enabled(options?.javascript, true)) {
1659
+ configs.push(javascript(configOptions(options?.javascript)));
1660
+ }
1661
+ if (enableTypeScript) {
1662
+ configs.push(
1663
+ typescript(configOptions(options?.typescript, { reactTypeCheck: enableReact }))
1664
+ );
1665
+ }
1666
+ if (enabled(options?.json, true)) {
1667
+ const formatOption = configOptions(options?.format, { indentWidth: 2 });
1668
+ configs.push(json(configOptions(options?.json, { stylistic: formatOption })));
1669
+ }
1670
+ if (enableReact) {
1671
+ configs.push(
1672
+ jsx(),
1673
+ react(
1674
+ configOptions(options?.react, {
1675
+ reactCompiler: isPackageExists("babel-plugin-react-compiler") || isPackageExists("react-compiler-webpack")
1676
+ })
1677
+ )
1678
+ );
1679
+ }
1680
+ if (enabled(options?.react, isPackageExists("next"))) {
1681
+ configs.push(nextJs());
1682
+ }
1683
+ if (enabled(options?.node, isPackageExists("@types/node"))) {
1684
+ configs.push(nodeJs(configOptions(options?.node)));
1685
+ }
1686
+ if (enabled(undefined, isPackageExists("tailwindcss"))) {
1687
+ configs.push(tailwindcss());
1688
+ }
1689
+ configs.push(regexp(), unicorn(), disables());
1690
+ if (enabled(options?.format, isPackageExists("dprint"))) {
1691
+ const jsonOptions = configOptions(options?.json);
1692
+ configs.push(
1693
+ formatters(
1694
+ configOptions(options?.format, {
1695
+ extraJsonFiles: jsonOptions.extraFiles
1696
+ })
1697
+ )
1698
+ );
1699
+ }
1700
+ let composer = new FlatConfigComposer(...configs);
1701
+ const _userConfigs = userConfigs;
1702
+ composer = composer.append(..._userConfigs).renamePlugins(pluginRenaming);
1703
+ return composer;
1704
+ }
1705
+
1706
+ export { combine, comments, config as default, disables, formatters, getFlatConfigName, getPackageJson, ignores, imports, isInEditorEnv, isInGitHooksOrLintStaged, javascript, json, jsx, loadLocalFile, memo, nextJs, nodeJs, react, regexp, tailwindcss, typescript, unicorn };