@lincy/eslint-config 3.7.0 → 4.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.cjs CHANGED
@@ -56,33 +56,15 @@ __export(src_exports, {
56
56
  default: () => src_default,
57
57
  ignores: () => ignores,
58
58
  imports: () => imports,
59
+ interopDefault: () => interopDefault,
59
60
  javascript: () => javascript,
60
61
  jsdoc: () => jsdoc,
61
62
  jsonc: () => jsonc,
62
63
  lincy: () => lincy,
63
64
  markdown: () => markdown,
64
65
  node: () => node,
65
- parserJsonc: () => import_jsonc_eslint_parser.default,
66
- parserTs: () => parserTs,
67
- parserVue: () => import_vue_eslint_parser.default,
68
- parserYaml: () => import_yaml_eslint_parser.default,
69
66
  perfectionist: () => perfectionist,
70
- pluginAntfu: () => import_eslint_plugin_antfu.default,
71
- pluginComments: () => import_eslint_plugin_eslint_comments.default,
72
- pluginImport: () => pluginImport,
73
- pluginJsdoc: () => import_eslint_plugin_jsdoc.default,
74
- pluginJsonc: () => pluginJsonc,
75
- pluginMarkdown: () => import_eslint_plugin_markdown.default,
76
- pluginNoOnlyTests: () => import_eslint_plugin_no_only_tests.default,
77
- pluginNode: () => import_eslint_plugin_n.default,
78
- pluginPerfectionist: () => import_eslint_plugin_perfectionist.default,
79
- pluginSortKeys: () => import_eslint_plugin_sort_keys.default,
80
- pluginStylistic: () => import_eslint_plugin.default,
81
- pluginTs: () => import_eslint_plugin2.default,
82
- pluginUnicorn: () => import_eslint_plugin_unicorn.default,
83
- pluginUnusedImports: () => import_eslint_plugin_unused_imports.default,
84
- pluginVue: () => import_eslint_plugin_vue.default,
85
- pluginYaml: () => pluginYaml,
67
+ react: () => react,
86
68
  renameRules: () => renameRules,
87
69
  sortPackageJson: () => sortPackageJson,
88
70
  sortTsconfig: () => sortTsconfig,
@@ -100,34 +82,21 @@ module.exports = __toCommonJS(src_exports);
100
82
  var import_node_process2 = __toESM(require("process"), 1);
101
83
  var import_node_fs = __toESM(require("fs"), 1);
102
84
  var import_local_pkg2 = require("local-pkg");
103
- var import_eslint_config_flat_gitignore = __toESM(require("eslint-config-flat-gitignore"), 1);
104
85
 
105
86
  // src/plugins.ts
106
87
  var import_eslint_plugin_antfu = __toESM(require("eslint-plugin-antfu"), 1);
107
88
  var import_eslint_plugin_eslint_comments = __toESM(require("eslint-plugin-eslint-comments"), 1);
108
89
  var pluginImport = __toESM(require("eslint-plugin-i"), 1);
109
- var import_eslint_plugin_jsdoc = __toESM(require("eslint-plugin-jsdoc"), 1);
110
- var pluginJsonc = __toESM(require("eslint-plugin-jsonc"), 1);
111
- var import_eslint_plugin_markdown = __toESM(require("eslint-plugin-markdown"), 1);
112
90
  var import_eslint_plugin_n = __toESM(require("eslint-plugin-n"), 1);
113
- var import_eslint_plugin = __toESM(require("@stylistic/eslint-plugin"), 1);
114
- var import_eslint_plugin2 = __toESM(require("@typescript-eslint/eslint-plugin"), 1);
115
91
  var import_eslint_plugin_unicorn = __toESM(require("eslint-plugin-unicorn"), 1);
116
92
  var import_eslint_plugin_unused_imports = __toESM(require("eslint-plugin-unused-imports"), 1);
117
- var import_eslint_plugin_vue = __toESM(require("eslint-plugin-vue"), 1);
118
- var pluginYaml = __toESM(require("eslint-plugin-yml"), 1);
119
- var import_eslint_plugin_no_only_tests = __toESM(require("eslint-plugin-no-only-tests"), 1);
120
- var import_eslint_plugin_sort_keys = __toESM(require("eslint-plugin-sort-keys"), 1);
121
93
  var import_eslint_plugin_perfectionist = __toESM(require("eslint-plugin-perfectionist"), 1);
122
- var parserTs = __toESM(require("@typescript-eslint/parser"), 1);
123
- var import_vue_eslint_parser = __toESM(require("vue-eslint-parser"), 1);
124
- var import_yaml_eslint_parser = __toESM(require("yaml-eslint-parser"), 1);
125
- var import_jsonc_eslint_parser = __toESM(require("jsonc-eslint-parser"), 1);
126
94
 
127
95
  // src/configs/comments.ts
128
- function comments() {
96
+ async function comments() {
129
97
  return [
130
98
  {
99
+ name: "eslint:comments",
131
100
  plugins: {
132
101
  "eslint-comments": import_eslint_plugin_eslint_comments.default
133
102
  },
@@ -183,7 +152,11 @@ var GLOB_EXCLUDE = [
183
152
  "**/pnpm-lock.yaml",
184
153
  "**/output",
185
154
  "**/coverage",
155
+ "**/tmp",
186
156
  "**/temp",
157
+ "**/.tmp",
158
+ "**/.temp",
159
+ "**/.history",
187
160
  "**/.vitepress/cache",
188
161
  "**/.nuxt",
189
162
  "**/.next",
@@ -201,7 +174,7 @@ var GLOB_EXCLUDE = [
201
174
  ];
202
175
 
203
176
  // src/configs/ignores.ts
204
- function ignores(options = {}) {
177
+ async function ignores(options = {}) {
205
178
  const {
206
179
  ignores: ignores2 = []
207
180
  } = options;
@@ -216,12 +189,13 @@ function ignores(options = {}) {
216
189
  }
217
190
 
218
191
  // src/configs/imports.ts
219
- function imports(options = {}) {
192
+ async function imports(options = {}) {
220
193
  const {
221
194
  stylistic: stylistic2 = true
222
195
  } = options;
223
196
  return [
224
197
  {
198
+ name: "eslint:imports",
225
199
  plugins: {
226
200
  antfu: import_eslint_plugin_antfu.default,
227
201
  import: pluginImport
@@ -246,7 +220,7 @@ function imports(options = {}) {
246
220
 
247
221
  // src/configs/javascript.ts
248
222
  var import_globals = __toESM(require("globals"), 1);
249
- function javascript(options = {}) {
223
+ async function javascript(options = {}) {
250
224
  const {
251
225
  isInEditor = false,
252
226
  overrides = {}
@@ -275,6 +249,7 @@ function javascript(options = {}) {
275
249
  linterOptions: {
276
250
  reportUnusedDisableDirectives: true
277
251
  },
252
+ name: "eslint:javascript",
278
253
  plugins: {
279
254
  "antfu": import_eslint_plugin_antfu.default,
280
255
  "unused-imports": import_eslint_plugin_unused_imports.default
@@ -458,6 +433,7 @@ function javascript(options = {}) {
458
433
  },
459
434
  {
460
435
  files: [`scripts/${GLOB_SRC}`, `cli.${GLOB_SRC_EXT}`],
436
+ name: "eslint:scripts-overrides",
461
437
  rules: {
462
438
  "no-console": "off"
463
439
  }
@@ -465,15 +441,39 @@ function javascript(options = {}) {
465
441
  ];
466
442
  }
467
443
 
444
+ // src/utils.ts
445
+ async function combine(...configs) {
446
+ const resolved = await Promise.all(configs);
447
+ return resolved.flat();
448
+ }
449
+ function renameRules(rules, from, to) {
450
+ return Object.fromEntries(
451
+ Object.entries(rules).map(([key, value]) => {
452
+ if (key.startsWith(from))
453
+ return [to + key.slice(from.length), value];
454
+ return [key, value];
455
+ })
456
+ );
457
+ }
458
+ function toArray(value) {
459
+ return Array.isArray(value) ? value : [value];
460
+ }
461
+ async function interopDefault(m) {
462
+ const resolved = await m;
463
+ return resolved.default || resolved;
464
+ }
465
+
468
466
  // src/configs/jsdoc.ts
469
- function jsdoc(options = {}) {
467
+ async function jsdoc(options = {}) {
470
468
  const {
471
469
  stylistic: stylistic2 = true
472
470
  } = options;
473
471
  return [
474
472
  {
473
+ name: "eslint:jsdoc",
475
474
  plugins: {
476
- jsdoc: import_eslint_plugin_jsdoc.default
475
+ // @ts-expect-error missing types
476
+ jsdoc: await interopDefault(import("eslint-plugin-jsdoc"))
477
477
  },
478
478
  rules: {
479
479
  "jsdoc/check-access": "warn",
@@ -501,13 +501,21 @@ function jsdoc(options = {}) {
501
501
  }
502
502
 
503
503
  // src/configs/jsonc.ts
504
- function jsonc(options = {}) {
504
+ async function jsonc(options = {}) {
505
505
  const {
506
506
  overrides = {},
507
507
  stylistic: stylistic2 = true
508
508
  } = options;
509
+ const [
510
+ pluginJsonc,
511
+ parserJsonc
512
+ ] = await Promise.all([
513
+ interopDefault(import("eslint-plugin-jsonc")),
514
+ interopDefault(import("jsonc-eslint-parser"))
515
+ ]);
509
516
  return [
510
517
  {
518
+ name: "eslint:jsonc:setup",
511
519
  plugins: {
512
520
  jsonc: pluginJsonc
513
521
  }
@@ -515,8 +523,9 @@ function jsonc(options = {}) {
515
523
  {
516
524
  files: [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
517
525
  languageOptions: {
518
- parser: import_jsonc_eslint_parser.default
526
+ parser: parserJsonc
519
527
  },
528
+ name: "eslint:jsonc:rules",
520
529
  rules: {
521
530
  "jsonc/no-bigint-literals": "error",
522
531
  "jsonc/no-binary-expression": "error",
@@ -563,19 +572,22 @@ function jsonc(options = {}) {
563
572
  }
564
573
 
565
574
  // src/configs/markdown.ts
566
- function markdown(options = {}) {
575
+ async function markdown(options = {}) {
567
576
  const {
568
577
  componentExts = [],
569
578
  overrides = {}
570
579
  } = options;
571
580
  return [
572
581
  {
582
+ name: "eslint:markdown:setup",
573
583
  plugins: {
574
- markdown: import_eslint_plugin_markdown.default
584
+ // @ts-expect-error missing types
585
+ markdown: await interopDefault(import("eslint-plugin-markdown"))
575
586
  }
576
587
  },
577
588
  {
578
589
  files: [GLOB_MARKDOWN],
590
+ name: "eslint:markdown:processor",
579
591
  processor: "markdown/markdown"
580
592
  },
581
593
  {
@@ -590,13 +602,18 @@ function markdown(options = {}) {
590
602
  }
591
603
  }
592
604
  },
605
+ name: "eslint:markdown:rules",
593
606
  rules: {
594
- "antfu/no-cjs-exports": "off",
595
607
  "antfu/no-ts-export-equal": "off",
608
+ "import/newline-after-import": "off",
596
609
  "no-alert": "off",
597
610
  "no-console": "off",
611
+ "no-labels": "off",
612
+ "no-lone-blocks": "off",
613
+ "no-restricted-syntax": "off",
598
614
  "no-undef": "off",
599
615
  "no-unused-expressions": "off",
616
+ "no-unused-labels": "off",
600
617
  "no-unused-vars": "off",
601
618
  "node/prefer-global/process": "off",
602
619
  "style/comma-dangle": "off",
@@ -637,9 +654,10 @@ function markdown(options = {}) {
637
654
  }
638
655
 
639
656
  // src/configs/node.ts
640
- function node() {
657
+ async function node() {
641
658
  return [
642
659
  {
660
+ name: "eslint:node",
643
661
  plugins: {
644
662
  node: import_eslint_plugin_n.default
645
663
  },
@@ -658,10 +676,11 @@ function node() {
658
676
  }
659
677
 
660
678
  // src/configs/sort.ts
661
- function sortPackageJson() {
679
+ async function sortPackageJson() {
662
680
  return [
663
681
  {
664
682
  files: ["**/package.json"],
683
+ name: "eslint:sort-package-json",
665
684
  rules: {
666
685
  "jsonc/sort-array-values": [
667
686
  "error",
@@ -750,6 +769,7 @@ function sortTsconfig() {
750
769
  return [
751
770
  {
752
771
  files: ["**/tsconfig.json", "**/tsconfig.*.json"],
772
+ name: "eslint:sort-tsconfig",
753
773
  rules: {
754
774
  "jsonc/sort-keys": [
755
775
  "error",
@@ -872,7 +892,7 @@ function sortTsconfig() {
872
892
  }
873
893
 
874
894
  // src/configs/stylistic.ts
875
- function stylistic(options = {}) {
895
+ async function stylistic(options = {}) {
876
896
  const {
877
897
  overrides = {},
878
898
  stylistic: stylistic2 = {}
@@ -882,15 +902,18 @@ function stylistic(options = {}) {
882
902
  jsx = true,
883
903
  quotes = "single"
884
904
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
905
+ const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
885
906
  return [
886
907
  {
908
+ name: "eslint:stylistic",
887
909
  plugins: {
888
910
  antfu: import_eslint_plugin_antfu.default,
889
- style: import_eslint_plugin.default
911
+ style: pluginStylistic
890
912
  },
891
913
  rules: {
892
914
  "antfu/consistent-list-newline": "off",
893
915
  "antfu/if-newline": "error",
916
+ "antfu/indent-binary-ops": ["error", { indent }],
894
917
  "antfu/top-level-function": "error",
895
918
  "curly": ["error", "multi-or-nest", "consistent"],
896
919
  "style/array-bracket-spacing": ["error", "never"],
@@ -928,6 +951,8 @@ function stylistic(options = {}) {
928
951
  "JSXText",
929
952
  "JSXEmptyExpression",
930
953
  "JSXSpreadChild",
954
+ "TSUnionType",
955
+ "TSIntersectionType",
931
956
  "TSTypeParameterInstantiation",
932
957
  "FunctionExpression > .params[decorators.length > 0]",
933
958
  "FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
@@ -1032,26 +1057,7 @@ function stylistic(options = {}) {
1032
1057
 
1033
1058
  // src/configs/typescript.ts
1034
1059
  var import_node_process = __toESM(require("process"), 1);
1035
-
1036
- // src/utils.ts
1037
- function combine(...configs) {
1038
- return configs.flat();
1039
- }
1040
- function renameRules(rules, from, to) {
1041
- return Object.fromEntries(
1042
- Object.entries(rules).map(([key, value]) => {
1043
- if (key.startsWith(from))
1044
- return [to + key.slice(from.length), value];
1045
- return [key, value];
1046
- })
1047
- );
1048
- }
1049
- function toArray(value) {
1050
- return Array.isArray(value) ? value : [value];
1051
- }
1052
-
1053
- // src/configs/typescript.ts
1054
- function typescript(options) {
1060
+ async function typescript(options) {
1055
1061
  const {
1056
1062
  componentExts = [],
1057
1063
  overrides = {},
@@ -1079,13 +1085,20 @@ function typescript(options) {
1079
1085
  "ts/unbound-method": "error"
1080
1086
  };
1081
1087
  const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1088
+ const [
1089
+ pluginTs,
1090
+ parserTs
1091
+ ] = await Promise.all([
1092
+ interopDefault(import("@typescript-eslint/eslint-plugin")),
1093
+ interopDefault(import("@typescript-eslint/parser"))
1094
+ ]);
1082
1095
  return [
1083
1096
  {
1084
1097
  // Install the plugins without globs, so they can be configured separately.
1098
+ name: "eslint:typescript:setup",
1085
1099
  plugins: {
1086
1100
  antfu: import_eslint_plugin_antfu.default,
1087
- import: pluginImport,
1088
- ts: import_eslint_plugin2.default
1101
+ ts: pluginTs
1089
1102
  }
1090
1103
  },
1091
1104
  {
@@ -1105,22 +1118,20 @@ function typescript(options) {
1105
1118
  ...parserOptions
1106
1119
  }
1107
1120
  },
1121
+ name: "eslint:typescript:rules",
1108
1122
  rules: {
1109
1123
  ...renameRules(
1110
- import_eslint_plugin2.default.configs["eslint-recommended"].overrides[0].rules,
1124
+ pluginTs.configs["eslint-recommended"].overrides[0].rules,
1111
1125
  "@typescript-eslint/",
1112
1126
  "ts/"
1113
1127
  ),
1114
1128
  ...renameRules(
1115
- import_eslint_plugin2.default.configs.strict.rules,
1129
+ pluginTs.configs.strict.rules,
1116
1130
  "@typescript-eslint/",
1117
1131
  "ts/"
1118
1132
  ),
1119
1133
  "antfu/generic-spacing": "error",
1120
1134
  "antfu/named-tuple-spacing": "error",
1121
- "antfu/no-cjs-exports": "error",
1122
- "antfu/no-const-enum": "error",
1123
- "antfu/no-ts-export-equal": "error",
1124
1135
  "no-dupe-class-members": "off",
1125
1136
  "no-invalid-this": "off",
1126
1137
  "no-loss-of-precision": "off",
@@ -1154,6 +1165,7 @@ function typescript(options) {
1154
1165
  },
1155
1166
  {
1156
1167
  files: ["**/*.d.ts"],
1168
+ name: "eslint:typescript:dts-overrides",
1157
1169
  rules: {
1158
1170
  "eslint-comments/no-unlimited-disable": "off",
1159
1171
  "import/no-duplicates": "off",
@@ -1163,12 +1175,14 @@ function typescript(options) {
1163
1175
  },
1164
1176
  {
1165
1177
  files: ["**/*.{test,spec}.ts?(x)"],
1178
+ name: "eslint:typescript:tests-overrides",
1166
1179
  rules: {
1167
1180
  "no-unused-expressions": "off"
1168
1181
  }
1169
1182
  },
1170
1183
  {
1171
1184
  files: ["**/*.js", "**/*.cjs"],
1185
+ name: "eslint:typescript:javascript-overrides",
1172
1186
  rules: {
1173
1187
  "ts/no-require-imports": "off",
1174
1188
  "ts/no-var-requires": "off"
@@ -1178,9 +1192,10 @@ function typescript(options) {
1178
1192
  }
1179
1193
 
1180
1194
  // src/configs/unicorn.ts
1181
- function unicorn() {
1195
+ async function unicorn() {
1182
1196
  return [
1183
1197
  {
1198
+ name: "eslint:unicorn",
1184
1199
  plugins: {
1185
1200
  unicorn: import_eslint_plugin_unicorn.default
1186
1201
  },
@@ -1224,7 +1239,7 @@ var pkg = (0, import_local_pkg.getPackageInfoSync)("vue");
1224
1239
  var vueVersion = pkg && pkg.version;
1225
1240
  vueVersion = vueVersion && vueVersion[0];
1226
1241
  vueVersion = Number.isNaN(vueVersion) ? "3" : vueVersion;
1227
- function vue(options = {}) {
1242
+ async function vue(options = {}) {
1228
1243
  const {
1229
1244
  overrides = {},
1230
1245
  stylistic: stylistic2 = true
@@ -1232,36 +1247,46 @@ function vue(options = {}) {
1232
1247
  const {
1233
1248
  indent = 4
1234
1249
  } = typeof stylistic2 === "boolean" ? {} : stylistic2;
1250
+ const [
1251
+ pluginVue,
1252
+ parserVue
1253
+ ] = await Promise.all([
1254
+ // @ts-expect-error missing types
1255
+ interopDefault(import("eslint-plugin-vue")),
1256
+ interopDefault(import("vue-eslint-parser"))
1257
+ ]);
1235
1258
  return [
1236
1259
  {
1260
+ name: "eslint:vue:setup",
1237
1261
  plugins: {
1238
- vue: import_eslint_plugin_vue.default
1262
+ vue: pluginVue
1239
1263
  }
1240
1264
  },
1241
1265
  {
1242
1266
  files: [GLOB_VUE],
1243
1267
  languageOptions: {
1244
- parser: import_vue_eslint_parser.default,
1268
+ parser: parserVue,
1245
1269
  parserOptions: {
1246
1270
  ecmaFeatures: {
1247
1271
  jsx: true
1248
1272
  },
1249
1273
  extraFileExtensions: [".vue"],
1250
- parser: options.typescript ? parserTs : null,
1274
+ parser: options.typescript ? await interopDefault(import("@typescript-eslint/parser")) : null,
1251
1275
  sourceType: "module"
1252
1276
  }
1253
1277
  },
1254
- processor: import_eslint_plugin_vue.default.processors[".vue"],
1278
+ name: "eslint:vue:rules",
1279
+ processor: pluginVue.processors[".vue"],
1255
1280
  rules: {
1256
- ...import_eslint_plugin_vue.default.configs.base.rules,
1281
+ ...pluginVue.configs.base.rules,
1257
1282
  ...vueVersion === "3" ? {
1258
- ...import_eslint_plugin_vue.default.configs["vue3-essential"].rules,
1259
- ...import_eslint_plugin_vue.default.configs["vue3-strongly-recommended"].rules,
1260
- ...import_eslint_plugin_vue.default.configs["vue3-recommended"].rules
1283
+ ...pluginVue.configs["vue3-essential"].rules,
1284
+ ...pluginVue.configs["vue3-strongly-recommended"].rules,
1285
+ ...pluginVue.configs["vue3-recommended"].rules
1261
1286
  } : {
1262
- ...import_eslint_plugin_vue.default.configs.essential.rules,
1263
- ...import_eslint_plugin_vue.default.configs["strongly-recommended"].rules,
1264
- ...import_eslint_plugin_vue.default.configs.recommended.rules
1287
+ ...pluginVue.configs.essential.rules,
1288
+ ...pluginVue.configs["strongly-recommended"].rules,
1289
+ ...pluginVue.configs.recommended.rules
1265
1290
  },
1266
1291
  "node/prefer-global/process": "off",
1267
1292
  "vue/block-order": ["error", {
@@ -1355,13 +1380,21 @@ function vue(options = {}) {
1355
1380
  }
1356
1381
 
1357
1382
  // src/configs/yaml.ts
1358
- function yaml(options = {}) {
1383
+ async function yaml(options = {}) {
1359
1384
  const {
1360
1385
  overrides = {},
1361
1386
  stylistic: stylistic2 = true
1362
1387
  } = options;
1388
+ const [
1389
+ pluginYaml,
1390
+ parserYaml
1391
+ ] = await Promise.all([
1392
+ interopDefault(import("eslint-plugin-yml")),
1393
+ interopDefault(import("yaml-eslint-parser"))
1394
+ ]);
1363
1395
  return [
1364
1396
  {
1397
+ name: "eslint:yaml:setup",
1365
1398
  plugins: {
1366
1399
  yaml: pluginYaml
1367
1400
  }
@@ -1369,8 +1402,9 @@ function yaml(options = {}) {
1369
1402
  {
1370
1403
  files: [GLOB_YAML],
1371
1404
  languageOptions: {
1372
- parser: import_yaml_eslint_parser.default
1405
+ parser: parserYaml
1373
1406
  },
1407
+ name: "eslint:yaml:rules",
1374
1408
  rules: {
1375
1409
  "style/spaced-comment": "off",
1376
1410
  "yaml/block-mapping": "error",
@@ -1400,21 +1434,43 @@ function yaml(options = {}) {
1400
1434
  }
1401
1435
 
1402
1436
  // src/configs/test.ts
1403
- function test(options = {}) {
1437
+ async function test(options = {}) {
1404
1438
  const {
1405
1439
  isInEditor = false,
1406
1440
  overrides = {}
1407
1441
  } = options;
1442
+ const [
1443
+ pluginVitest,
1444
+ pluginNoOnlyTests
1445
+ ] = await Promise.all([
1446
+ interopDefault(import("eslint-plugin-vitest")),
1447
+ // @ts-expect-error missing types
1448
+ interopDefault(import("eslint-plugin-no-only-tests"))
1449
+ ]);
1408
1450
  return [
1409
1451
  {
1452
+ name: "eslint:test:setup",
1410
1453
  plugins: {
1411
- "no-only-tests": import_eslint_plugin_no_only_tests.default
1454
+ test: {
1455
+ ...pluginVitest,
1456
+ rules: {
1457
+ ...pluginVitest.rules,
1458
+ // extend `test/no-only-tests` rule
1459
+ ...pluginNoOnlyTests.rules
1460
+ }
1461
+ }
1412
1462
  }
1413
1463
  },
1414
1464
  {
1415
1465
  files: GLOB_TESTS,
1466
+ name: "eslint:test:rules",
1416
1467
  rules: {
1417
- "no-only-tests/no-only-tests": isInEditor ? "off" : "error",
1468
+ "node/prefer-global/process": "off",
1469
+ "test/consistent-test-it": ["error", { fn: "it", withinDescribe: "it" }],
1470
+ "test/no-identical-title": "error",
1471
+ "test/no-only-tests": isInEditor ? "off" : "error",
1472
+ "test/prefer-hooks-in-order": "error",
1473
+ "test/prefer-lowercase-title": "error",
1418
1474
  ...overrides
1419
1475
  }
1420
1476
  }
@@ -1422,9 +1478,10 @@ function test(options = {}) {
1422
1478
  }
1423
1479
 
1424
1480
  // src/configs/perfectionist.ts
1425
- function perfectionist() {
1481
+ async function perfectionist() {
1426
1482
  return [
1427
1483
  {
1484
+ name: "eslint:perfectionist",
1428
1485
  plugins: {
1429
1486
  perfectionist: import_eslint_plugin_perfectionist.default
1430
1487
  }
@@ -1432,6 +1489,86 @@ function perfectionist() {
1432
1489
  ];
1433
1490
  }
1434
1491
 
1492
+ // src/configs/react.ts
1493
+ async function react(options = {}) {
1494
+ const {
1495
+ jsx = true,
1496
+ overrides = {},
1497
+ version = "17.0"
1498
+ } = options;
1499
+ const [
1500
+ pluginReact,
1501
+ pluginReactHooks
1502
+ ] = await Promise.all([
1503
+ // @ts-expect-error missing types
1504
+ interopDefault(import("eslint-plugin-react")),
1505
+ // @ts-expect-error missing types
1506
+ interopDefault(import("eslint-plugin-react-hooks"))
1507
+ ]);
1508
+ return [
1509
+ {
1510
+ name: "eslint:react:setup",
1511
+ plugins: {
1512
+ "react": pluginReact,
1513
+ "react-hooks": pluginReactHooks
1514
+ }
1515
+ },
1516
+ {
1517
+ files: [GLOB_JSX, GLOB_TSX],
1518
+ languageOptions: {
1519
+ parserOptions: {
1520
+ ecmaFeatures: {
1521
+ jsx
1522
+ }
1523
+ }
1524
+ },
1525
+ name: "eslint:react:rules",
1526
+ rules: {
1527
+ ...pluginReact.configs.all.rules,
1528
+ ...pluginReactHooks.configs.recommended.rules,
1529
+ "react/forbid-component-props": "off",
1530
+ // 禁止组件上使用某些 props
1531
+ "react/hook-use-state": "off",
1532
+ // useState 钩子值和 setter 变量的解构和对称命名
1533
+ "react/jsx-filename-extension": "off",
1534
+ // 禁止可能包含 JSX 文件扩展名
1535
+ "react/jsx-max-depth": "off",
1536
+ // 强制 JSX 最大深度
1537
+ "react/jsx-no-bind": "off",
1538
+ // .bind()JSX 属性中禁止使用箭头函数
1539
+ "react/jsx-no-literals": "off",
1540
+ // 禁止在 JSX 中使用字符串文字
1541
+ "react/jsx-props-no-spreading": "off",
1542
+ // 强制任何 JSX 属性都不会传播
1543
+ "react/no-danger": "off",
1544
+ // 禁止使用 dangerouslySetInnerHTML
1545
+ "react/no-unsafe": "off",
1546
+ // 禁止使用不安全的生命周期方法
1547
+ "react/react-in-jsx-scope": "off",
1548
+ // 使用 JSX 时需要引入 React
1549
+ "react/require-default-props": "off",
1550
+ // 为每个非必需 prop 强制执行 defaultProps 定义
1551
+ "style/jsx-first-prop-new-line": "off",
1552
+ // 强制 JSX 中第一个属性的正确位置
1553
+ "style/jsx-max-props-per-line": ["error", { maximum: 4 }],
1554
+ // 在 JSX 中的单行上强制执行最多 props 数量
1555
+ "style/jsx-newline": "off",
1556
+ // 在 jsx 元素和表达式之后换行
1557
+ "style/jsx-one-expression-per-line": "off",
1558
+ // 每行一个 JSX 元素
1559
+ "style/jsx-quotes": ["error", "prefer-double"],
1560
+ // 强制在 JSX 属性中一致使用双引号或单引号
1561
+ ...overrides
1562
+ },
1563
+ settings: {
1564
+ react: {
1565
+ version
1566
+ }
1567
+ }
1568
+ }
1569
+ ];
1570
+ }
1571
+
1435
1572
  // src/factory.ts
1436
1573
  var flatConfigProps = [
1437
1574
  "files",
@@ -1449,25 +1586,34 @@ var VuePackages = [
1449
1586
  "vitepress",
1450
1587
  "@slidev/cli"
1451
1588
  ];
1452
- function lincy(options = {}, ...userConfigs) {
1589
+ var ReactPackages = [
1590
+ "react",
1591
+ "next"
1592
+ ];
1593
+ async function lincy(options = {}, ...userConfigs) {
1453
1594
  const {
1454
1595
  componentExts = [],
1455
1596
  gitignore: enableGitignore = true,
1456
1597
  isInEditor = !!((import_node_process2.default.env.VSCODE_PID || import_node_process2.default.env.JETBRAINS_IDE) && !import_node_process2.default.env.CI),
1457
1598
  overrides = {},
1599
+ react: enableReact = ReactPackages.some((i) => (0, import_local_pkg2.isPackageExists)(i)),
1458
1600
  typescript: enableTypeScript = (0, import_local_pkg2.isPackageExists)("typescript"),
1459
1601
  vue: enableVue = VuePackages.some((i) => (0, import_local_pkg2.isPackageExists)(i))
1460
1602
  } = options;
1461
1603
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
1462
- if (stylisticOptions && !("jsx" in stylisticOptions))
1463
- stylisticOptions.jsx = options.jsx ?? true;
1604
+ if (stylisticOptions) {
1605
+ if (!("jsx" in stylisticOptions))
1606
+ stylisticOptions.jsx = options.jsx ?? true;
1607
+ if (enableReact)
1608
+ stylisticOptions.jsx = false;
1609
+ }
1464
1610
  const configs = [];
1465
1611
  if (enableGitignore) {
1466
1612
  if (typeof enableGitignore !== "boolean") {
1467
- configs.push([(0, import_eslint_config_flat_gitignore.default)(enableGitignore)]);
1613
+ configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r(enableGitignore)]));
1468
1614
  } else {
1469
1615
  if (import_node_fs.default.existsSync(".gitignore"))
1470
- configs.push([(0, import_eslint_config_flat_gitignore.default)()]);
1616
+ configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r()]));
1471
1617
  }
1472
1618
  }
1473
1619
  configs.push(
@@ -1518,6 +1664,12 @@ function lincy(options = {}, ...userConfigs) {
1518
1664
  typescript: !!enableTypeScript
1519
1665
  }));
1520
1666
  }
1667
+ if (enableReact) {
1668
+ configs.push(react({
1669
+ overrides: overrides.react,
1670
+ ...typeof enableReact !== "boolean" ? enableReact : {}
1671
+ }));
1672
+ }
1521
1673
  if (options.jsonc ?? true) {
1522
1674
  configs.push(
1523
1675
  jsonc({
@@ -1583,33 +1735,15 @@ var src_default = lincy;
1583
1735
  comments,
1584
1736
  ignores,
1585
1737
  imports,
1738
+ interopDefault,
1586
1739
  javascript,
1587
1740
  jsdoc,
1588
1741
  jsonc,
1589
1742
  lincy,
1590
1743
  markdown,
1591
1744
  node,
1592
- parserJsonc,
1593
- parserTs,
1594
- parserVue,
1595
- parserYaml,
1596
1745
  perfectionist,
1597
- pluginAntfu,
1598
- pluginComments,
1599
- pluginImport,
1600
- pluginJsdoc,
1601
- pluginJsonc,
1602
- pluginMarkdown,
1603
- pluginNoOnlyTests,
1604
- pluginNode,
1605
- pluginPerfectionist,
1606
- pluginSortKeys,
1607
- pluginStylistic,
1608
- pluginTs,
1609
- pluginUnicorn,
1610
- pluginUnusedImports,
1611
- pluginVue,
1612
- pluginYaml,
1746
+ react,
1613
1747
  renameRules,
1614
1748
  sortPackageJson,
1615
1749
  sortTsconfig,