@coderwyd/eslint-config 2.7.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -39,25 +39,16 @@ function comments() {
39
39
  // src/constants/glob.ts
40
40
  var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
41
41
  var GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
42
- var GLOB_JSX = "**/*.?([cm])jsx";
43
42
  var GLOB_TS = "**/*.?([cm])ts";
44
43
  var GLOB_DTS = "**/*.d.?([cm])ts";
45
44
  var GLOB_TSX = "**/*.?([cm])tsx";
46
45
  var GLOB_VUE = "**/*.vue";
47
46
  var GLOB_ASTRO_TS = "**/*.astro/*.ts";
48
47
  var GLOB_SVELTE = "**/*.svelte";
49
- var GLOB_HTML = "**/*.htm?(l)";
50
- var GLOB_CSS = "**/*.css";
51
- var GLOB_POSTCSS = "**/*.{p,post}css";
52
- var GLOB_LESS = "**/*.less";
53
- var GLOB_SCSS = "**/*.scss";
54
48
  var GLOB_JSON = "**/*.json";
55
49
  var GLOB_JSON5 = "**/*.json5";
56
50
  var GLOB_JSONC = "**/*.jsonc";
57
51
  var GLOB_MARKDOWN = "**/*.md";
58
- var GLOB_YAML = "**/*.y?(a)ml";
59
- var GLOB_TOML = "**/*.toml";
60
- var GLOB_GRAPHQL = "**/*.{g,graph}ql";
61
52
  var GLOB_MARKDOWN_CODE = `${GLOB_MARKDOWN}/${GLOB_SRC}`;
62
53
  var GLOB_TESTS = [
63
54
  `**/__tests__/**/*.${GLOB_SRC_EXT}`,
@@ -100,339 +91,18 @@ var GLOB_EXCLUDE = [
100
91
  "**/components.d.ts"
101
92
  ];
102
93
 
103
- // src/configs/disables.ts
104
- function disables() {
105
- return [
106
- {
107
- files: [`**/scripts/${GLOB_SRC}`],
108
- name: "coderwyd/disables/scripts",
109
- rules: {
110
- "antfu/no-top-level-await": "off",
111
- "no-console": "off",
112
- "ts/explicit-function-return-type": "off"
113
- }
114
- },
115
- {
116
- files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
117
- name: "coderwyd/disables/cli",
118
- rules: {
119
- "antfu/no-top-level-await": "off",
120
- "no-console": "off"
121
- }
122
- },
123
- {
124
- files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
125
- name: "coderwyd/disables/bin",
126
- rules: {
127
- "antfu/no-import-dist": "off",
128
- "antfu/no-import-node-modules-by-path": "off"
129
- }
130
- },
131
- {
132
- files: [GLOB_DTS],
133
- name: "coderwyd/disables/dts",
134
- rules: {
135
- "eslint-comments/no-unlimited-disable": "off",
136
- "import/no-duplicates": "off",
137
- "no-restricted-syntax": "off",
138
- "unused-imports/no-unused-vars": "off"
139
- }
140
- },
141
- {
142
- files: ["**/*.{test,spec}.([tj])s?(x)"],
143
- name: "coderwyd/disables/test",
144
- rules: {
145
- "antfu/no-top-level-await": "off",
146
- "no-unused-expressions": "off"
147
- }
148
- },
149
- {
150
- files: ["**/*.js", "**/*.cjs"],
151
- name: "coderwyd/disables/cjs",
152
- rules: {
153
- "ts/no-require-imports": "off"
154
- }
155
- }
156
- ];
157
- }
158
-
159
- // src/shared/index.ts
160
- import process from "node:process";
161
- import { fileURLToPath } from "node:url";
162
- import { getPackageInfoSync, isPackageExists } from "local-pkg";
163
- var scopeUrl = fileURLToPath(new URL(".", import.meta.url));
164
- var isCwdInScope = isPackageExists("@coderwyd/eslint-config");
165
- var parserPlain = {
166
- meta: {
167
- name: "parser-plain"
168
- },
169
- parseForESLint: (code) => ({
170
- ast: {
171
- body: [],
172
- comments: [],
173
- loc: { end: code.length, start: 0 },
174
- range: [0, code.length],
175
- tokens: [],
176
- type: "Program"
177
- },
178
- scopeManager: null,
179
- services: { isPlain: true },
180
- visitorKeys: {
181
- Program: []
182
- }
183
- })
184
- };
185
- async function combine(...configs2) {
186
- const resolved = await Promise.all(configs2);
187
- return resolved.flat();
188
- }
189
- function renameRules(rules, map) {
190
- return Object.fromEntries(
191
- Object.entries(rules).map(([key, value]) => {
192
- for (const [from, to] of Object.entries(map)) {
193
- if (key.startsWith(`${from}/`))
194
- return [to + key.slice(from.length), value];
195
- }
196
- return [key, value];
197
- })
198
- );
199
- }
200
- function renamePluginInConfigs(configs2, map) {
201
- return configs2.map((i) => {
202
- const clone = { ...i };
203
- if (clone.rules)
204
- clone.rules = renameRules(clone.rules, map);
205
- if (clone.plugins) {
206
- clone.plugins = Object.fromEntries(
207
- Object.entries(clone.plugins).map(([key, value]) => {
208
- if (key in map)
209
- return [map[key], value];
210
- return [key, value];
211
- })
212
- );
213
- }
214
- return clone;
215
- });
216
- }
217
- function getVueVersion() {
218
- const pkg = getPackageInfoSync("vue", { paths: [process.cwd()] });
219
- if (pkg && typeof pkg.version === "string" && !Number.isNaN(+pkg.version[0]))
220
- return +pkg.version[0];
221
- return 3;
222
- }
223
- function toArray(value) {
224
- return Array.isArray(value) ? value : [value];
225
- }
226
- async function interopDefault(m) {
227
- const resolved = await m;
228
- return resolved.default || resolved;
229
- }
230
- function isPackageInScope(name) {
231
- return isPackageExists(name, { paths: [scopeUrl] });
232
- }
233
- async function ensurePackages(packages) {
234
- if (process.env.CI || process.stdout.isTTY === false || isCwdInScope === false)
235
- return;
236
- const nonExistingPackages = packages.filter((i) => !isPackageInScope(i));
237
- if (nonExistingPackages.length === 0)
238
- return;
239
- const { default: prompts } = await import("prompts");
240
- const { result } = await prompts([
241
- {
242
- message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`,
243
- name: "result",
244
- type: "confirm"
245
- }
246
- ]);
247
- if (result) {
248
- await import("@antfu/install-pkg").then(
249
- (i) => i.installPackage(nonExistingPackages, { dev: true })
250
- );
251
- }
252
- }
253
- function resolveSubOptions(options, key) {
254
- return typeof options[key] === "boolean" ? {} : options[key] || {};
255
- }
256
- function getOverrides(options, key) {
257
- const sub = resolveSubOptions(options, key);
258
- return {
259
- ..."overrides" in sub ? sub.overrides || {} : {}
260
- };
261
- }
262
- function isInEditorEnv() {
263
- if (process.env.CI)
264
- return false;
265
- if (isInGitHooksOrLintStaged())
266
- return false;
267
- return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM || false);
268
- }
269
- function isInGitHooksOrLintStaged() {
270
- return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged") || process.env.npm_lifecycle_script?.startsWith("nano-staged") || false);
271
- }
272
-
273
- // src/configs/stylistic.ts
274
- var StylisticConfigDefaults = {
275
- indent: 2,
276
- jsx: true,
277
- quotes: "single",
278
- semi: false
279
- };
280
- async function stylistic(options = {}) {
281
- const {
282
- indent,
283
- jsx: jsx2,
284
- overrides = {},
285
- quotes,
286
- semi
287
- } = {
288
- ...StylisticConfigDefaults,
289
- ...options
290
- };
291
- const pluginStylistic = await interopDefault(
292
- import("@stylistic/eslint-plugin")
293
- );
294
- const config = pluginStylistic.configs.customize({
295
- flat: true,
296
- indent,
297
- jsx: jsx2,
298
- pluginName: "style",
299
- quotes,
300
- semi
301
- });
302
- return [
303
- {
304
- name: "coderwyd/stylistic/rules",
305
- plugins: {
306
- antfu: default3,
307
- style: pluginStylistic
308
- },
309
- rules: {
310
- ...config.rules,
311
- "antfu/consistent-chaining": "error",
312
- "antfu/consistent-list-newline": "error",
313
- "antfu/curly": "error",
314
- "antfu/if-newline": "warn",
315
- "antfu/top-level-function": "warn",
316
- ...overrides
317
- }
318
- }
319
- ];
320
- }
321
-
322
- // src/configs/formatter.ts
323
- async function formatter(options = {}, stylistic2 = {}) {
324
- const { css, graphql, html, markdown, toml, yaml } = options === true ? {
325
- css: true,
326
- graphql: true,
327
- html: true,
328
- markdown: true,
329
- toml: true,
330
- yaml: true
331
- } : options;
332
- const { indent, quotes, semi } = {
333
- ...StylisticConfigDefaults,
334
- ...stylistic2
335
- };
336
- const prettierOptions = Object.assign(
337
- {
338
- endOfLine: "auto",
339
- printWidth: 80,
340
- semi,
341
- singleQuote: quotes === "single",
342
- tabWidth: typeof indent === "number" ? indent : 2,
343
- trailingComma: "all",
344
- useTabs: indent === "tab"
345
- },
346
- typeof options === "boolean" ? {} : options.prettierOptions || {}
347
- );
348
- await ensurePackages(["eslint-plugin-format"]);
349
- const pluginFormat = await interopDefault(import("eslint-plugin-format"));
350
- function createPrettierFormatter(files, parser, plugins) {
351
- const rules = {
352
- ...prettierOptions,
353
- parser
354
- };
355
- const markdownRules = {
356
- printWidth: 120,
357
- ...rules,
358
- embeddedLanguageFormatting: "off"
359
- };
360
- if (plugins?.length)
361
- rules.plugins = [...rules.plugins || [], ...plugins];
362
- const config = {
363
- files,
364
- languageOptions: {
365
- parser: parserPlain
366
- },
367
- name: `coderwyd/formatter/${parser}`,
368
- plugins: {
369
- format: pluginFormat
370
- },
371
- rules: {
372
- "format/prettier": [
373
- "warn",
374
- parser === "markdown" ? markdownRules : rules
375
- ]
376
- }
377
- };
378
- return config;
379
- }
380
- const configs2 = [
381
- {
382
- name: "coderwyd/formatter/setup",
383
- plugins: {
384
- format: pluginFormat
385
- }
386
- }
387
- ];
388
- if (html) {
389
- const htmlConfig = createPrettierFormatter([GLOB_HTML], "html");
390
- configs2.push(htmlConfig);
391
- }
392
- if (css) {
393
- const cssConfig = createPrettierFormatter([GLOB_CSS, GLOB_POSTCSS], "css");
394
- const scssConfig = createPrettierFormatter([GLOB_SCSS], "scss");
395
- const lessConfig = createPrettierFormatter([GLOB_LESS], "less");
396
- configs2.push(cssConfig, scssConfig, lessConfig);
397
- }
398
- if (markdown) {
399
- const markdownConfig = createPrettierFormatter([GLOB_MARKDOWN], "markdown");
400
- configs2.push(markdownConfig);
401
- }
402
- if (graphql) {
403
- const graphqlConfig = createPrettierFormatter([GLOB_GRAPHQL], "graphql");
404
- configs2.push(graphqlConfig);
405
- }
406
- if (yaml) {
407
- const yamlConfig = createPrettierFormatter([GLOB_YAML], "yaml");
408
- configs2.push(yamlConfig);
409
- }
410
- if (toml) {
411
- await ensurePackages(["@toml-tools/parser", "prettier-plugin-toml"]);
412
- const tomlConfig = createPrettierFormatter([GLOB_TOML], "toml", [
413
- "prettier-plugin-toml"
414
- ]);
415
- configs2.push(tomlConfig);
416
- }
417
- return configs2;
418
- }
419
-
420
94
  // src/configs/ignores.ts
421
95
  function ignores(userIgnores = []) {
422
96
  return [
423
97
  {
424
- ignores: [
425
- ...GLOB_EXCLUDE,
426
- ...userIgnores
427
- ],
98
+ ignores: [...GLOB_EXCLUDE, ...userIgnores],
428
99
  name: "coderwyd/ignores"
429
100
  }
430
101
  ];
431
102
  }
432
103
 
433
104
  // src/configs/imports.ts
434
- function imports(options = {}) {
435
- const { stylistic: stylistic2 = true } = options;
105
+ function imports() {
436
106
  return [
437
107
  {
438
108
  name: "coderwyd/imports/rules",
@@ -449,10 +119,7 @@ function imports(options = {}) {
449
119
  "import/no-mutable-exports": "error",
450
120
  "import/no-named-default": "error",
451
121
  "import/no-self-import": "error",
452
- "import/no-webpack-loader-syntax": "error",
453
- ...stylistic2 ? {
454
- "import/newline-after-import": ["error", { count: 1 }]
455
- } : {}
122
+ "import/no-webpack-loader-syntax": "error"
456
123
  }
457
124
  }
458
125
  ];
@@ -504,7 +171,7 @@ function javascript(options = {}) {
504
171
  "constructor-super": "error",
505
172
  "default-case-last": "error",
506
173
  "dot-notation": ["error", { allowKeywords: true }],
507
- "eqeqeq": ["error", "smart"],
174
+ eqeqeq: ["error", "smart"],
508
175
  "for-direction": "error",
509
176
  "getter-return": "error",
510
177
  "new-cap": [
@@ -685,16 +352,126 @@ function javascript(options = {}) {
685
352
  ],
686
353
  "valid-typeof": ["error", { requireStringLiterals: true }],
687
354
  "vars-on-top": "error",
688
- "yoda": ["error", "never"],
355
+ yoda: ["error", "never"],
689
356
  ...overrides
690
357
  }
691
358
  }
692
359
  ];
693
360
  }
694
361
 
362
+ // src/shared/index.ts
363
+ import process from "node:process";
364
+ import { fileURLToPath } from "node:url";
365
+ import { getPackageInfoSync, isPackageExists } from "local-pkg";
366
+ var scopeUrl = fileURLToPath(new URL(".", import.meta.url));
367
+ var isCwdInScope = isPackageExists("@coderwyd/eslint-config");
368
+ var parserPlain = {
369
+ meta: {
370
+ name: "parser-plain"
371
+ },
372
+ parseForESLint: (code) => ({
373
+ ast: {
374
+ body: [],
375
+ comments: [],
376
+ loc: { end: code.length, start: 0 },
377
+ range: [0, code.length],
378
+ tokens: [],
379
+ type: "Program"
380
+ },
381
+ scopeManager: null,
382
+ services: { isPlain: true },
383
+ visitorKeys: {
384
+ Program: []
385
+ }
386
+ })
387
+ };
388
+ async function combine(...configs2) {
389
+ const resolved = await Promise.all(configs2);
390
+ return resolved.flat();
391
+ }
392
+ function renameRules(rules, map) {
393
+ return Object.fromEntries(
394
+ Object.entries(rules).map(([key, value]) => {
395
+ for (const [from, to] of Object.entries(map)) {
396
+ if (key.startsWith(`${from}/`))
397
+ return [to + key.slice(from.length), value];
398
+ }
399
+ return [key, value];
400
+ })
401
+ );
402
+ }
403
+ function renamePluginInConfigs(configs2, map) {
404
+ return configs2.map((i) => {
405
+ const clone = { ...i };
406
+ if (clone.rules) clone.rules = renameRules(clone.rules, map);
407
+ if (clone.plugins) {
408
+ clone.plugins = Object.fromEntries(
409
+ Object.entries(clone.plugins).map(([key, value]) => {
410
+ if (key in map) return [map[key], value];
411
+ return [key, value];
412
+ })
413
+ );
414
+ }
415
+ return clone;
416
+ });
417
+ }
418
+ function getVueVersion() {
419
+ const pkg = getPackageInfoSync("vue", { paths: [process.cwd()] });
420
+ if (pkg && typeof pkg.version === "string" && !Number.isNaN(+pkg.version[0]))
421
+ return +pkg.version[0];
422
+ return 3;
423
+ }
424
+ function toArray(value) {
425
+ return Array.isArray(value) ? value : [value];
426
+ }
427
+ async function interopDefault(m) {
428
+ const resolved = await m;
429
+ return resolved.default || resolved;
430
+ }
431
+ function isPackageInScope(name) {
432
+ return isPackageExists(name, { paths: [scopeUrl] });
433
+ }
434
+ async function ensurePackages(packages) {
435
+ if (process.env.CI || process.stdout.isTTY === false || isCwdInScope === false)
436
+ return;
437
+ const nonExistingPackages = packages.filter((i) => !isPackageInScope(i));
438
+ if (nonExistingPackages.length === 0) return;
439
+ const { default: prompts } = await import("prompts");
440
+ const { result } = await prompts([
441
+ {
442
+ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`,
443
+ name: "result",
444
+ type: "confirm"
445
+ }
446
+ ]);
447
+ if (result) {
448
+ await import("@antfu/install-pkg").then(
449
+ (i) => i.installPackage(nonExistingPackages, { dev: true })
450
+ );
451
+ }
452
+ }
453
+ function resolveSubOptions(options, key) {
454
+ return typeof options[key] === "boolean" ? {} : options[key] || {};
455
+ }
456
+ function getOverrides(options, key) {
457
+ const sub = resolveSubOptions(options, key);
458
+ return {
459
+ ..."overrides" in sub ? sub.overrides || {} : {}
460
+ };
461
+ }
462
+ function isInEditorEnv() {
463
+ if (process.env.CI) return false;
464
+ if (isInGitHooksOrLintStaged()) {
465
+ return false;
466
+ }
467
+ return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM || false);
468
+ }
469
+ function isInGitHooksOrLintStaged() {
470
+ return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged") || process.env.npm_lifecycle_script?.startsWith("nano-staged") || false);
471
+ }
472
+
695
473
  // src/configs/jsdoc.ts
696
- async function jsdoc(options = {}) {
697
- const { stylistic: stylistic2 = true } = options;
474
+ async function jsdoc() {
698
475
  return [
699
476
  {
700
477
  name: "coderwyd/jsdoc/rules",
@@ -716,11 +493,7 @@ async function jsdoc(options = {}) {
716
493
  "jsdoc/require-property-name": "warn",
717
494
  "jsdoc/require-returns-check": "warn",
718
495
  "jsdoc/require-returns-description": "warn",
719
- "jsdoc/require-yields-check": "warn",
720
- ...stylistic2 ? {
721
- "jsdoc/check-alignment": "warn",
722
- "jsdoc/multiline-blocks": "warn"
723
- } : {}
496
+ "jsdoc/require-yields-check": "warn"
724
497
  }
725
498
  }
726
499
  ];
@@ -728,14 +501,7 @@ async function jsdoc(options = {}) {
728
501
 
729
502
  // src/configs/jsonc.ts
730
503
  async function jsonc(options = {}) {
731
- const {
732
- files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
733
- overrides = {},
734
- stylistic: stylistic2 = true
735
- } = options || {};
736
- const {
737
- indent = 2
738
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
504
+ const { files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC], overrides = {} } = options || {};
739
505
  const [pluginJsonc, parserJsonc] = await Promise.all([
740
506
  interopDefault(import("eslint-plugin-jsonc")),
741
507
  interopDefault(import("jsonc-eslint-parser"))
@@ -780,50 +546,12 @@ async function jsonc(options = {}) {
780
546
  "jsonc/space-unary-ops": "error",
781
547
  "jsonc/valid-json-number": "error",
782
548
  "jsonc/vue-custom-block/no-parsing-error": "error",
783
- ...stylistic2 ? {
784
- "jsonc/array-bracket-spacing": ["error", "never"],
785
- "jsonc/comma-dangle": ["error", "never"],
786
- "jsonc/comma-style": ["error", "last"],
787
- "jsonc/indent": ["error", indent],
788
- "jsonc/key-spacing": [
789
- "error",
790
- { afterColon: true, beforeColon: false }
791
- ],
792
- "jsonc/object-curly-newline": [
793
- "error",
794
- { consistent: true, multiline: true }
795
- ],
796
- "jsonc/object-curly-spacing": ["error", "always"],
797
- "jsonc/object-property-newline": [
798
- "error",
799
- { allowMultiplePropertiesPerLine: true }
800
- ],
801
- "jsonc/quote-props": "error",
802
- "jsonc/quotes": "error"
803
- } : {},
804
549
  ...overrides
805
550
  }
806
551
  }
807
552
  ];
808
553
  }
809
554
 
810
- // src/configs/jsx.ts
811
- function jsx() {
812
- return [
813
- {
814
- files: [GLOB_JSX, GLOB_TSX],
815
- languageOptions: {
816
- parserOptions: {
817
- ecmaFeatures: {
818
- jsx: true
819
- }
820
- }
821
- },
822
- name: "coderwyd/jsx/setup"
823
- }
824
- ];
825
- }
826
-
827
555
  // src/configs/node.ts
828
556
  function node() {
829
557
  return [
@@ -856,7 +584,10 @@ function perfectionist() {
856
584
  perfectionist: default5
857
585
  },
858
586
  rules: {
859
- "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
587
+ "perfectionist/sort-exports": [
588
+ "error",
589
+ { order: "asc", type: "natural" }
590
+ ],
860
591
  "perfectionist/sort-imports": [
861
592
  "warn",
862
593
  {
@@ -892,6 +623,27 @@ function perfectionist() {
892
623
  ];
893
624
  }
894
625
 
626
+ // src/configs/prettier.ts
627
+ import prettierRules from "eslint-config-prettier";
628
+ var { rules: eslintRules } = prettierRules;
629
+ async function prettier() {
630
+ const pluginPrettier = await interopDefault(import("eslint-plugin-prettier"));
631
+ return [
632
+ {
633
+ name: "coderwyd/prettier/rules",
634
+ plugins: {
635
+ prettier: pluginPrettier
636
+ },
637
+ rules: {
638
+ ...eslintRules,
639
+ "arrow-body-style": "off",
640
+ "prefer-arrow-callback": "off",
641
+ "prettier/prettier": "warn"
642
+ }
643
+ }
644
+ ];
645
+ }
646
+
895
647
  // src/configs/react.ts
896
648
  import { isPackageExists as isPackageExists3 } from "local-pkg";
897
649
 
@@ -900,12 +652,7 @@ import process2 from "node:process";
900
652
  import { isPackageExists as isPackageExists2 } from "local-pkg";
901
653
  var isInEditor = !!((process2.env.VSCODE_PID || process2.env.VSCODE_CWD || process2.env.JETBRAINS_IDE || process2.env.VIM || process2.env.NVIM) && !process2.env.CI);
902
654
  var hasTypeScript = isPackageExists2("typescript");
903
- var VueJsPackages = [
904
- "vue",
905
- "nuxt",
906
- "vitepress",
907
- "@slidev/cli"
908
- ];
655
+ var VueJsPackages = ["vue", "nuxt", "vitepress", "@slidev/cli"];
909
656
  var hasVue = hasPackages(VueJsPackages);
910
657
  var RemixPackages = [
911
658
  "@remix-run/node",
@@ -945,7 +692,7 @@ async function react(options = {}) {
945
692
  {
946
693
  name: "coderwyd/react/setup",
947
694
  plugins: {
948
- "react": plugins["@eslint-react"],
695
+ react: plugins["@eslint-react"],
949
696
  "react-dom": plugins["@eslint-react/dom"],
950
697
  "react-hooks": pluginReactHooks,
951
698
  "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
@@ -1063,8 +810,7 @@ function regexp(options = {}) {
1063
810
  };
1064
811
  if (options.level === "warn") {
1065
812
  Object.keys(rules).forEach((key) => {
1066
- if (rules[key] === "error")
1067
- rules[key] = "warn";
813
+ if (rules[key] === "error") rules[key] = "warn";
1068
814
  });
1069
815
  }
1070
816
  return [
@@ -1303,13 +1049,65 @@ function sortTsconfig() {
1303
1049
  ];
1304
1050
  }
1305
1051
 
1052
+ // src/configs/specials.ts
1053
+ function specials() {
1054
+ return [
1055
+ {
1056
+ files: [`**/scripts/${GLOB_SRC}`],
1057
+ name: "coderwyd/specials/scripts",
1058
+ rules: {
1059
+ "antfu/no-top-level-await": "off",
1060
+ "no-console": "off",
1061
+ "ts/explicit-function-return-type": "off"
1062
+ }
1063
+ },
1064
+ {
1065
+ files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
1066
+ name: "coderwyd/specials/cli",
1067
+ rules: {
1068
+ "antfu/no-top-level-await": "off",
1069
+ "no-console": "off"
1070
+ }
1071
+ },
1072
+ {
1073
+ files: ["**/bin/**/*", `**/bin.${GLOB_SRC_EXT}`],
1074
+ name: "coderwyd/specials/bin",
1075
+ rules: {
1076
+ "antfu/no-import-dist": "off",
1077
+ "antfu/no-import-node-modules-by-path": "off"
1078
+ }
1079
+ },
1080
+ {
1081
+ files: [GLOB_DTS],
1082
+ name: "coderwyd/specials/dts",
1083
+ rules: {
1084
+ "eslint-comments/no-unlimited-disable": "off",
1085
+ "import/no-duplicates": "off",
1086
+ "no-restricted-syntax": "off",
1087
+ "unused-imports/no-unused-vars": "off"
1088
+ }
1089
+ },
1090
+ {
1091
+ files: ["**/*.{test,spec}.([tj])s?(x)"],
1092
+ name: "coderwyd/specials/test",
1093
+ rules: {
1094
+ "antfu/no-top-level-await": "off",
1095
+ "no-unused-expressions": "off"
1096
+ }
1097
+ },
1098
+ {
1099
+ files: ["**/*.js", "**/*.cjs"],
1100
+ name: "coderwyd/specials/cjs",
1101
+ rules: {
1102
+ "ts/no-require-imports": "off"
1103
+ }
1104
+ }
1105
+ ];
1106
+ }
1107
+
1306
1108
  // src/configs/svelte.ts
1307
1109
  async function svelte(options = {}) {
1308
- const { files = [GLOB_SVELTE], overrides = {}, stylistic: stylistic2 = true } = options;
1309
- const {
1310
- indent = 2,
1311
- quotes = "single"
1312
- } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1110
+ const { files = [GLOB_SVELTE], overrides = {} } = options;
1313
1111
  await ensurePackages(["eslint-plugin-svelte"]);
1314
1112
  const [pluginSvelte, parserSvelte] = await Promise.all([
1315
1113
  interopDefault(import("eslint-plugin-svelte")),
@@ -1378,23 +1176,6 @@ async function svelte(options = {}) {
1378
1176
  varsIgnorePattern: "^(_|\\$\\$Props$|\\$\\$Events$|\\$\\$Slots$)"
1379
1177
  }
1380
1178
  ],
1381
- ...stylistic2 ? {
1382
- "style/indent": "off",
1383
- // superseded by svelte/indent
1384
- "style/no-trailing-spaces": "off",
1385
- // superseded by svelte/no-trailing-spaces
1386
- "svelte/derived-has-same-inputs-outputs": "error",
1387
- "svelte/html-closing-bracket-spacing": "error",
1388
- "svelte/html-quotes": ["error", { prefer: quotes }],
1389
- "svelte/indent": [
1390
- "error",
1391
- { alignAttributesVertically: true, indent }
1392
- ],
1393
- "svelte/mustache-spacing": "error",
1394
- "svelte/no-spaces-around-equal-signs-in-attribute": "error",
1395
- "svelte/no-trailing-spaces": "error",
1396
- "svelte/spaced-html-comment": "error"
1397
- } : {},
1398
1179
  ...overrides
1399
1180
  }
1400
1181
  }
@@ -1477,7 +1258,12 @@ async function test(options = {}) {
1477
1258
  // src/configs/typescript.ts
1478
1259
  import process3 from "node:process";
1479
1260
  async function typescript(options = {}) {
1480
- const { componentExts = [], overrides = {}, overridesTypeAware = {}, parserOptions = {} } = options;
1261
+ const {
1262
+ componentExts = [],
1263
+ overrides = {},
1264
+ overridesTypeAware = {},
1265
+ parserOptions = {}
1266
+ } = options;
1481
1267
  const files = options.files ?? [
1482
1268
  GLOB_TS,
1483
1269
  GLOB_TSX,
@@ -1597,11 +1383,14 @@ async function typescript(options = {}) {
1597
1383
  "ts/no-non-null-assertion": "off",
1598
1384
  "ts/no-redeclare": ["error", { builtinGlobals: false }],
1599
1385
  "ts/no-require-imports": "error",
1600
- "ts/no-unused-expressions": ["error", {
1601
- allowShortCircuit: true,
1602
- allowTaggedTemplates: true,
1603
- allowTernary: true
1604
- }],
1386
+ "ts/no-unused-expressions": [
1387
+ "error",
1388
+ {
1389
+ allowShortCircuit: true,
1390
+ allowTaggedTemplates: true,
1391
+ allowTernary: true
1392
+ }
1393
+ ],
1605
1394
  "ts/no-unused-vars": "off",
1606
1395
  "ts/no-use-before-define": [
1607
1396
  "error",
@@ -1734,15 +1523,11 @@ async function unocss(options = {}) {
1734
1523
  }
1735
1524
 
1736
1525
  // src/configs/vue.ts
1737
- import { mergeProcessors } from "eslint-merge-processors";
1738
1526
  async function vue(options = {}) {
1739
- const { files = [GLOB_VUE], overrides = {}, stylistic: stylistic2 = true } = options;
1740
- const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1741
- const { indent = 2 } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1742
- const [pluginVue, parserVue, processorVueBlocks] = await Promise.all([
1527
+ const { files = [GLOB_VUE], overrides = {} } = options;
1528
+ const [pluginVue, parserVue] = await Promise.all([
1743
1529
  interopDefault(import("eslint-plugin-vue")),
1744
- interopDefault(import("vue-eslint-parser")),
1745
- interopDefault(import("eslint-processor-vue-blocks"))
1530
+ interopDefault(import("vue-eslint-parser"))
1746
1531
  ]);
1747
1532
  const isVue3 = getVueVersion() === 3;
1748
1533
  const configKeys = isVue3 ? ["vue3-essential", "vue3-strongly-recommended", "vue3-recommended"] : ["essential", "strongly-recommended", "recommended"];
@@ -1754,32 +1539,6 @@ async function vue(options = {}) {
1754
1539
  };
1755
1540
  }, {});
1756
1541
  return [
1757
- {
1758
- // This allows Vue plugin to work with auto imports
1759
- // https://github.com/vuejs/eslint-plugin-vue/pull/2422
1760
- languageOptions: {
1761
- globals: {
1762
- computed: "readonly",
1763
- defineEmits: "readonly",
1764
- defineExpose: "readonly",
1765
- defineProps: "readonly",
1766
- onMounted: "readonly",
1767
- onUnmounted: "readonly",
1768
- reactive: "readonly",
1769
- ref: "readonly",
1770
- shallowReactive: "readonly",
1771
- shallowRef: "readonly",
1772
- toRef: "readonly",
1773
- toRefs: "readonly",
1774
- watch: "readonly",
1775
- watchEffect: "readonly"
1776
- }
1777
- },
1778
- name: "coderwyd/vue/setup",
1779
- plugins: {
1780
- vue: pluginVue
1781
- }
1782
- },
1783
1542
  {
1784
1543
  files,
1785
1544
  languageOptions: {
@@ -1796,16 +1555,10 @@ async function vue(options = {}) {
1796
1555
  }
1797
1556
  },
1798
1557
  name: "coderwyd/vue/rules",
1799
- processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors([
1800
- pluginVue.processors[".vue"],
1801
- processorVueBlocks({
1802
- ...sfcBlocks,
1803
- blocks: {
1804
- styles: true,
1805
- ...sfcBlocks.blocks
1806
- }
1807
- })
1808
- ]),
1558
+ plugins: {
1559
+ vue: pluginVue
1560
+ },
1561
+ processor: pluginVue.processors[".vue"],
1809
1562
  rules: {
1810
1563
  ...pluginVue.configs.base.rules,
1811
1564
  ...vueRules,
@@ -1837,11 +1590,7 @@ async function vue(options = {}) {
1837
1590
  }
1838
1591
  ],
1839
1592
  // 'vue/define-props-declaration': ['warn', 'type-based'],
1840
- "vue/dot-location": ["error", "property"],
1841
- "vue/dot-notation": ["error", { allowKeywords: true }],
1842
1593
  "vue/eqeqeq": ["error", "smart"],
1843
- "vue/html-indent": ["error", indent],
1844
- "vue/html-quotes": ["error", "double"],
1845
1594
  "vue/html-self-closing": [
1846
1595
  "error",
1847
1596
  {
@@ -1858,7 +1607,6 @@ async function vue(options = {}) {
1858
1607
  "vue/multi-word-component-names": "off",
1859
1608
  // 'vue/next-tick-style': ['warn', 'promise'],
1860
1609
  "vue/no-constant-condition": "warn",
1861
- "vue/no-dupe-keys": "off",
1862
1610
  "vue/no-duplicate-attr-inheritance": "warn",
1863
1611
  "vue/no-empty-pattern": "error",
1864
1612
  "vue/no-extra-parens": ["error", "functions"],
@@ -1890,6 +1638,7 @@ async function vue(options = {}) {
1890
1638
  ignoreConstructors: false
1891
1639
  }
1892
1640
  ],
1641
+ "vue/padding-line-between-blocks": ["error", "always"],
1893
1642
  "vue/prefer-define-options": "warn",
1894
1643
  "vue/prefer-separate-static-class": "error",
1895
1644
  "vue/prefer-template": "error",
@@ -1910,50 +1659,6 @@ async function vue(options = {}) {
1910
1659
  "vue/space-infix-ops": "error",
1911
1660
  "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
1912
1661
  "vue/valid-define-options": "warn",
1913
- ...stylistic2 ? {
1914
- "vue/array-bracket-spacing": ["error", "never"],
1915
- "vue/arrow-spacing": ["error", { after: true, before: true }],
1916
- "vue/block-spacing": ["error", "always"],
1917
- "vue/block-tag-newline": [
1918
- "error",
1919
- {
1920
- multiline: "always",
1921
- singleline: "always"
1922
- }
1923
- ],
1924
- "vue/brace-style": [
1925
- "error",
1926
- "stroustrup",
1927
- { allowSingleLine: true }
1928
- ],
1929
- "vue/comma-dangle": ["error", "always-multiline"],
1930
- "vue/comma-spacing": ["error", { after: true, before: false }],
1931
- "vue/comma-style": ["error", "last"],
1932
- "vue/html-comment-content-newline": "warn",
1933
- "vue/html-comment-content-spacing": [
1934
- "error",
1935
- "always",
1936
- {
1937
- exceptions: ["-"]
1938
- }
1939
- ],
1940
- "vue/key-spacing": [
1941
- "error",
1942
- { afterColon: true, beforeColon: false }
1943
- ],
1944
- "vue/keyword-spacing": ["error", { after: true, before: true }],
1945
- "vue/object-curly-newline": "off",
1946
- "vue/object-curly-spacing": ["error", "always"],
1947
- "vue/object-property-newline": [
1948
- "error",
1949
- { allowMultiplePropertiesPerLine: true }
1950
- ],
1951
- "vue/operator-linebreak": ["error", "before"],
1952
- "vue/padding-line-between-blocks": ["error", "always"],
1953
- "vue/quote-props": ["error", "consistent-as-needed"],
1954
- "vue/space-in-parens": ["error", "never"],
1955
- "vue/template-curly-spacing": "error"
1956
- } : {},
1957
1662
  ...overrides
1958
1663
  }
1959
1664
  }
@@ -1975,23 +1680,17 @@ var defaultPluginRenaming = {
1975
1680
  "@eslint-react/dom": "react-dom",
1976
1681
  "@eslint-react/hooks-extra": "react-hooks-extra",
1977
1682
  "@eslint-react/naming-convention": "react-naming-convention",
1978
- "@stylistic": "style",
1979
1683
  "@typescript-eslint": "ts",
1980
1684
  "import-x": "import",
1981
- "n": "node",
1982
- "vitest": "test",
1983
- "yml": "yaml"
1685
+ n: "node",
1686
+ vitest: "test",
1687
+ yml: "yaml"
1984
1688
  };
1985
1689
  async function defineConfig(options = {}, ...userConfigs) {
1986
1690
  const {
1987
1691
  autoRenamePlugins = true,
1988
1692
  componentExts = [],
1989
- formatter: formatterOptions = {
1990
- css: true,
1991
- html: true
1992
- },
1993
1693
  gitignore: enableGitignore = true,
1994
- jsx: enableJsx = true,
1995
1694
  react: enableReact = false,
1996
1695
  regexp: enableRegexp = true,
1997
1696
  svelte: enableSvelte = false,
@@ -2004,11 +1703,10 @@ async function defineConfig(options = {}, ...userConfigs) {
2004
1703
  if (isInEditor2 == null) {
2005
1704
  isInEditor2 = isInEditorEnv();
2006
1705
  if (isInEditor2)
2007
- console.log("[@coderwyd/eslint-config] Detected running in editor, some rules are disabled.");
1706
+ console.log(
1707
+ "[@coderwyd/eslint-config] Detected running in editor, some rules are disabled."
1708
+ );
2008
1709
  }
2009
- const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2010
- if (stylisticOptions && !("jsx" in stylisticOptions))
2011
- stylisticOptions.jsx = enableJsx;
2012
1710
  const configs2 = [];
2013
1711
  if (enableGitignore) {
2014
1712
  if (typeof enableGitignore !== "boolean") {
@@ -2021,7 +1719,11 @@ async function defineConfig(options = {}, ...userConfigs) {
2021
1719
  ])
2022
1720
  );
2023
1721
  } else {
2024
- configs2.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({ name: "coderwyd/gitignore", strict: false })]));
1722
+ configs2.push(
1723
+ interopDefault(import("eslint-config-flat-gitignore")).then((r) => [
1724
+ r({ name: "coderwyd/gitignore", strict: false })
1725
+ ])
1726
+ );
2025
1727
  }
2026
1728
  }
2027
1729
  const typescriptOptions = resolveSubOptions(options, "typescript");
@@ -2034,22 +1736,15 @@ async function defineConfig(options = {}, ...userConfigs) {
2034
1736
  }),
2035
1737
  comments(),
2036
1738
  node(),
2037
- jsdoc({
2038
- stylistic: stylisticOptions
2039
- }),
2040
- imports({
2041
- stylistic: stylisticOptions
2042
- }),
1739
+ jsdoc(),
1740
+ imports(),
2043
1741
  unicorn(),
2044
1742
  command(),
1743
+ prettier(),
2045
1744
  // Optional plugins (installed but not enabled by default)
2046
1745
  perfectionist()
2047
1746
  );
2048
- if (enableVue)
2049
- componentExts.push("vue");
2050
- if (enableJsx) {
2051
- configs2.push(jsx());
2052
- }
1747
+ if (enableVue) componentExts.push("vue");
2053
1748
  if (enableTypeScript) {
2054
1749
  configs2.push(
2055
1750
  typescript({
@@ -2059,14 +1754,6 @@ async function defineConfig(options = {}, ...userConfigs) {
2059
1754
  })
2060
1755
  );
2061
1756
  }
2062
- if (stylisticOptions) {
2063
- configs2.push(
2064
- stylistic({
2065
- ...stylisticOptions,
2066
- overrides: getOverrides(options, "stylistic")
2067
- })
2068
- );
2069
- }
2070
1757
  if (enableRegexp)
2071
1758
  configs2.push(regexp(typeof enableRegexp === "boolean" ? {} : enableRegexp));
2072
1759
  if (options.test ?? true) {
@@ -2082,7 +1769,6 @@ async function defineConfig(options = {}, ...userConfigs) {
2082
1769
  vue({
2083
1770
  ...resolveSubOptions(options, "vue"),
2084
1771
  overrides: getOverrides(options, "typescript"),
2085
- stylistic: stylisticOptions,
2086
1772
  typescript: !!enableTypeScript
2087
1773
  })
2088
1774
  );
@@ -2099,7 +1785,6 @@ async function defineConfig(options = {}, ...userConfigs) {
2099
1785
  configs2.push(
2100
1786
  svelte({
2101
1787
  overrides: getOverrides(options, "svelte"),
2102
- stylistic: stylisticOptions,
2103
1788
  typescript: !!enableTypeScript
2104
1789
  })
2105
1790
  );
@@ -2123,32 +1808,23 @@ async function defineConfig(options = {}, ...userConfigs) {
2123
1808
  if (options.jsonc ?? true) {
2124
1809
  configs2.push(
2125
1810
  jsonc({
2126
- overrides: getOverrides(options, "jsonc"),
2127
- stylistic: stylisticOptions
1811
+ overrides: getOverrides(options, "jsonc")
2128
1812
  }),
2129
1813
  sortPackageJson(),
2130
1814
  sortTsconfig()
2131
1815
  );
2132
1816
  }
2133
- if (formatterOptions) {
2134
- configs2.push(
2135
- formatter(
2136
- formatterOptions,
2137
- typeof stylisticOptions === "boolean" ? {} : stylisticOptions
2138
- )
2139
- );
2140
- }
2141
- configs2.push(disables());
1817
+ configs2.push(specials());
2142
1818
  if ("files" in options) {
2143
- throw new Error('[@coderwyd/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.');
1819
+ throw new Error(
1820
+ '[@coderwyd/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.'
1821
+ );
2144
1822
  }
2145
1823
  const fusedConfig = flatConfigProps.reduce((acc, key) => {
2146
- if (key in options)
2147
- acc[key] = options[key];
1824
+ if (key in options) acc[key] = options[key];
2148
1825
  return acc;
2149
1826
  }, {});
2150
- if (Object.keys(fusedConfig).length > 0)
2151
- configs2.push([fusedConfig]);
1827
+ if (Object.keys(fusedConfig).length > 0) configs2.push([fusedConfig]);
2152
1828
  const merged = await combine(...configs2, ...userConfigs);
2153
1829
  if (autoRenamePlugins)
2154
1830
  return renamePluginInConfigs(merged, defaultPluginRenaming);