@lincy/eslint-config 7.1.2 → 8.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
@@ -19,7 +19,7 @@ var __copyProps = (to, from, except, desc) => {
19
19
  }
20
20
  return to;
21
21
  };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
23
23
  value: mod,
24
24
  enumerable: true
25
25
  }) : target, mod));
@@ -88,22 +88,6 @@ function findUpSync(name, { cwd = node_process.default.cwd(), type = "file", sto
88
88
  }
89
89
  }
90
90
  //#endregion
91
- //#region src/configs/comments.ts
92
- async function comments(options = {}) {
93
- const { overrides = {} } = options;
94
- return [{
95
- name: "eslint/comments/rules",
96
- plugins: { "eslint-comments": _eslint_community_eslint_plugin_eslint_comments.default },
97
- rules: {
98
- "eslint-comments/no-aggregating-enable": "error",
99
- "eslint-comments/no-duplicate-disable": "error",
100
- "eslint-comments/no-unlimited-disable": "error",
101
- "eslint-comments/no-unused-enable": "error",
102
- ...overrides
103
- }
104
- }];
105
- }
106
- //#endregion
107
91
  //#region src/globs.ts
108
92
  const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
109
93
  const GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
@@ -184,6 +168,163 @@ const GLOB_EXCLUDE = [
184
168
  "**/.*/skills"
185
169
  ];
186
170
  //#endregion
171
+ //#region src/utils.ts
172
+ const scopeUrl = (0, node_url.fileURLToPath)(new URL(".", require("url").pathToFileURL(__filename).href));
173
+ const isCwdInScope = (0, local_pkg.isPackageExists)("@antfu/eslint-config");
174
+ const parserPlain = {
175
+ meta: { name: "parser-plain" },
176
+ parseForESLint: (code) => ({
177
+ ast: {
178
+ body: [],
179
+ comments: [],
180
+ loc: {
181
+ end: code.length,
182
+ start: 0
183
+ },
184
+ range: [0, code.length],
185
+ tokens: [],
186
+ type: "Program"
187
+ },
188
+ scopeManager: null,
189
+ services: { isPlain: true },
190
+ visitorKeys: { Program: [] }
191
+ })
192
+ };
193
+ /**
194
+ * Combine array and non-array configs into a single array.
195
+ */
196
+ async function combine(...configs) {
197
+ return (await Promise.all(configs)).flat();
198
+ }
199
+ function renameRules(rules, map) {
200
+ return Object.fromEntries(Object.entries(rules).map(([key, value]) => {
201
+ for (const [from, to] of Object.entries(map)) if (key.startsWith(`${from}/`)) return [to + key.slice(from.length), value];
202
+ return [key, value];
203
+ }));
204
+ }
205
+ function renamePluginInConfigs(configs, map) {
206
+ return configs.map((i) => {
207
+ const clone = { ...i };
208
+ if (clone.rules) clone.rules = renameRules(clone.rules, map);
209
+ if (clone.plugins) clone.plugins = Object.fromEntries(Object.entries(clone.plugins).map(([key, value]) => {
210
+ if (key in map) return [map[key], value];
211
+ return [key, value];
212
+ }));
213
+ return clone;
214
+ });
215
+ }
216
+ function toArray(value) {
217
+ return Array.isArray(value) ? value : [value];
218
+ }
219
+ async function interopDefault(m) {
220
+ const resolved = await m;
221
+ return resolved.default || resolved;
222
+ }
223
+ function isPackageInScope(name) {
224
+ return (0, local_pkg.isPackageExists)(name, { paths: [scopeUrl] });
225
+ }
226
+ async function ensurePackages(packages) {
227
+ if (node_process.default.env.CI || node_process.default.stdout.isTTY === false || isCwdInScope === false) return;
228
+ const nonExistingPackages = packages.filter((i) => i && !isPackageInScope(i));
229
+ if (nonExistingPackages.length === 0) return;
230
+ if (await (await import("@clack/prompts")).confirm({
231
+ /** message: `${nonExistingPackages.length === 1 ? 'Package is' : 'Packages are'} required for this config: ${nonExistingPackages.join(', ')}. Do you want to install them?`, */
232
+ message: `此配置需要软件包: ${nonExistingPackages.join(", ")}. 你想安装它们吗?` })) await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
233
+ }
234
+ function isInEditorEnv() {
235
+ if (node_process.default.env.CI) return false;
236
+ if (isInGitHooksOrLintStaged()) return false;
237
+ return !!(node_process.default.env.VSCODE_PID || node_process.default.env.VSCODE_CWD || node_process.default.env.JETBRAINS_IDE || node_process.default.env.VIM || node_process.default.env.NVIM);
238
+ }
239
+ function isInGitHooksOrLintStaged() {
240
+ return !!(node_process.default.env.GIT_PARAMS || node_process.default.env.VSCODE_GIT_COMMAND || node_process.default.env.npm_lifecycle_script?.startsWith("lint-staged"));
241
+ }
242
+ //#endregion
243
+ //#region src/configs/antislop.ts
244
+ async function antislop(options = {}) {
245
+ const { cognitiveComplexity = 15, overrides = {}, slop = true, sonarjs = true } = options;
246
+ await ensurePackages([...slop ? ["eslint-plugin-slop"] : [], ...sonarjs ? ["eslint-plugin-sonarjs"] : []]);
247
+ const [pluginSlop, pluginSonarjs] = await Promise.all([slop ? interopDefault(import("eslint-plugin-slop")) : void 0, sonarjs ? interopDefault(import("eslint-plugin-sonarjs")) : void 0]);
248
+ return [
249
+ {
250
+ name: "eslint/antislop/setup",
251
+ plugins: {
252
+ ...slop ? { slop: pluginSlop } : {},
253
+ ...sonarjs ? { sonarjs: pluginSonarjs } : {}
254
+ },
255
+ ...typeof slop === "object" ? { settings: { slop } } : {}
256
+ },
257
+ ...slop ? [{
258
+ files: [
259
+ ...GLOB_ALL_SRC,
260
+ GLOB_JSONC,
261
+ GLOB_TOML,
262
+ GLOB_GRAPHQL
263
+ ],
264
+ /**
265
+ * Markdown code fences are already scanned as part of the raw
266
+ * Markdown text, so exclude the virtual embedded-code files to
267
+ * avoid reporting the same em dash twice
268
+ */
269
+ ignores: [GLOB_MARKDOWN_CODE],
270
+ name: "eslint/antislop/rules/universal",
271
+ rules: { "slop/no-em-dash": "error" }
272
+ }] : [],
273
+ {
274
+ files: [GLOB_SRC],
275
+ name: "eslint/antislop/rules/javascript",
276
+ rules: {
277
+ ...slop ? {
278
+ "slop/max-comment-length": "error",
279
+ "slop/no-chained-type-assertions": "error",
280
+ "slop/no-jargon": "error",
281
+ "slop/no-trivial-functions": "error",
282
+ "slop/no-trivial-type-aliases": "error",
283
+ "slop/prefer-jsdoc": "error"
284
+ } : {},
285
+ ...sonarjs ? {
286
+ ...cognitiveComplexity === false ? {} : { "sonarjs/cognitive-complexity": ["error", cognitiveComplexity] },
287
+ "sonarjs/no-all-duplicated-branches": "error",
288
+ "sonarjs/no-collapsible-if": "error",
289
+ "sonarjs/no-commented-code": "error",
290
+ "sonarjs/no-dead-store": "error",
291
+ "sonarjs/no-duplicated-branches": "error",
292
+ "sonarjs/no-element-overwrite": "error",
293
+ "sonarjs/no-empty-collection": "error",
294
+ "sonarjs/no-gratuitous-expressions": "error",
295
+ "sonarjs/no-identical-conditions": "error",
296
+ "sonarjs/no-identical-expressions": "error",
297
+ "sonarjs/no-identical-functions": "error",
298
+ "sonarjs/no-invariant-returns": "error",
299
+ "sonarjs/no-inverted-boolean-check": "error",
300
+ "sonarjs/no-redundant-boolean": "error",
301
+ "sonarjs/no-redundant-jump": "error",
302
+ "sonarjs/no-unused-collection": "error",
303
+ "sonarjs/no-use-of-empty-return-value": "error",
304
+ "sonarjs/prefer-single-boolean-return": "error"
305
+ } : {},
306
+ ...overrides
307
+ }
308
+ }
309
+ ];
310
+ }
311
+ //#endregion
312
+ //#region src/configs/comments.ts
313
+ async function comments(options = {}) {
314
+ const { overrides = {} } = options;
315
+ return [{
316
+ name: "eslint/comments/rules",
317
+ plugins: { "eslint-comments": _eslint_community_eslint_plugin_eslint_comments.default },
318
+ rules: {
319
+ "eslint-comments/no-aggregating-enable": "error",
320
+ "eslint-comments/no-duplicate-disable": "error",
321
+ "eslint-comments/no-unlimited-disable": "error",
322
+ "eslint-comments/no-unused-enable": "error",
323
+ ...overrides
324
+ }
325
+ }];
326
+ }
327
+ //#endregion
187
328
  //#region src/configs/disables.ts
