@lincy/eslint-config 6.2.0 → 6.3.3

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
@@ -29,6 +29,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  let eslint_flat_config_utils = require("eslint-flat-config-utils");
30
30
  let node_process = require("node:process");
31
31
  node_process = __toESM(node_process);
32
+ let node_fs_promises = require("node:fs/promises");
33
+ node_fs_promises = __toESM(node_fs_promises);
32
34
  let node_url = require("node:url");
33
35
  let node_fs = require("node:fs");
34
36
  node_fs = __toESM(node_fs);
@@ -58,6 +60,21 @@ let eslint_plugin_regexp = require("eslint-plugin-regexp");
58
60
 
59
61
  //#region node_modules/.pnpm/find-up-simple@1.0.1/node_modules/find-up-simple/index.js
60
62
  const toPath = (urlOrPath) => urlOrPath instanceof URL ? (0, node_url.fileURLToPath)(urlOrPath) : urlOrPath;
63
+ async function findUp(name, { cwd = node_process.default.cwd(), type = "file", stopAt } = {}) {
64
+ let directory = node_path.default.resolve(toPath(cwd) ?? "");
65
+ const { root } = node_path.default.parse(directory);
66
+ stopAt = node_path.default.resolve(directory, toPath(stopAt ?? root));
67
+ const isAbsoluteName = node_path.default.isAbsolute(name);
68
+ while (directory) {
69
+ const filePath = isAbsoluteName ? name : node_path.default.join(directory, name);
70
+ try {
71
+ const stats = await node_fs_promises.default.stat(filePath);
72
+ if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) return filePath;
73
+ } catch {}
74
+ if (directory === stopAt || directory === root) break;
75
+ directory = node_path.default.dirname(directory);
76
+ }
77
+ }
61
78
  function findUpSync(name, { cwd = node_process.default.cwd(), type = "file", stopAt } = {}) {
62
79
  let directory = node_path.default.resolve(toPath(cwd) ?? "");
63
80
  const { root } = node_path.default.parse(directory);
@@ -1028,7 +1045,14 @@ async function perfectionist(options = {}) {
1028
1045
 
1029
1046
  //#endregion
1030
1047
  //#region src/configs/pnpm.ts
1048
+ async function detectCatalogUsage() {
1049
+ const workspaceFile = await findUp("pnpm-workspace.yaml");
1050
+ if (!workspaceFile) return false;
1051
+ const yaml$1 = await node_fs_promises.default.readFile(workspaceFile, "utf-8");
1052
+ return yaml$1.includes("catalog:") || yaml$1.includes("catalogs:");
1053
+ }
1031
1054
  async function pnpm(options = {}) {
1055
+ const { catalogs = await detectCatalogUsage(), isInEditor = false } = options;
1032
1056
  const [pluginPnpm, yamlParser, jsoncParser] = await Promise.all([
1033
1057
  interopDefault(import("eslint-plugin-pnpm")),
1034
1058
  interopDefault(import("yaml-eslint-parser")),
@@ -1041,9 +1065,12 @@ async function pnpm(options = {}) {
1041
1065
  name: "eslint/pnpm/package-json",
1042
1066
  plugins: { pnpm: pluginPnpm },
1043
1067
  rules: {
1044
- "pnpm/json-enforce-catalog": ["error", { autofix: !options.isInEditor }],
1045
- "pnpm/json-prefer-workspace-settings": ["error", { autofix: !options.isInEditor }],
1046
- "pnpm/json-valid-catalog": ["error", { autofix: !options.isInEditor }]
1068
+ ...catalogs ? { "pnpm/json-enforce-catalog": ["error", {
1069
+ autofix: !isInEditor,
1070
+ ignores: ["@types/vscode"]
1071
+ }] } : {},
1072
+ "pnpm/json-prefer-workspace-settings": ["error", { autofix: isInEditor }],
1073
+ "pnpm/json-valid-catalog": ["error", { autofix: isInEditor }]
1047
1074
  }
1048
1075
  },
1049
1076
  {
@@ -1201,20 +1228,19 @@ async function react(options = {}) {
1201
1228
  "react-dom/no-find-dom-node": "error",
1202
1229
  "react-dom/no-flush-sync": "error",
1203
1230
  "react-dom/no-hydrate": "error",
1204
- "react-dom/no-missing-button-type": "warn",
1205
- "react-dom/no-missing-iframe-sandbox": "warn",
1206
1231
  "react-dom/no-namespace": "error",
1207
1232
  "react-dom/no-render": "error",
1208
1233
  "react-dom/no-render-return-value": "error",
1209
1234
  "react-dom/no-script-url": "warn",
1210
1235
  "react-dom/no-unsafe-iframe-sandbox": "warn",
1211
- "react-dom/no-unsafe-target-blank": "warn",
1212
1236
  "react-dom/no-use-form-state": "error",
1213
1237
  "react-dom/no-void-elements-with-children": "error",
1214
1238
  "react-hooks/exhaustive-deps": "warn",
1215
1239
  "react-hooks/rules-of-hooks": "error",
1240
+ "react/jsx-key-before-spread": "warn",
1216
1241
  "react/jsx-no-comment-textnodes": "warn",
1217
1242
  "react/jsx-no-duplicate-props": "warn",
1243
+ "react/jsx-uses-react": "warn",
1218
1244
  "react/jsx-uses-vars": "warn",
1219
1245
  "react/no-access-state-in-setstate": "error",
1220
1246
  "react/no-array-index-key": "warn",
@@ -1231,11 +1257,12 @@ async function react(options = {}) {
1231
1257
  "react/no-create-ref": "error",
1232
1258
  "react/no-default-props": "error",
1233
1259
  "react/no-direct-mutation-state": "error",
1234
- "react/no-duplicate-key": "warn",
1260
+ "react/no-duplicate-key": "error",
1235
1261
  "react/no-forward-ref": "warn",
1236
1262
  "react/no-implicit-key": "warn",
1237
1263
  "react/no-missing-key": "error",
1238
1264
  "react/no-nested-component-definitions": "error",
1265
+ "react/no-nested-lazy-component-declarations": "error",
1239
1266
  "react/no-prop-types": "error",
1240
1267
  "react/no-redundant-should-component-update": "error",
1241
1268
  "react/no-set-state-in-component-did-mount": "warn",
@@ -1246,10 +1273,6 @@ async function react(options = {}) {
1246
1273
  "react/no-unsafe-component-will-mount": "warn",
1247
1274
  "react/no-unsafe-component-will-receive-props": "warn",
1248
1275
  "react/no-unsafe-component-will-update": "warn",
1249
- "react/no-unstable-context-value": "warn",
1250
- "react/no-unstable-default-props": "warn",
1251
- "react/no-unused-class-component-members": "warn",
1252
- "react/no-unused-state": "warn",
1253
1276
  "react/no-use-context": "warn",
1254
1277
  "react/no-useless-forward-ref": "warn",
1255
1278
  "react/prefer-use-state-lazy-initialization": "warn",
package/dist/index.d.cts CHANGED
@@ -387,6 +387,11 @@ interface RuleOptions {
387
387
  * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/consistent-type-specifier-style/README.md
388
388
  */
389
389
  'import/consistent-type-specifier-style'?: Linter.RuleEntry<ImportConsistentTypeSpecifierStyle>;
390
+ /**
391
+ * Ensure all exports appear after other statements.
392
+ * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/exports-last/README.md
393
+ */
394
+ 'import/exports-last'?: Linter.RuleEntry<[]>;
390
395
  /**
391
396
  * Ensure all imports appear before other statements.
392
397
  * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/first/README.md
@@ -4280,6 +4285,11 @@ interface RuleOptions {
4280
4285
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md
4281
4286
  */
4282
4287
  'test/no-test-return-statement'?: Linter.RuleEntry<[]>;
4288
+ /**
4289
+ * Disallow unnecessary async function wrapper for expected promises
4290
+ * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-unneeded-async-expect-function.md
4291
+ */
4292
+ 'test/no-unneeded-async-expect-function'?: Linter.RuleEntry<[]>;
4283
4293
  /**
4284
4294
  * Enforce padding around `afterAll` blocks
4285
4295
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-all-blocks.md
@@ -5099,6 +5109,11 @@ interface RuleOptions {
5099
5109
  * @see https://typescript-eslint.io/rules/no-useless-constructor
5100
5110
  */
5101
5111
  'ts/no-useless-constructor'?: Linter.RuleEntry<[]>;
5112
+ /**
5113
+ * Disallow default values that will never be used
5114
+ * @see https://typescript-eslint.io/rules/no-useless-default-assignment
5115
+ */
5116
+ 'ts/no-useless-default-assignment'?: Linter.RuleEntry<[]>;
5102
5117
  /**
5103
5118
  * Disallow empty exports that don't change anything in a module file
5104
5119
  * @see https://typescript-eslint.io/rules/no-useless-empty-export
@@ -16577,6 +16592,12 @@ interface OptionsIgnores {
16577
16592
  interface OptionsIsInEditor {
16578
16593
  isInEditor?: boolean;
16579
16594
  }
16595
+ interface OptionsPnpm extends OptionsIsInEditor {
16596
+ /**
16597
+ * 需要使用目录支持?
16598
+ */
16599
+ catalogs?: boolean;
16600
+ }
16580
16601
  interface OptionsUnoCSS {
16581
16602
  /**
16582
16603
  * 启用 attributify 支持.
@@ -16856,7 +16877,7 @@ declare function node(options?: OptionsOverrides): Promise<TypedFlatConfigItem[]
16856
16877
  declare function perfectionist(options?: OptionsOverrides): Promise<TypedFlatConfigItem[]>;
16857
16878
  //#endregion
16858
16879
  //#region src/configs/pnpm.d.ts
16859
- declare function pnpm(options?: OptionsIsInEditor): Promise<TypedFlatConfigItem[]>;
16880
+ declare function pnpm(options?: OptionsPnpm): Promise<TypedFlatConfigItem[]>;
16860
16881
  //#endregion
16861
16882
  //#region src/configs/react.d.ts
16862
16883
  declare function react(options?: OptionsTypeScriptParserOptions & OptionsTypeScriptWithTypes & OptionsOverrides & OptionsReact): Promise<TypedFlatConfigItem[]>;
@@ -16976,4 +16997,4 @@ declare function ensurePackages(packages: (string | undefined)[]): Promise<void>
16976
16997
  declare function isInEditorEnv(): boolean;
16977
16998
  declare function isInGitHooksOrLintStaged(): boolean;
16978
16999
  //#endregion
16979
- export { Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVELTE, GLOB_SVG, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsProjectType, OptionsReact, OptionsRegExp, OptionsStylistic, OptionsTypeScriptErasableOnly, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, OptionsUnicorn, OptionsUnoCSS, OptionsVue, ResolvedOptions, Rules, StylisticConfig, StylisticConfigDefaults, TypedFlatConfigItem, combine, comments, lincy as default, lincy, defaultPluginRenaming, disables, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, jsx, markdown, nextjs, node, parserPlain, perfectionist, pnpm, react, regexp, renamePluginInConfigs, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, test, toArray, toml, typescript, unicorn, unocss, vue, yaml };
17000
+ export { Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVELTE, GLOB_SVG, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsPnpm, OptionsProjectType, OptionsReact, OptionsRegExp, OptionsStylistic, OptionsTypeScriptErasableOnly, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, OptionsUnicorn, OptionsUnoCSS, OptionsVue, ResolvedOptions, Rules, StylisticConfig, StylisticConfigDefaults, TypedFlatConfigItem, combine, comments, lincy as default, lincy, defaultPluginRenaming, disables, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, jsx, markdown, nextjs, node, parserPlain, perfectionist, pnpm, react, regexp, renamePluginInConfigs, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, test, toArray, toml, typescript, unicorn, unocss, vue, yaml };
package/dist/index.d.mts CHANGED
@@ -387,6 +387,11 @@ interface RuleOptions {
387
387
  * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/consistent-type-specifier-style/README.md
388
388
  */
389
389
  'import/consistent-type-specifier-style'?: Linter.RuleEntry<ImportConsistentTypeSpecifierStyle>;
390
+ /**
391
+ * Ensure all exports appear after other statements.
392
+ * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/exports-last/README.md
393
+ */
394
+ 'import/exports-last'?: Linter.RuleEntry<[]>;
390
395
  /**
391
396
  * Ensure all imports appear before other statements.
392
397
  * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/first/README.md
@@ -4280,6 +4285,11 @@ interface RuleOptions {
4280
4285
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md
4281
4286
  */
4282
4287
  'test/no-test-return-statement'?: Linter.RuleEntry<[]>;
4288
+ /**
4289
+ * Disallow unnecessary async function wrapper for expected promises
4290
+ * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-unneeded-async-expect-function.md
4291
+ */
4292
+ 'test/no-unneeded-async-expect-function'?: Linter.RuleEntry<[]>;
4283
4293
  /**
4284
4294
  * Enforce padding around `afterAll` blocks
4285
4295
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-all-blocks.md
@@ -5099,6 +5109,11 @@ interface RuleOptions {
5099
5109
  * @see https://typescript-eslint.io/rules/no-useless-constructor
5100
5110
  */
5101
5111
  'ts/no-useless-constructor'?: Linter.RuleEntry<[]>;
5112
+ /**
5113
+ * Disallow default values that will never be used
5114
+ * @see https://typescript-eslint.io/rules/no-useless-default-assignment
5115
+ */
5116
+ 'ts/no-useless-default-assignment'?: Linter.RuleEntry<[]>;
5102
5117
  /**
5103
5118
  * Disallow empty exports that don't change anything in a module file
5104
5119
  * @see https://typescript-eslint.io/rules/no-useless-empty-export
@@ -16577,6 +16592,12 @@ interface OptionsIgnores {
16577
16592
  interface OptionsIsInEditor {
16578
16593
  isInEditor?: boolean;
16579
16594
  }
16595
+ interface OptionsPnpm extends OptionsIsInEditor {
16596
+ /**
16597
+ * 需要使用目录支持?
16598
+ */
16599
+ catalogs?: boolean;
16600
+ }
16580
16601
  interface OptionsUnoCSS {
16581
16602
  /**
16582
16603
  * 启用 attributify 支持.
@@ -16856,7 +16877,7 @@ declare function node(options?: OptionsOverrides): Promise<TypedFlatConfigItem[]
16856
16877
  declare function perfectionist(options?: OptionsOverrides): Promise<TypedFlatConfigItem[]>;
16857
16878
  //#endregion
16858
16879
  //#region src/configs/pnpm.d.ts
16859
- declare function pnpm(options?: OptionsIsInEditor): Promise<TypedFlatConfigItem[]>;
16880
+ declare function pnpm(options?: OptionsPnpm): Promise<TypedFlatConfigItem[]>;
16860
16881
  //#endregion
16861
16882
  //#region src/configs/react.d.ts
16862
16883
  declare function react(options?: OptionsTypeScriptParserOptions & OptionsTypeScriptWithTypes & OptionsOverrides & OptionsReact): Promise<TypedFlatConfigItem[]>;
@@ -16976,4 +16997,4 @@ declare function ensurePackages(packages: (string | undefined)[]): Promise<void>
16976
16997
  declare function isInEditorEnv(): boolean;
16977
16998
  declare function isInGitHooksOrLintStaged(): boolean;
16978
16999
  //#endregion
16979
- export { Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVELTE, GLOB_SVG, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsProjectType, OptionsReact, OptionsRegExp, OptionsStylistic, OptionsTypeScriptErasableOnly, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, OptionsUnicorn, OptionsUnoCSS, OptionsVue, ResolvedOptions, Rules, StylisticConfig, StylisticConfigDefaults, TypedFlatConfigItem, combine, comments, lincy as default, lincy, defaultPluginRenaming, disables, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, jsx, markdown, nextjs, node, parserPlain, perfectionist, pnpm, react, regexp, renamePluginInConfigs, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, test, toArray, toml, typescript, unicorn, unocss, vue, yaml };
17000
+ export { Awaitable, type ConfigNames, GLOB_ALL_SRC, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLE, GLOB_SVELTE, GLOB_SVG, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, OptionsComponentExts, OptionsConfig, OptionsFiles, OptionsFormatters, OptionsHasTypeScript, OptionsIgnores, OptionsIsInEditor, OptionsOverrides, OptionsPnpm, OptionsProjectType, OptionsReact, OptionsRegExp, OptionsStylistic, OptionsTypeScriptErasableOnly, OptionsTypeScriptParserOptions, OptionsTypeScriptWithTypes, OptionsTypescript, OptionsUnicorn, OptionsUnoCSS, OptionsVue, ResolvedOptions, Rules, StylisticConfig, StylisticConfigDefaults, TypedFlatConfigItem, combine, comments, lincy as default, lincy, defaultPluginRenaming, disables, ensurePackages, formatters, getOverrides, ignores, imports, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, jsx, markdown, nextjs, node, parserPlain, perfectionist, pnpm, react, regexp, renamePluginInConfigs, renameRules, resolveSubOptions, sortPackageJson, sortTsconfig, stylistic, test, toArray, toml, typescript, unicorn, unocss, vue, yaml };
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import { FlatConfigComposer } from "eslint-flat-config-utils";
2
2
  import process from "node:process";
3
+ import fs from "node:fs/promises";
3
4
  import { fileURLToPath } from "node:url";
4
- import fs from "node:fs";
5
+ import fs$1 from "node:fs";
5
6
  import path from "node:path";
6
7
  import { getPackageInfoSync, isPackageExists } from "local-pkg";
7
8
  import pluginComments from "@eslint-community/eslint-plugin-eslint-comments";
@@ -18,6 +19,21 @@ import { configs } from "eslint-plugin-regexp";
18
19
 
19
20
  //#region node_modules/.pnpm/find-up-simple@1.0.1/node_modules/find-up-simple/index.js
20
21
  const toPath = (urlOrPath) => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
22
+ async function findUp(name, { cwd = process.cwd(), type = "file", stopAt } = {}) {
23
+ let directory = path.resolve(toPath(cwd) ?? "");
24
+ const { root } = path.parse(directory);
25
+ stopAt = path.resolve(directory, toPath(stopAt ?? root));
26
+ const isAbsoluteName = path.isAbsolute(name);
27
+ while (directory) {
28
+ const filePath = isAbsoluteName ? name : path.join(directory, name);
29
+ try {
30
+ const stats = await fs.stat(filePath);
31
+ if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) return filePath;
32
+ } catch {}
33
+ if (directory === stopAt || directory === root) break;
34
+ directory = path.dirname(directory);
35
+ }
36
+ }
21
37
  function findUpSync(name, { cwd = process.cwd(), type = "file", stopAt } = {}) {
22
38
  let directory = path.resolve(toPath(cwd) ?? "");
23
39
  const { root } = path.parse(directory);
@@ -26,7 +42,7 @@ function findUpSync(name, { cwd = process.cwd(), type = "file", stopAt } = {}) {
26
42
  while (directory) {
27
43
  const filePath = isAbsoluteName ? name : path.join(directory, name);
28
44
  try {
29
- const stats = fs.statSync(filePath, { throwIfNoEntry: false });
45
+ const stats = fs$1.statSync(filePath, { throwIfNoEntry: false });
30
46
  if (type === "file" && stats?.isFile() || type === "directory" && stats?.isDirectory()) return filePath;
31
47
  } catch {}
32
48
  if (directory === stopAt || directory === root) break;
@@ -988,7 +1004,14 @@ async function perfectionist(options = {}) {
988
1004
 
989
1005
  //#endregion
990
1006
  //#region src/configs/pnpm.ts
1007
+ async function detectCatalogUsage() {
1008
+ const workspaceFile = await findUp("pnpm-workspace.yaml");
1009
+ if (!workspaceFile) return false;
1010
+ const yaml$1 = await fs.readFile(workspaceFile, "utf-8");
1011
+ return yaml$1.includes("catalog:") || yaml$1.includes("catalogs:");
1012
+ }
991
1013
  async function pnpm(options = {}) {
1014
+ const { catalogs = await detectCatalogUsage(), isInEditor = false } = options;
992
1015
  const [pluginPnpm, yamlParser, jsoncParser] = await Promise.all([
993
1016
  interopDefault(import("eslint-plugin-pnpm")),
994
1017
  interopDefault(import("yaml-eslint-parser")),
@@ -1001,9 +1024,12 @@ async function pnpm(options = {}) {
1001
1024
  name: "eslint/pnpm/package-json",
1002
1025
  plugins: { pnpm: pluginPnpm },
1003
1026
  rules: {
1004
- "pnpm/json-enforce-catalog": ["error", { autofix: !options.isInEditor }],
1005
- "pnpm/json-prefer-workspace-settings": ["error", { autofix: !options.isInEditor }],
1006
- "pnpm/json-valid-catalog": ["error", { autofix: !options.isInEditor }]
1027
+ ...catalogs ? { "pnpm/json-enforce-catalog": ["error", {
1028
+ autofix: !isInEditor,
1029
+ ignores: ["@types/vscode"]
1030
+ }] } : {},
1031
+ "pnpm/json-prefer-workspace-settings": ["error", { autofix: isInEditor }],
1032
+ "pnpm/json-valid-catalog": ["error", { autofix: isInEditor }]
1007
1033
  }
1008
1034
  },
1009
1035
  {
@@ -1161,20 +1187,19 @@ async function react(options = {}) {
1161
1187
  "react-dom/no-find-dom-node": "error",
1162
1188
  "react-dom/no-flush-sync": "error",
1163
1189
  "react-dom/no-hydrate": "error",
1164
- "react-dom/no-missing-button-type": "warn",
1165
- "react-dom/no-missing-iframe-sandbox": "warn",
1166
1190
  "react-dom/no-namespace": "error",
1167
1191
  "react-dom/no-render": "error",
1168
1192
  "react-dom/no-render-return-value": "error",
1169
1193
  "react-dom/no-script-url": "warn",
1170
1194
  "react-dom/no-unsafe-iframe-sandbox": "warn",
1171
- "react-dom/no-unsafe-target-blank": "warn",
1172
1195
  "react-dom/no-use-form-state": "error",
1173
1196
  "react-dom/no-void-elements-with-children": "error",
1174
1197
  "react-hooks/exhaustive-deps": "warn",
1175
1198
  "react-hooks/rules-of-hooks": "error",
1199
+ "react/jsx-key-before-spread": "warn",
1176
1200
  "react/jsx-no-comment-textnodes": "warn",
1177
1201
  "react/jsx-no-duplicate-props": "warn",
1202
+ "react/jsx-uses-react": "warn",
1178
1203
  "react/jsx-uses-vars": "warn",
1179
1204
  "react/no-access-state-in-setstate": "error",
1180
1205
  "react/no-array-index-key": "warn",
@@ -1191,11 +1216,12 @@ async function react(options = {}) {
1191
1216
  "react/no-create-ref": "error",
1192
1217
  "react/no-default-props": "error",
1193
1218
  "react/no-direct-mutation-state": "error",
1194
- "react/no-duplicate-key": "warn",
1219
+ "react/no-duplicate-key": "error",
1195
1220
  "react/no-forward-ref": "warn",
1196
1221
  "react/no-implicit-key": "warn",
1197
1222
  "react/no-missing-key": "error",
1198
1223
  "react/no-nested-component-definitions": "error",
1224
+ "react/no-nested-lazy-component-declarations": "error",
1199
1225
  "react/no-prop-types": "error",
1200
1226
  "react/no-redundant-should-component-update": "error",
1201
1227
  "react/no-set-state-in-component-did-mount": "warn",
@@ -1206,10 +1232,6 @@ async function react(options = {}) {
1206
1232
  "react/no-unsafe-component-will-mount": "warn",
1207
1233
  "react/no-unsafe-component-will-receive-props": "warn",
1208
1234
  "react/no-unsafe-component-will-update": "warn",
1209
- "react/no-unstable-context-value": "warn",
1210
- "react/no-unstable-default-props": "warn",
1211
- "react/no-unused-class-component-members": "warn",
1212
- "react/no-unused-state": "warn",
1213
1235
  "react/no-use-context": "warn",
1214
1236
  "react/no-useless-forward-ref": "warn",
1215
1237
  "react/prefer-use-state-lazy-initialization": "warn",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lincy/eslint-config",
3
3
  "type": "module",
4
- "version": "6.2.0",
4
+ "version": "6.3.3",
5
5
  "description": "LinCenYing's ESLint config",
6
6
  "author": "LinCenYing <lincenying@gmail.com> (https://github.com/lincenying/)",
7
7
  "license": "MIT",
@@ -61,28 +61,28 @@
61
61
  "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
62
62
  "@eslint/markdown": "^7.5.1",
63
63
  "@stylistic/eslint-plugin": "^5.6.1",
64
- "@typescript-eslint/eslint-plugin": "^8.49.0",
65
- "@typescript-eslint/parser": "^8.49.0",
66
- "@vitest/eslint-plugin": "^1.5.2",
64
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
65
+ "@typescript-eslint/parser": "^8.50.0",
66
+ "@vitest/eslint-plugin": "^1.5.4",
67
67
  "eslint-config-flat-gitignore": "^2.1.0",
68
68
  "eslint-flat-config-utils": "^2.1.4",
69
69
  "eslint-merge-processors": "^2.0.0",
70
70
  "eslint-parser-plain": "^0.1.1",
71
71
  "eslint-plugin-antfu": "^3.1.1",
72
72
  "eslint-plugin-erasable-syntax-only": "^0.4.0",
73
- "eslint-plugin-import-lite": "^0.3.0",
73
+ "eslint-plugin-import-lite": "^0.3.1",
74
74
  "eslint-plugin-jsdoc": "^61.5.0",
75
75
  "eslint-plugin-jsonc": "^2.21.0",
76
76
  "eslint-plugin-n": "^17.23.1",
77
77
  "eslint-plugin-no-only-tests": "^3.3.0",
78
78
  "eslint-plugin-perfectionist": "^4.15.1",
79
- "eslint-plugin-pnpm": "^1.4.2",
79
+ "eslint-plugin-pnpm": "^1.4.3",
80
80
  "eslint-plugin-regexp": "^2.10.0",
81
81
  "eslint-plugin-toml": "^0.12.0",
82
82
  "eslint-plugin-unicorn": "^62.0.0",
83
83
  "eslint-plugin-unused-imports": "^4.3.0",
84
84
  "eslint-plugin-vue": "^10.6.2",
85
- "eslint-plugin-yml": "^1.19.0",
85
+ "eslint-plugin-yml": "^1.19.1",
86
86
  "eslint-processor-vue-blocks": "^2.0.0",
87
87
  "globals": "^16.5.0",
88
88
  "jsonc-eslint-parser": "^2.4.2",
@@ -93,33 +93,33 @@
93
93
  },
94
94
  "devDependencies": {
95
95
  "@antfu/ni": "^28.0.0",
96
- "@eslint-react/eslint-plugin": "^2.3.12",
96
+ "@eslint-react/eslint-plugin": "^2.3.13",
97
97
  "@eslint/config-inspector": "^1.4.2",
98
- "@next/eslint-plugin-next": "^16.0.8",
98
+ "@next/eslint-plugin-next": "^16.1.0",
99
99
  "@prettier/plugin-xml": "^3.4.2",
100
100
  "@stylistic/eslint-plugin-migrate": "^4.4.1",
101
- "@types/node": "^24.10.2",
101
+ "@types/node": "^24.10.4",
102
102
  "@types/react": "^19.2.7",
103
103
  "@unocss/eslint-plugin": "^66.5.10",
104
104
  "bumpp": "^10.3.2",
105
- "eslint": "^9.39.1",
105
+ "eslint": "^9.39.2",
106
106
  "eslint-plugin-format": "^1.1.0",
107
107
  "eslint-plugin-react-hooks": "^7.0.1",
108
- "eslint-plugin-react-refresh": "^0.4.24",
108
+ "eslint-plugin-react-refresh": "^0.4.26",
109
109
  "eslint-typegen": "^2.3.0",
110
110
  "esno": "^4.8.0",
111
111
  "execa": "^9.6.1",
112
112
  "find-up-simple": "^1.0.1",
113
113
  "lint-staged": "^16.2.7",
114
114
  "prettier": "^3.7.4",
115
- "react": "^19.2.1",
115
+ "react": "^19.2.3",
116
116
  "simple-open-url": "^3.0.1",
117
117
  "tinyglobby": "^0.2.15",
118
- "tsdown": "^0.17.2",
118
+ "tsdown": "^0.17.4",
119
119
  "typescript": "^5.9.3",
120
- "vitest": "^4.0.15",
121
- "vue": "^3.5.25",
122
- "@lincy/eslint-config": "6.2.0"
120
+ "vitest": "^4.0.16",
121
+ "vue": "^3.5.26",
122
+ "@lincy/eslint-config": "6.3.3"
123
123
  },
124
124
  "resolutions": {
125
125
  "@eslint-community/eslint-utils": "catalog:peer",