@2030/eslint-config 2.0.2 → 3.0.0

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