188
329
  async function disables() {
189
330
  return [
@@ -251,6 +392,7 @@ async function e18e(options = {}) {
251
392
  ...moduleReplacements ? { ...configs.moduleReplacements.rules } : {},
252
393
  ...performanceImprovements ? { ...configs.performanceImprovements.rules } : {},
253
394
  ...type === "lib" ? {} : { "e18e/prefer-static-regex": "off" },
395
+ /** these are a bit opinionated and dangerous (introducing behavioral changes), so we'll disable them by default for now */
254
396
  "e18e/prefer-array-at": "off",
255
397
  "e18e/prefer-array-from-map": "off",
256
398
  "e18e/prefer-array-to-reversed": "off",
@@ -262,78 +404,9 @@ async function e18e(options = {}) {
262
404
  }];
263
405
  }
264
406
  //#endregion
265
- //#region src/utils.ts
266
- const scopeUrl = (0, node_url.fileURLToPath)(new URL(".", require("url").pathToFileURL(__filename).href));
267
- const isCwdInScope = (0, local_pkg.isPackageExists)("@antfu/eslint-config");
268
- const parserPlain = {
269
- meta: { name: "parser-plain" },
270
- parseForESLint: (code) => ({
271
- ast: {
272
- body: [],
273
- comments: [],
274
- loc: {
275
- end: code.length,
276
- start: 0
277
- },
278
- range: [0, code.length],
279
- tokens: [],
280
- type: "Program"
281
- },
282
- scopeManager: null,
283
- services: { isPlain: true },
284
- visitorKeys: { Program: [] }
285
- })
286
- };
287
- /**
288
- * Combine array and non-array configs into a single array.
289
- */
290
- async function combine(...configs) {
291
- return (await Promise.all(configs)).flat();
292
- }
293
- function renameRules(rules, map) {
294
- return Object.fromEntries(Object.entries(rules).map(([key, value]) => {
295
- for (const [from, to] of Object.entries(map)) if (key.startsWith(`${from}/`)) return [to + key.slice(from.length), value];
296
- return [key, value];
297
- }));
298
- }
299
- function renamePluginInConfigs(configs, map) {
300
- return configs.map((i) => {
301
- const clone = { ...i };
302
- if (clone.rules) clone.rules = renameRules(clone.rules, map);
303
- if (clone.plugins) clone.plugins = Object.fromEntries(Object.entries(clone.plugins).map(([key, value]) => {
304
- if (key in map) return [map[key], value];
305
- return [key, value];
306
- }));
307
- return clone;
308
- });
309
- }
310
- function toArray(value) {
311
- return Array.isArray(value) ? value : [value];
312
- }
313
- async function interopDefault(m) {
314
- const resolved = await m;
315
- return resolved.default || resolved;
316
- }
317
- function isPackageInScope(name) {
318
- return (0, local_pkg.isPackageExists)(name, { paths: [scopeUrl] });
319
- }
320
- async function ensurePackages(packages) {
321
- if (node_process.default.env.CI || node_process.default.stdout.isTTY === false || isCwdInScope === false) return;
322
- const nonExistingPackages = packages.filter((i) => i && !isPackageInScope(i));
323
- if (nonExistingPackages.length === 0) return;
324
- if (await (await import("@clack/prompts")).confirm({ message: `此配置需要软件包: ${nonExistingPackages.join(", ")}. 你想安装它们吗?` })) await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
325
- }
326
- function isInEditorEnv() {
327
- if (node_process.default.env.CI) return false;
328
- if (isInGitHooksOrLintStaged()) return false;
329
- return !!(node_process.default.env.VSCODE_PID || node_process.default.env.VSCODE_CWD || node_process.default.env.JETBRAINS_IDE || node_process.default.env.VIM || node_process.default.env.NVIM);
330
- }
331
- function isInGitHooksOrLintStaged() {
332
- return !!(node_process.default.env.GIT_PARAMS || node_process.default.env.VSCODE_GIT_COMMAND || node_process.default.env.npm_lifecycle_script?.startsWith("lint-staged"));
333
- }
334
- //#endregion
335
407
  //#region src/configs/stylistic.ts
336
408
  const StylisticConfigDefaults = {
409
+ braceStyle: "stroustrup",
337
410
  indent: 4,
338
411
  jsx: true,
339
412
  lessOpinionated: false,
@@ -343,12 +416,13 @@ const StylisticConfigDefaults = {
343
416
  };
344
417
  async function stylistic(options = {}) {
345
418
  const { overrides = {}, stylistic = StylisticConfigDefaults } = options;
346
- const { indent, jsx, lessOpinionated, quotes, semi } = typeof stylistic === "boolean" ? StylisticConfigDefaults : {
419
+ const { braceStyle, indent, jsx, lessOpinionated, quotes, semi } = typeof stylistic === "boolean" ? StylisticConfigDefaults : {
347
420
  ...StylisticConfigDefaults,
348
421
  ...stylistic
349
422
  };
350
423
  const pluginStylistic = await interopDefault(import("@stylistic/eslint-plugin"));
351
424
  const config = pluginStylistic.configs.customize({
425
+ braceStyle,
352
426
  indent,
353
427
  jsx,
354
428
  pluginName: "style",
@@ -605,6 +679,7 @@ async function javascript(options = {}) {
605
679
  "no-class-assign": "error",
606
680
  "no-compare-neg-zero": "error",
607
681
  "no-cond-assign": ["error", "always"],
682
+ /** 'no-console': ['error', { allow: ['warn', 'error'] }], */
608
683
  "no-console": "off",
609
684
  "no-const-assign": "error",
610
685
  "no-control-regex": "error",
@@ -896,6 +971,11 @@ async function markdown(options = {}) {
896
971
  files,
897
972
  ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
898
973
  name: "eslint/markdown/processor",
974
+ /**
975
+ * `eslint-plugin-markdown` only creates virtual files for code blocks,
976
+ * but not the markdown file itself. We use `eslint-merge-processors` to
977
+ * add a pass-through processor for the markdown file itself.
978
+ */
899
979
  processor: (0, eslint_merge_processors.mergeProcessors)([markdown.processors.markdown, eslint_merge_processors.processorPassThrough])
900
980
  },
901
981
  {
@@ -909,6 +989,7 @@ async function markdown(options = {}) {
909
989
  rules: {
910
990
  ...markdown.configs.recommended.at(0)?.rules,
911
991
  "markdown/fenced-code-language": "off",
992
+ /** https://github.com/eslint/markdown/issues/294 */
912
993
  "markdown/no-missing-label-refs": "off",
913
994
  ...overridesMarkdown
914
995
  }
@@ -917,6 +998,7 @@ async function markdown(options = {}) {
917
998
  files,
918
999
  name: "eslint/markdown/disables/markdown",
919
1000
  rules: {
1001
+ /** Disable rules do not work with markdown sourcecode. */
920
1002
  "command/command": "off",
921
1003
  "no-irregular-whitespace": "off",
922
1004
  "perfectionist/sort-exports": "off",
@@ -1088,7 +1170,7 @@ async function pnpm(options) {
1088
1170
  interopDefault(import("eslint-plugin-yml")),
1089
1171
  interopDefault(import("yaml-eslint-parser"))
1090
1172
  ]);
1091
- const { catalogs = await detectCatalogUsage(), isInEditor = false, json = true, sort = true, yaml = true } = options;
1173
+ const { catalogs = await detectCatalogUsage(), isInEditor = false, json = true, sort = true, stylistic = true, yaml = true } = options;
1092
1174
  const configs = [];
1093
1175
  if (json) configs.push({
1094
1176
  files: ["package.json", "**/package.json"],
@@ -1104,100 +1186,230 @@ async function pnpm(options) {
1104
1186
  "pnpm/json-valid-catalog": ["error", { autofix: !isInEditor }]
1105
1187
  }
1106
1188
  });
1107
- if (yaml) {
1108
- configs.push({
1109
- files: ["pnpm-workspace.yaml"],
1110
- languageOptions: { parser: yamlParser },
1111
- name: "eslint/pnpm/pnpm-workspace-yaml",
1112
- plugins: { pnpm: pluginPnpm },
1113
- rules: {
1114
- "pnpm/yaml-enforce-settings": ["error", { settings: {
1115
- shellEmulator: true,
1116
- trustPolicy: "no-downgrade"
1117
- } }],
1118
- "pnpm/yaml-no-duplicate-catalog-item": "error",
1119
- "pnpm/yaml-no-unused-catalog-item": "error"
1120
- }
1121
- });
1122
- if (sort) configs.push({
1123
- files: ["pnpm-workspace.yaml"],
1124
- languageOptions: { parser: yamlParser },
1125
- name: "eslint/pnpm/pnpm-workspace-yaml-sort",
1126
- plugins: { yaml: pluginYaml },
1127
- rules: { "yaml/sort-keys": [
1128
- "error",
1129
- {
1130
- order: [
1131
- ...[
1132
- "cacheDir",
1133
- "catalogMode",
1134
- "cleanupUnusedCatalogs",
1135
- "dedupeDirectDeps",
1136
- "deployAllFiles",
1137
- "enablePrePostScripts",
1138
- "engineStrict",
1139
- "extendNodePath",
1140
- "hoist",
1141
- "hoistPattern",
1142
- "hoistWorkspacePackages",
1143
- "ignoreCompatibilityDb",
1144
- "ignoreDepScripts",
1145
- "ignoreScripts",
1146
- "ignoreWorkspaceRootCheck",
1147
- "managePackageManagerVersions",
1148
- "minimumReleaseAge",
1149
- "minimumReleaseAgeExclude",
1150
- "modulesDir",
1151
- "nodeLinker",
1152
- "nodeVersion",
1153
- "optimisticRepeatInstall",
1154
- "packageManagerStrict",
1155
- "packageManagerStrictVersion",
1156
- "preferSymlinkedExecutables",
1157
- "preferWorkspacePackages",
1158
- "publicHoistPattern",
1159
- "registrySupportsTimeField",
1160
- "requiredScripts",
1161
- "resolutionMode",
1162
- "savePrefix",
1163
- "scriptShell",
1164
- "shamefullyHoist",
1165
- "shellEmulator",
1166
- "stateDir",
1167
- "supportedArchitectures",
1168
- "symlink",
1169
- "tag",
1170
- "trustPolicy",
1171
- "trustPolicyExclude",
1172
- "updateNotifier"
1173
- ],
1174
- "packages",
1175
- "overrides",
1176
- "patchedDependencies",
1177
- "catalog",
1178
- "catalogs",
1179
- ...[
1180
- "allowedDeprecatedVersions",
1181
- "allowNonAppliedPatches",
1182
- "configDependencies",
1183
- "ignoredBuiltDependencies",
1184
- "ignoredOptionalDependencies",
1185
- "neverBuiltDependencies",
1186
- "onlyBuiltDependencies",
1187
- "onlyBuiltDependenciesFile",
1188
- "packageExtensions",
1189
- "peerDependencyRules"
1190
- ]
1189
+ if (yaml) configs.push({
1190
+ files: ["pnpm-workspace.yaml"],
1191
+ languageOptions: { parser: yamlParser },
1192
+ name: "eslint/pnpm/pnpm-workspace-yaml",
1193
+ plugins: { pnpm: pluginPnpm },
1194
+ rules: {
1195
+ "pnpm/yaml-enforce-settings": ["error", { settings: {
1196
+ minimumReleaseAgeExcludePrune: true,
1197
+ shellEmulator: true
1198
+ } }],
1199
+ "pnpm/yaml-no-duplicate-catalog-item": "error",
1200
+ "pnpm/yaml-no-unused-catalog-item": "error"
1201
+ }
1202
+ });
1203
+ if (yaml && stylistic) configs.push({
1204
+ files: ["pnpm-workspace.yaml"],
1205
+ languageOptions: { parser: yamlParser },
1206
+ name: "antfu/pnpm/pnpm-workspace-yaml-stylistic",
1207
+ plugins: { pnpm: pluginPnpm },
1208
+ rules: { "pnpm/yaml-blank-lines": "error" }
1209
+ });
1210
+ if (yaml && sort) configs.push({
1211
+ files: ["pnpm-workspace.yaml"],
1212
+ languageOptions: { parser: yamlParser },
1213
+ name: "eslint/pnpm/pnpm-workspace-yaml-sort",
1214
+ plugins: { yaml: pluginYaml },
1215
+ rules: { "yaml/sort-keys": [
1216
+ "error",
1217
+ {
1218
+ order: [
1219
+ ...[
1220
+ "dedupeInjectedDeps",
1221
+ "disallowWorkspaceCycles",
1222
+ "failIfNoMatch",
1223
+ "ignoreWorkspaceCycles",
1224
+ "ignoreWorkspaceRootCheck",
1225
+ "includeWorkspaceRoot",
1226
+ "injectWorkspacePackages",
1227
+ "legacyDirFiltering",
1228
+ "linkWorkspacePackages",
1229
+ "preferWorkspacePackages",
1230
+ "saveWorkspaceProtocol",
1231
+ "sharedWorkspaceLockfile",
1232
+ "syncInjectedDepsAfterScripts"
1191
1233
  ],
1192
- pathPattern: "^$"
1193
- },
1194
- {
1195
- order: { type: "asc" },
1196
- pathPattern: ".*"
1197
- }
1198
- ] }
1199
- });
1200
- }
1234
+ ...[
1235
+ "catalogMode",
1236
+ "catalogPrune",
1237
+ "cleanupUnusedCatalogs"
1238
+ ],
1239
+ ...[
1240
+ "allowedDeprecatedVersions",
1241
+ "blockExoticSubdeps",
1242
+ "ignoredOptionalDependencies",
1243
+ "minimumReleaseAge",
1244
+ "minimumReleaseAgeExclude",
1245
+ "minimumReleaseAgeExcludePrune",
1246
+ "minimumReleaseAgeIgnoreMissingTime",
1247
+ "minimumReleaseAgeStrict",
1248
+ "registrySupportsTimeField",
1249
+ "resolutionMode",
1250
+ "supportedArchitectures",
1251
+ "trustLockfile",
1252
+ "trustPolicy",
1253
+ "trustPolicyExclude",
1254
+ "trustPolicyIgnoreAfter",
1255
+ "update"
1256
+ ],
1257
+ ...[
1258
+ "autoInstallPeers",
1259
+ "dedupePeerDependents",
1260
+ "dedupePeers",
1261
+ "peerDependencyRules",
1262
+ "resolvePeersFromWorkspaceRoot",
1263
+ "strictPeerDependencies"
1264
+ ],
1265
+ ...[
1266
+ "fetchMinSpeedKiBps",
1267
+ "fetchRetries",
1268
+ "fetchRetryFactor",
1269
+ "fetchRetryMaxtimeout",
1270
+ "fetchRetryMintimeout",
1271
+ "fetchTimeout",
1272
+ "fetchWarnTimeoutMs",
1273
+ "gitShallowHosts",
1274
+ "httpProxy",
1275
+ "httpsProxy",
1276
+ "localAddress",
1277
+ "maxsockets",
1278
+ "namedRegistries",
1279
+ "networkConcurrency",
1280
+ "noProxy",
1281
+ "registries",
1282
+ "registry",
1283
+ "strictSsl"
1284
+ ],
1285
+ ...[
1286
+ "dlxCacheMaxAge",
1287
+ "enableGlobalVirtualStore",
1288
+ "enableModulesDir",
1289
+ "extendNodePath",
1290
+ "modulesCacheMaxAge",
1291
+ "modulesDir",
1292
+ "nodeExperimentalPackageMap",
1293
+ "nodeLinker",
1294
+ "nodePackageMapType",
1295
+ "packageImportMethod",
1296
+ "preferSymlinkedExecutables",
1297
+ "symlink",
1298
+ "virtualStoreDir",
1299
+ "virtualStoreDirMaxLength",
1300
+ "virtualStoreOnly",
1301
+ "virtualStoreType"
1302
+ ],
1303
+ ...[
1304
+ "hoist",
1305
+ "hoistingLimits",
1306
+ "hoistPattern",
1307
+ "hoistWorkspacePackages",
1308
+ "publicHoistPattern",
1309
+ "shamefullyHoist"
1310
+ ],
1311
+ ...[
1312
+ "frozenStore",
1313
+ "storeDir",
1314
+ "strictStorePkgContentCheck",
1315
+ "useRunningStoreServer",
1316
+ "verifyStoreIntegrity"
1317
+ ],
1318
+ ...[
1319
+ "gitBranchLockfile",
1320
+ "lockfile",
1321
+ "lockfileIncludeTarballUrl",
1322
+ "mergeGitBranchLockfilesBranchPattern",
1323
+ "peersSuffixMaxLength",
1324
+ "preferFrozenLockfile"
1325
+ ],
1326
+ ...[
1327
+ "childConcurrency",
1328
+ "dangerouslyAllowAllBuilds",
1329
+ "enablePrePostScripts",
1330
+ "ignoreDepScripts",
1331
+ "ignoreScripts",
1332
+ "nodeOptions",
1333
+ "requiredScripts",
1334
+ "scriptShell",
1335
+ "shellEmulator",
1336
+ "sideEffectsCache",
1337
+ "sideEffectsCacheReadonly",
1338
+ "strictDepBuilds",
1339
+ "unsafePerm",
1340
+ "verifyDepsBeforeRun"
1341
+ ],
1342
+ ...[
1343
+ "managePackageManagerVersions",
1344
+ "nodeDownloadMirrors",
1345
+ "nodeVersion",
1346
+ "packageManagerStrict",
1347
+ "packageManagerStrictVersion",
1348
+ "pmOnFail",
1349
+ "runtimeOnFail"
1350
+ ],
1351
+ ...[
1352
+ "ci",
1353
+ "color",
1354
+ "engineStrict",
1355
+ "loglevel",
1356
+ "npmPath",
1357
+ "recursiveInstall",
1358
+ "updateNotifier",
1359
+ "useBetaCli",
1360
+ "useStderr"
1361
+ ],
1362
+ ...[
1363
+ "cacheDir",
1364
+ "globalBinDir",
1365
+ "globalDir",
1366
+ "globalPnpmfile",
1367
+ "globalShims",
1368
+ "ignorePnpmfile",
1369
+ "npmrcAuthFile",
1370
+ "pnpmfile",
1371
+ "stateDir"
1372
+ ],
1373
+ ...["audit", "versioning"],
1374
+ ...[
1375
+ "allowNonAppliedPatches",
1376
+ "dedupeDirectDeps",
1377
+ "deployAllFiles",
1378
+ "ignoreCompatibilityDb",
1379
+ "initAuthorEmail",
1380
+ "initAuthorName",
1381
+ "initAuthorUrl",
1382
+ "initLicense",
1383
+ "initVersion",
1384
+ "optimisticRepeatInstall",
1385
+ "saveExact",
1386
+ "savePrefix",
1387
+ "tag"
1388
+ ],
1389
+ "packages",
1390
+ "packageConfigs",
1391
+ "overrides",
1392
+ "packageExtensions",
1393
+ "patchedDependencies",
1394
+ "configDependencies",
1395
+ "allowBuilds",
1396
+ ...[
1397
+ "ignoredBuiltDependencies",
1398
+ "neverBuiltDependencies",
1399
+ "onlyBuiltDependencies",
1400
+ "onlyBuiltDependenciesFile"
1401
+ ],
1402
+ "catalog",
1403
+ "catalogs"
1404
+ ],
1405
+ pathPattern: "^$"
1406
+ },
1407
+ {
1408
+ order: { type: "asc" },
1409
+ pathPattern: ".*"
1410
+ }
1411
+ ] }
1412
+ });
1201
1413
  return configs;
1202
1414
  }
1203
1415
  //#endregion
@@ -1226,17 +1438,12 @@ async function react(options = {}) {
1226
1438
  const isUsingRemix = RemixPackages.some((i) => (0, local_pkg.isPackageExists)(i));
1227
1439
  const isUsingReactRouter = ReactRouterPackages.some((i) => (0, local_pkg.isPackageExists)(i));
1228
1440
  const isUsingNext = NextJsPackages.some((i) => (0, local_pkg.isPackageExists)(i));
1229
- const plugins = pluginReact.configs.all.plugins;
1230
1441
  return [
1231
1442
  {
1232
1443
  name: "eslint/react/setup",
1233
1444
  plugins: {
1234
- "react": plugins["@eslint-react"],
1235
- "react-dom": plugins["@eslint-react/dom"],
1236
- "react-naming-convention": plugins["@eslint-react/naming-convention"],
1237
- "react-refresh": pluginReactRefresh,
1238
- "react-rsc": plugins["@eslint-react/rsc"],
1239
- "react-web-api": plugins["@eslint-react/web-api"]
1445
+ "react": pluginReact.configs.all.plugins["@eslint-react"],
1446
+ "react-refresh": pluginReactRefresh
1240
1447
  }
1241
1448
  },
1242
1449
  {
@@ -1248,6 +1455,7 @@ async function react(options = {}) {
1248
1455
  name: "eslint/react/rules",
1249
1456
  rules: {
1250
1457
  ...pluginReact.configs.recommended.rules,
1458
+ /** preconfigured rules from eslint-plugin-react-refresh https://github.com/ArnaudBarre/eslint-plugin-react-refresh/tree/main/src */
1251
1459
  "react-refresh/only-export-components": ["error", {
1252
1460
  allowConstantExport: isAllowConstantExport,
1253
1461
  allowExportNames: [...isUsingNext ? [
@@ -1277,7 +1485,6 @@ async function react(options = {}) {
1277
1485
  "shouldRevalidate"
1278
1486
  ] : []]
1279
1487
  }],
1280
- "react/prefer-namespace-import": "error",
1281
1488
  ...overrides
1282
1489
  }
1283
1490
  },
@@ -1285,8 +1492,9 @@ async function react(options = {}) {
1285
1492
  files: filesTypeAware,
1286
1493
  name: "eslint/react/typescript",
1287
1494
  rules: {
1288
- "react-dom/no-string-style-prop": "off",
1289
- "react-dom/no-unknown-property": "off"
1495
+ /** Disables rules that are already handled by TypeScript */
1496
+ "react/dom-no-string-style-prop": "off",
1497
+ "react/dom-no-unknown-property": "off"
1290
1498
  }
1291
1499
  },
1292
1500
  ...isTypeAware ? [{
@@ -1367,6 +1575,7 @@ async function sortPackageJson() {
1367
1575
  "activationEvents",
1368
1576
  "contributes",
1369
1577
  "scripts",
1578
+ "scripts-info",
1370
1579
  "peerDependencies",
1371
1580
  "peerDependenciesMeta",
1372
1581
  "dependencies",
@@ -1682,6 +1891,7 @@ async function typescript(options = {}) {
1682
1891
  }
1683
1892
  return [
1684
1893
  {
1894
+ /** Install the plugins without globs, so they can be configured separately. */
1685
1895
  name: "eslint/typescript/setup",
1686
1896
  plugins: {
1687
1897
  antfu: eslint_plugin_antfu.default,
@@ -1719,8 +1929,11 @@ async function typescript(options = {}) {
1719
1929
  "ts/no-redeclare": ["error", { builtinGlobals: false }],
1720
1930
  "ts/no-require-imports": "error",
1721
1931
  "ts/no-unused-expressions": ["error", {
1932
+ /** allowShortCircuit 设置为 true 将允许你在表达式中使用短路计算(默认值:false) */
1722
1933
  allowShortCircuit: true,
1934
+ /** allowTaggedTemplates 设置为 true 将使你能够在表达式中使用标记模板字面量(默认值:false) */
1723
1935
  allowTaggedTemplates: true,
1936
+ /** allowTernary 设置为 true 将使你能够在表达式中使用三元运算符,类似于短路计算(默认值:false) */
1724
1937
  allowTernary: true
1725
1938
  }],
1726
1939
  "ts/no-unused-vars": ["warn", {
@@ -1764,6 +1977,7 @@ async function typescript(options = {}) {
1764
1977
  plugins: { "erasable-syntax-only": await interopDefault(import("eslint-plugin-erasable-syntax-only")) },
1765
1978
  rules: {
1766
1979
  "erasable-syntax-only/enums": "error",
1980
+ "erasable-syntax-only/export-aliases": "error",
1767
1981
  "erasable-syntax-only/import-aliases": "error",
1768
1982
  "erasable-syntax-only/namespaces": "error",
1769
1983
  "erasable-syntax-only/parameter-properties": "error"
@@ -1776,8 +1990,11 @@ async function typescript(options = {}) {
1776
1990
  async function unicorn(options = {}) {
1777
1991
  const { allRecommended = false, overrides = {} } = options;
1778
1992
  return [{
1779
- name: "eslint/unicorn/rules",
1780
- plugins: { unicorn: eslint_plugin_unicorn.default },
1993
+ name: "eslint/unicorn/setup",
1994
+ plugins: { unicorn: eslint_plugin_unicorn.default }
1995
+ }, {
1996
+ files: [GLOB_SRC],
1997
+ name: "antfu/unicorn/rules",
1781
1998
  rules: {
1782
1999
  ...allRecommended ? eslint_plugin_unicorn.default.configs.recommended.rules : {
1783
2000
  "unicorn/consistent-empty-array-spread": "error",
@@ -1826,13 +2043,17 @@ vueVersion = Number.isNaN(vueVersion) ? "3" : vueVersion;
1826
2043
  async function vue(options = {}) {
1827
2044
  const { files = [GLOB_VUE], overrides = {}, stylistic = true } = options;
1828
2045
  const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1829
- const { indent = 4 } = typeof stylistic === "boolean" ? {} : stylistic;
2046
+ const { braceStyle = "stroustrup", indent = 4 } = typeof stylistic === "boolean" ? {} : stylistic;
1830
2047
  const [pluginVue, parserVue, processorVueBlocks] = await Promise.all([
1831
2048
  interopDefault(import("eslint-plugin-vue")),
1832
2049
  interopDefault(import("vue-eslint-parser")),
1833
2050
  interopDefault(import("eslint-processor-vue-blocks"))
1834
2051
  ]);
1835
2052
  return [{
2053
+ /**
2054
+ * This allows Vue plugin to work with auto imports
2055
+ * https://github.com/vuejs/eslint-plugin-vue/pull/2422
2056
+ */
1836
2057
  languageOptions: { globals: {
1837
2058
  computed: "readonly",
1838
2059
  defineEmits: "readonly",
@@ -1992,7 +2213,7 @@ async function vue(options = {}) {
1992
2213
  }],
1993
2214
  "vue/brace-style": [
1994
2215
  "error",
1995
- "stroustrup",
2216
+ braceStyle,
1996
2217
  { allowSingleLine: false }
1997
2218
  ],
1998
2219
  "vue/comma-dangle": ["error", "always-multiline"],
@@ -2058,6 +2279,11 @@ async function yaml(options = {}) {
2058
2279
  "yaml/flow-sequence-bracket-spacing": "error",
2059
2280
  "yaml/indent": ["error", typeof other_indent === "number" ? other_indent : 2],
2060
2281
  "yaml/key-spacing": "error",
2282
+ "yaml/no-multiple-empty-lines": ["error", {
2283
+ max: 1,
2284
+ maxBOF: 0,
2285
+ maxEOF: 0
2286
+ }],
2061
2287
  "yaml/no-tab-indent": "error",
2062
2288
  "yaml/quotes": ["error", {
2063
2289
  avoidEscape: true,
@@ -2088,10 +2314,6 @@ const VuePackages = [
2088
2314
  ];
2089
2315
  const defaultPluginRenaming = {
2090
2316
  "@eslint-react": "react",
2091
- "@eslint-react/dom": "react-dom",
2092
- "@eslint-react/naming-convention": "react-naming-convention",
2093
- "@eslint-react/rsc": "react-rsc",
2094
- "@eslint-react/web-api": "react-web-api",
2095
2317
  "@next/next": "next",
2096
2318
  "@stylistic": "style",
2097
2319
  "@typescript-eslint": "ts",
@@ -2111,7 +2333,7 @@ const defaultPluginRenaming = {
2111
2333
  * 合并的 ESLint 配置
2112
2334
  */
2113
2335
  function lincy(options = {}, ...userConfigs) {
2114
- const { autoRenamePlugins = true, componentExts = [], e18e: enableE18e = true, gitignore: enableGitignore = true, ignores: userIgnores = [], imports: enableImports = true, jsx: enableJsx = true, nextjs: enableNextjs = false, overrides = {}, pnpm: enableCatalogs = !!findUpSync("pnpm-workspace.yaml"), react: enableReact = false, regexp: enableRegexp = true, type: appType = "app", typescript: enableTypeScript = (0, local_pkg.isPackageExists)("typescript") || (0, local_pkg.isPackageExists)("@typescript/native-preview"), unicorn: enableUnicorn = true, unocss: enableUnoCSS = false, vue: enableVue = VuePackages.some((i) => (0, local_pkg.isPackageExists)(i)) } = options;
2336
+ const { antislop: enableAntislop = false, autoRenamePlugins = true, componentExts = [], e18e: enableE18e = true, gitignore: enableGitignore = true, ignores: userIgnores = [], imports: enableImports = true, jsx: enableJsx = true, nextjs: enableNextjs = false, overrides = {}, pnpm: enableCatalogs = !!findUpSync("pnpm-workspace.yaml"), react: enableReact = false, regexp: enableRegexp = true, type: appType = "app", typescript: enableTypeScript = (0, local_pkg.isPackageExists)("typescript") || (0, local_pkg.isPackageExists)("@typescript/native-preview"), unicorn: enableUnicorn = true, unocss: enableUnoCSS = false, vue: enableVue = VuePackages.some((i) => (0, local_pkg.isPackageExists)(i)) } = options;
2115
2337
  let isInEditor = options.isInEditor;
2116
2338
  if (isInEditor == null) {
2117
2339
  isInEditor = isInEditorEnv();
@@ -2120,14 +2342,16 @@ function lincy(options = {}, ...userConfigs) {
2120
2342
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2121
2343
  if (stylisticOptions && !("jsx" in stylisticOptions)) stylisticOptions.jsx = enableJsx;
2122
2344
  const configs = [];
2123
- if (enableGitignore) if (typeof enableGitignore !== "boolean") configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2124
- name: "eslint/gitignore",
2125
- ...enableGitignore
2126
- })]));
2127
- else configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2128
- name: "eslint/gitignore",
2129
- strict: false
2130
- })]));
2345
+ if (enableGitignore) {
2346
+ if (typeof enableGitignore !== "boolean") configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2347
+ name: "eslint/gitignore",
2348
+ ...enableGitignore
2349
+ })]));
2350
+ else configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2351
+ name: "eslint/gitignore",
2352
+ strict: false
2353
+ })]));
2354
+ }
2131
2355
  const typescriptOptions = resolveSubOptions(options, "typescript");
2132
2356
  const tsconfigPath = "tsconfigPath" in typescriptOptions ? typescriptOptions.tsconfigPath : void 0;
2133
2357
  configs.push(ignores([...overrides.ignores || [], ...userIgnores], !enableTypeScript), javascript({
@@ -2158,6 +2382,11 @@ function lincy(options = {}, ...userConfigs) {
2158
2382
  tsconfigPath,
2159
2383
  type: appType
2160
2384
  }));
2385
+ if (enableAntislop) configs.push(antislop({
2386
+ ...resolveSubOptions(options, "antislop"),
2387
+ overrides: getOverrides(options, "antislop"),
2388
+ typescript: !!enableTypeScript
2389
+ }));
2161
2390
  if (stylisticOptions) configs.push(stylistic({
2162
2391
  overrides: getOverrides(options, "stylistic"),
2163
2392
  stylistic: stylisticOptions
@@ -2195,6 +2424,9 @@ function lincy(options = {}, ...userConfigs) {
2195
2424
  }), sortPackageJson(), sortTsconfig());
2196
2425
  if (enableCatalogs) configs.push(pnpm({
2197
2426
  isInEditor,
2427
+ json: options.jsonc !== false,
2428
+ stylistic: stylisticOptions,
2429
+ yaml: options.yaml !== false,
2198
2430
  ...resolveSubOptions(options, "pnpm")
2199
2431
  }));
2200
2432
  if (options.yaml ?? true) configs.push(yaml({
@@ -2271,6 +2503,7 @@ exports.GLOB_VUE = GLOB_VUE;
2271
2503
  exports.GLOB_XML = GLOB_XML;
2272
2504
  exports.GLOB_YAML = GLOB_YAML;
2273
2505
  exports.StylisticConfigDefaults = StylisticConfigDefaults;
2506
+ exports.antislop = antislop;
2274
2507
  exports.combine = combine;
2275
2508
  exports.comments = comments;
2276
2509
  exports.default = src_default;