@coderwyd/eslint-config 4.7.0 → 4.7.2

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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import process from "node:process";
2
- import c from "picocolors";
2
+ import { styleText } from "node:util";
3
3
  import yargs from "yargs";
4
4
  import { hideBin } from "yargs/helpers";
5
5
  import fs from "node:fs";
@@ -10,41 +10,41 @@ import prompts from "prompts";
10
10
  import { execSync } from "node:child_process";
11
11
 
12
12
  //#region package.json
13
- var version = "4.7.0";
13
+ var version = "4.7.2";
14
14
  var devDependencies = {
15
15
  "@antfu/ni": "^26.1.0",
16
- "@eslint-react/eslint-plugin": "^2.0.3",
16
+ "@eslint-react/eslint-plugin": "^2.2.2",
17
17
  "@eslint/config-inspector": "^1.3.0",
18
18
  "@types/eslint-config-prettier": "^6.11.3",
19
- "@types/node": "^24.6.0",
19
+ "@types/node": "^24.7.2",
20
20
  "@types/prompts": "^2.4.9",
21
21
  "@types/yargs": "^17.0.33",
22
- "@unocss/eslint-plugin": "^66.5.2",
23
- "bumpp": "^10.2.3",
24
- "eslint": "^9.36.0",
25
- "eslint-plugin-react-hooks": "6.0.0-rc1",
26
- "eslint-plugin-react-refresh": "^0.4.22",
22
+ "@unocss/eslint-plugin": "^66.5.3",
23
+ "bumpp": "^10.3.1",
24
+ "eslint": "^9.37.0",
25
+ "eslint-plugin-react-hooks": "7.0.0",
26
+ "eslint-plugin-react-refresh": "^0.4.23",
27
27
  "eslint-plugin-svelte": "^3.12.4",
28
28
  "eslint-plugin-tailwindcss": "^3.18.2",
29
29
  "eslint-typegen": "^2.3.0",
30
- "jiti": "^2.6.0",
30
+ "jiti": "^2.6.1",
31
31
  "nano-staged": "^0.8.0",
32
32
  "prettier": "^3.6.2",
33
- "publint": "^0.3.13",
33
+ "publint": "^0.3.14",
34
34
  "simple-git-hooks": "^2.13.1",
35
- "svelte": "^5.39.6",
35
+ "svelte": "^5.40.0",
36
36
  "svelte-eslint-parser": "^1.3.3",
37
- "tsdown": "^0.15.5",
38
- "typescript": "^5.9.2",
39
- "unplugin-unused": "^0.5.3"
37
+ "tsdown": "^0.15.7",
38
+ "typescript": "^5.9.3",
39
+ "unplugin-unused": "^0.5.4"
40
40
  };
41
41
 
42
42
  //#endregion
43
43
  //#region src/cli/constants.ts
44
- const ARROW = c.cyan("→");
45
- const CHECK = c.green("✔");
46
- const CROSS = c.red("✘");
47
- const WARN = c.yellow("ℹ");
44
+ const ARROW = styleText("cyan", "→");
45
+ const CHECK = styleText("green", "✔");
46
+ const CROSS = styleText("red", "✘");
47
+ const WARN = styleText("yellow", "ℹ");
48
48
  const eslintVersion = devDependencies.eslint;
49
49
  const vscodeSettingsString = `
50
50
  "editor.formatOnSave": true,
@@ -77,7 +77,7 @@ async function run(options = {}) {
77
77
  const pathPackageJSON = path.join(cwd, "package.json");
78
78
  const pathESLintIngore = path.join(cwd, ".eslintignore");
79
79
  if (fs.existsSync(pathFlatConfig)) {
80
- console.log(c.yellow(`${WARN} eslint.config.js already exists, migration wizard exited.`));
80
+ console.log(styleText("yellow", `${WARN} eslint.config.js already exists, migration wizard exited.`));
81
81
  return process.exit(1);
82
82
  }
83
83
  if (!SKIP_GIT_CHECK && !isGitClean()) {
@@ -89,19 +89,18 @@ async function run(options = {}) {
89
89
  });
90
90
  if (!confirmed) return process.exit(1);
91
91
  }
92
- console.log(c.cyan(`${ARROW} bumping @coderwyd/eslint-config to v${version}`));
92
+ console.log(styleText("cyan", `${ARROW} bumping @coderwyd/eslint-config to v${version}`));
93
93
  const pkgContent = await fsp.readFile(pathPackageJSON, "utf-8");
94
94
  const pkg = JSON.parse(pkgContent);
95
95
  pkg.devDependencies ??= {};
96
96
  pkg.devDependencies["@coderwyd/eslint-config"] = `^${version}`;
97
97
  if (!pkg.devDependencies.eslint) pkg.devDependencies.eslint = eslintVersion;
98
98
  await fsp.writeFile(pathPackageJSON, JSON.stringify(pkg, null, 2));
99
- console.log(c.green(`${CHECK} changes wrote to package.json`));
99
+ console.log(styleText("green", `${CHECK} changes wrote to package.json`));
100
100
  const eslintIgnores = [];
101
101
  if (fs.existsSync(pathESLintIngore)) {
102
- console.log(c.cyan(`${ARROW} migrating existing .eslintignore`));
103
- const content = await fsp.readFile(pathESLintIngore, "utf-8");
104
- const globs = parse(content).globs();
102
+ console.log(styleText("cyan", `${ARROW} migrating existing .eslintignore`));
103
+ const globs = parse(await fsp.readFile(pathESLintIngore, "utf-8")).globs();
105
104
  for (const glob of globs) if (glob.type === "ignore") eslintIgnores.push(...glob.patterns);
106
105
  else if (glob.type === "unignore") eslintIgnores.push(...glob.patterns.map((pattern) => `!${pattern}`));
107
106
  }
@@ -118,7 +117,7 @@ const { defineConfig } = require('@coderwyd/eslint-config')
118
117
  module.exports = defineConfig({\n${coderwydConfig}\n})
119
118
  `.trimStart();
120
119
  await fsp.writeFile(pathFlatConfig, eslintConfigContent);
121
- console.log(c.green(`${CHECK} created eslint.config.js`));
120
+ console.log(styleText("green", `${CHECK} created eslint.config.js`));
122
121
  const files = fs.readdirSync(cwd);
123
122
  const legacyConfig = [];
124
123
  files.forEach((file) => {
@@ -126,7 +125,7 @@ module.exports = defineConfig({\n${coderwydConfig}\n})
126
125
  });
127
126
  if (legacyConfig.length > 0) {
128
127
  console.log(`${WARN} you can now remove those files manually:`);
129
- console.log(` ${c.dim(legacyConfig.join(", "))}`);
128
+ console.log(` ${styleText("dim", legacyConfig.join(", "))}`);
130
129
  }
131
130
  let promptResult = { updateVscodeSettings: true };
132
131
  if (!SKIP_PROMPT) try {
@@ -148,24 +147,24 @@ module.exports = defineConfig({\n${coderwydConfig}\n})
148
147
  if (!fs.existsSync(dotVscodePath)) await fsp.mkdir(dotVscodePath, { recursive: true });
149
148
  if (!fs.existsSync(settingsPath)) {
150
149
  await fsp.writeFile(settingsPath, `{${vscodeSettingsString}}\n`, "utf-8");
151
- console.log(c.green(`${CHECK} created .vscode/settings.json`));
150
+ console.log(styleText("green", `${CHECK} created .vscode/settings.json`));
152
151
  } else {
153
152
  let settingsContent = await fsp.readFile(settingsPath, "utf8");
154
153
  settingsContent = settingsContent.trim().replace(/\s*\}$/, "");
155
154
  settingsContent += settingsContent.endsWith(",") || settingsContent.endsWith("{") ? "" : ",";
156
155
  settingsContent += `${vscodeSettingsString}}\n`;
157
156
  await fsp.writeFile(settingsPath, settingsContent, "utf-8");
158
- console.log(c.green(`${CHECK} updated .vscode/settings.json`));
157
+ console.log(styleText("green", `${CHECK} updated .vscode/settings.json`));
159
158
  }
160
159
  }
161
- console.log(c.green(`${CHECK} migration completed`));
162
- console.log(`Now you can update the dependencies and run ${c.blue("eslint . --fix")}\n`);
160
+ console.log(styleText("green", `${CHECK} migration completed`));
161
+ console.log(`Now you can update the dependencies and run ${styleText("blue", "eslint . --fix")}\n`);
163
162
  }
164
163
 
165
164
  //#endregion
166
165
  //#region src/cli/index.ts
167
166
  function header() {
168
- console.log(`\n${c.green(`@coderwyd/eslint-config `)}${c.dim(`v${version}`)}`);
167
+ console.log(`\n${styleText("green", `@coderwyd/eslint-config `)}${styleText("dim", `v${version}`)}`);
169
168
  }
170
169
  yargs(hideBin(process.argv)).scriptName("@coderwyd/eslint-config").usage("").command("*", "Run the initialization or migration", (args) => args.option("yes", {
171
170
  alias: "y",
@@ -177,8 +176,8 @@ yargs(hideBin(process.argv)).scriptName("@coderwyd/eslint-config").usage("").com
177
176
  try {
178
177
  await run(args);
179
178
  } catch (error) {
180
- console.error(c.inverse(c.red(" Failed to migrate ")));
181
- console.error(c.red(`${CROSS} ${String(error)}`));
179
+ console.error(styleText(["red", "inverse"], " Failed to migrate "));
180
+ console.error(styleText("red", `${CROSS} ${String(error)}`));
182
181
  process.exit(1);
183
182
  }
184
183
  }).showHelpOnFail(false).alias("h", "help").version("version", version).alias("v", "version").help().argv;
package/dist/index.d.ts CHANGED
@@ -508,6 +508,11 @@ interface RuleOptions {
508
508
  * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/empty-tags.md#repos-sticky-header
509
509
  */
510
510
  'jsdoc/empty-tags'?: Linter.RuleEntry<JsdocEmptyTags>;
511
+ /**
512
+ * Reports use of JSDoc tags in non-tag positions (in the default "typescript" mode).
513
+ * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/escape-inline-tags.md#repos-sticky-header
514
+ */
515
+ 'jsdoc/escape-inline-tags'?: Linter.RuleEntry<JsdocEscapeInlineTags>;
511
516
  /**
512
517
  * Prohibits use of `@implements` on non-constructor functions (to enforce the tag only being used on classes/constructors).
513
518
  * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/implements-on-classes.md#repos-sticky-header
@@ -773,6 +778,26 @@ interface RuleOptions {
773
778
  * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/text-escaping.md#repos-sticky-header
774
779
  */
775
780
  'jsdoc/text-escaping'?: Linter.RuleEntry<JsdocTextEscaping>;
781
+ /**
782
+ * Prefers either function properties or method signatures
783
+ * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/ts-method-signature-style.md#repos-sticky-header
784
+ */
785
+ 'jsdoc/ts-method-signature-style'?: Linter.RuleEntry<JsdocTsMethodSignatureStyle>;
786
+ /**
787
+ * Warns against use of the empty object type
788
+ * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/ts-no-empty-object-type.md#repos-sticky-header
789
+ */
790
+ 'jsdoc/ts-no-empty-object-type'?: Linter.RuleEntry<[]>;
791
+ /**
792
+ * Catches unnecessary template expressions such as string expressions within a template literal.
793
+ * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/ts-no-unnecessary-template-expression.md#repos-sticky-header
794
+ */
795
+ 'jsdoc/ts-no-unnecessary-template-expression'?: Linter.RuleEntry<JsdocTsNoUnnecessaryTemplateExpression>;
796
+ /**
797
+ * Prefers function types over call signatures when there are no other properties.
798
+ * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/ts-prefer-function-type.md#repos-sticky-header
799
+ */
800
+ 'jsdoc/ts-prefer-function-type'?: Linter.RuleEntry<JsdocTsPreferFunctionType>;
776
801
  /**
777
802
  * Formats JSDoc type values.
778
803
  * @see https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/type-formatting.md#repos-sticky-header
@@ -2444,7 +2469,7 @@ interface RuleOptions {
2444
2469
  */
2445
2470
  'react-dom/no-missing-button-type'?: Linter.RuleEntry<[]>;
2446
2471
  /**
2447
- * Enforces explicit `sandbox` attribute for `iframe` elements.
2472
+ * Enforces explicit `sandbox` prop for `iframe` elements.
2448
2473
  * @see https://eslint-react.xyz/docs/rules/dom-no-missing-iframe-sandbox
2449
2474
  */
2450
2475
  'react-dom/no-missing-iframe-sandbox'?: Linter.RuleEntry<[]>;
@@ -2508,20 +2533,124 @@ interface RuleOptions {
2508
2533
  * @see https://eslint-react.xyz/docs/rules/hooks-extra-no-direct-set-state-in-use-effect
2509
2534
  */
2510
2535
  'react-hooks-extra/no-direct-set-state-in-use-effect'?: Linter.RuleEntry<[]>;
2536
+ /**
2537
+ * Verifies that automatic effect dependencies are compiled if opted-in
2538
+ */
2539
+ 'react-hooks/automatic-effect-dependencies'?: Linter.RuleEntry<ReactHooksAutomaticEffectDependencies>;
2540
+ /**
2541
+ * Validates against calling capitalized functions/methods instead of using JSX
2542
+ */
2543
+ 'react-hooks/capitalized-calls'?: Linter.RuleEntry<ReactHooksCapitalizedCalls>;
2544
+ /**
2545
+ * Validates against higher order functions defining nested components or hooks. Components and hooks should be defined at the module level
2546
+ */
2547
+ 'react-hooks/component-hook-factories'?: Linter.RuleEntry<ReactHooksComponentHookFactories>;
2548
+ /**
2549
+ * Validates the compiler configuration options
2550
+ */
2551
+ 'react-hooks/config'?: Linter.RuleEntry<ReactHooksConfig>;
2552
+ /**
2553
+ * Validates usage of error boundaries instead of try/catch for errors in child components
2554
+ */
2555
+ 'react-hooks/error-boundaries'?: Linter.RuleEntry<ReactHooksErrorBoundaries>;
2511
2556
  /**
2512
2557
  * verifies the list of dependencies for Hooks like useEffect and similar
2513
2558
  * @see https://github.com/facebook/react/issues/14920
2514
2559
  */
2515
2560
  'react-hooks/exhaustive-deps'?: Linter.RuleEntry<ReactHooksExhaustiveDeps>;
2516
2561
  /**
2517
- * Surfaces diagnostics from React Forget
2562
+ * Validates usage of fbt
2563
+ */
2564
+ 'react-hooks/fbt'?: Linter.RuleEntry<ReactHooksFbt>;
2565
+ /**
2566
+ * Validates usage of `fire`
2567
+ */
2568
+ 'react-hooks/fire'?: Linter.RuleEntry<ReactHooksFire>;
2569
+ /**
2570
+ * Validates configuration of [gating mode](https://react.dev/reference/react-compiler/gating)
2571
+ */
2572
+ 'react-hooks/gating'?: Linter.RuleEntry<ReactHooksGating>;
2573
+ /**
2574
+ * Validates against assignment/mutation of globals during render, part of ensuring that [side effects must render outside of render](https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)
2575
+ */
2576
+ 'react-hooks/globals'?: Linter.RuleEntry<ReactHooksGlobals>;
2577
+ /**
2578
+ * Validates the rules of hooks
2579
+ */
2580
+ 'react-hooks/hooks'?: Linter.RuleEntry<ReactHooksHooks>;
2581
+ /**
2582
+ * Validates against mutating props, state, and other values that [are immutable](https://react.dev/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable)
2583
+ */
2584
+ 'react-hooks/immutability'?: Linter.RuleEntry<ReactHooksImmutability>;
2585
+ /**
2586
+ * Validates against usage of libraries which are incompatible with memoization (manual or automatic)
2587
+ */
2588
+ 'react-hooks/incompatible-library'?: Linter.RuleEntry<ReactHooksIncompatibleLibrary>;
2589
+ /**
2590
+ * Internal invariants
2518
2591
  */
2519
- 'react-hooks/react-compiler'?: Linter.RuleEntry<ReactHooksReactCompiler>;
2592
+ 'react-hooks/invariant'?: Linter.RuleEntry<ReactHooksInvariant>;
2593
+ /**
2594
+ * Validates that effect dependencies are memoized
2595
+ */
2596
+ 'react-hooks/memoized-effect-dependencies'?: Linter.RuleEntry<ReactHooksMemoizedEffectDependencies>;
2597
+ /**
2598
+ * Validates against deriving values from state in an effect
2599
+ */
2600
+ 'react-hooks/no-deriving-state-in-effects'?: Linter.RuleEntry<ReactHooksNoDerivingStateInEffects>;
2601
+ /**
2602
+ * Validates that existing manual memoized is preserved by the compiler. React Compiler will only compile components and hooks if its inference [matches or exceeds the existing manual memoization](https://react.dev/learn/react-compiler/introduction#what-should-i-do-about-usememo-usecallback-and-reactmemo)
2603
+ */
2604
+ 'react-hooks/preserve-manual-memoization'?: Linter.RuleEntry<ReactHooksPreserveManualMemoization>;
2605
+ /**
2606
+ * Validates that [components/hooks are pure](https://react.dev/reference/rules/components-and-hooks-must-be-pure) by checking that they do not call known-impure functions
2607
+ */
2608
+ 'react-hooks/purity'?: Linter.RuleEntry<ReactHooksPurity>;
2609
+ /**
2610
+ * Validates correct usage of refs, not reading/writing during render. See the "pitfalls" section in [`useRef()` usage](https://react.dev/reference/react/useRef#usage)
2611
+ */
2612
+ 'react-hooks/refs'?: Linter.RuleEntry<ReactHooksRefs>;
2613
+ /**
2614
+ * Validates against suppression of other rules
2615
+ */
2616
+ 'react-hooks/rule-suppression'?: Linter.RuleEntry<ReactHooksRuleSuppression>;
2520
2617
  /**
2521
2618
  * enforces the Rules of Hooks
2522
- * @see https://reactjs.org/docs/hooks-rules.html
2619
+ * @see https://react.dev/reference/rules/rules-of-hooks
2620
+ */
2621
+ 'react-hooks/rules-of-hooks'?: Linter.RuleEntry<ReactHooksRulesOfHooks>;
2622
+ /**
2623
+ * Validates against calling setState synchronously in an effect, which can lead to re-renders that degrade performance
2624
+ */
2625
+ 'react-hooks/set-state-in-effect'?: Linter.RuleEntry<ReactHooksSetStateInEffect>;
2626
+ /**
2627
+ * Validates against setting state during render, which can trigger additional renders and potential infinite render loops
2628
+ */
2629
+ 'react-hooks/set-state-in-render'?: Linter.RuleEntry<ReactHooksSetStateInRender>;
2630
+ /**
2631
+ * Validates that components are static, not recreated every render. Components that are recreated dynamically can reset state and trigger excessive re-rendering
2632
+ */
2633
+ 'react-hooks/static-components'?: Linter.RuleEntry<ReactHooksStaticComponents>;
2634
+ /**
2635
+ * Validates against invalid syntax
2636
+ */
2637
+ 'react-hooks/syntax'?: Linter.RuleEntry<ReactHooksSyntax>;
2638
+ /**
2639
+ * Unimplemented features
2640
+ */
2641
+ 'react-hooks/todo'?: Linter.RuleEntry<ReactHooksTodo>;
2642
+ /**
2643
+ * Validates against syntax that we do not plan to support in React Compiler
2644
+ */
2645
+ 'react-hooks/unsupported-syntax'?: Linter.RuleEntry<ReactHooksUnsupportedSyntax>;
2646
+ /**
2647
+ * Validates usage of the useMemo() hook against common mistakes. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.
2523
2648
  */
2524
- 'react-hooks/rules-of-hooks'?: Linter.RuleEntry<[]>;
2649
+ 'react-hooks/use-memo'?: Linter.RuleEntry<ReactHooksUseMemo>;
2650
+ /**
2651
+ * Validates that useMemos always return a value. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.
2652
+ */
2653
+ 'react-hooks/void-use-memo'?: Linter.RuleEntry<ReactHooksVoidUseMemo>;
2525
2654
  /**
2526
2655
  * Enforces naming conventions for components.
2527
2656
  * @see https://eslint-react.xyz/docs/rules/naming-convention-component-name
@@ -2569,7 +2698,7 @@ interface RuleOptions {
2569
2698
  */
2570
2699
  'react-web-api/no-leaked-timeout'?: Linter.RuleEntry<[]>;
2571
2700
  /**
2572
- * Enforces that the 'key' attribute is placed before the spread attribute in JSX elements.
2701
+ * Enforces that the 'key' prop is placed before the spread prop in JSX elements.
2573
2702
  * @see https://eslint-react.xyz/docs/rules/jsx-key-before-spread
2574
2703
  */
2575
2704
  'react/jsx-key-before-spread'?: Linter.RuleEntry<[]>;
@@ -2774,7 +2903,7 @@ interface RuleOptions {
2774
2903
  */
2775
2904
  'react/no-set-state-in-component-did-update'?: Linter.RuleEntry<[]>;
2776
2905
  /**
2777
- * Disallows calling `this.setState` in `componentWillUpdate` outside of functions, such as callbacks.
2906
+ * Disallow calling `this.setState` in `componentWillUpdate` outside of functions, such as callbacks.
2778
2907
  * @see https://eslint-react.xyz/docs/rules/no-set-state-in-component-will-update
2779
2908
  */
2780
2909
  'react/no-set-state-in-component-will-update'?: Linter.RuleEntry<[]>;
@@ -3851,7 +3980,7 @@ interface RuleOptions {
3851
3980
  */
3852
3981
  'template-tag-spacing'?: Linter.RuleEntry<TemplateTagSpacing>;
3853
3982
  /**
3854
- * require .spec test file pattern
3983
+ * require test file pattern
3855
3984
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-filename.md
3856
3985
  */
3857
3986
  'test/consistent-test-filename'?: Linter.RuleEntry<TestConsistentTestFilename>;
@@ -4036,6 +4165,11 @@ interface RuleOptions {
4036
4165
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-test-blocks.md
4037
4166
  */
4038
4167
  'test/padding-around-test-blocks'?: Linter.RuleEntry<[]>;
4168
+ /**
4169
+ * Prefer `toHaveBeenCalledExactlyOnceWith` over `toHaveBeenCalledOnce` and `toHaveBeenCalledWith`
4170
+ * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-exactly-once-with.md
4171
+ */
4172
+ 'test/prefer-called-exactly-once-with'?: Linter.RuleEntry<[]>;
4039
4173
  /**
4040
4174
  * enforce using `toBeCalledOnce()` or `toHaveBeenCalledOnce()`
4041
4175
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-once.md
@@ -4096,6 +4230,11 @@ interface RuleOptions {
4096
4230
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-on-top.md
4097
4231
  */
4098
4232
  'test/prefer-hooks-on-top'?: Linter.RuleEntry<[]>;
4233
+ /**
4234
+ * prefer dynamic import in mock
4235
+ * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-import-in-mock.md
4236
+ */
4237
+ 'test/prefer-import-in-mock'?: Linter.RuleEntry<[]>;
4099
4238
  /**
4100
4239
  * enforce importing Vitest globals
4101
4240
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-importing-vitest-globals.md
@@ -4643,7 +4782,7 @@ interface RuleOptions {
4643
4782
  * Disallow member access on a value with type `any`
4644
4783
  * @see https://typescript-eslint.io/rules/no-unsafe-member-access
4645
4784
  */
4646
- 'ts/no-unsafe-member-access'?: Linter.RuleEntry<[]>;
4785
+ 'ts/no-unsafe-member-access'?: Linter.RuleEntry<TsNoUnsafeMemberAccess>;
4647
4786
  /**
4648
4787
  * Disallow returning a value with type `any` from a function
4649
4788
  * @see https://typescript-eslint.io/rules/no-unsafe-return
@@ -7356,6 +7495,12 @@ type JsdocConvertToJsdocComments = [] | [{
7356
7495
  type JsdocEmptyTags = [] | [{
7357
7496
  tags?: string[];
7358
7497
  }];
7498
+ // ----- jsdoc/escape-inline-tags -----
7499
+ type JsdocEscapeInlineTags = [] | [{
7500
+ allowedInlineTags?: string[];
7501
+ enableFixer?: boolean;
7502
+ fixType?: ("backticks" | "backslash");
7503
+ }];
7359
7504
  // ----- jsdoc/implements-on-classes -----
7360
7505
  type JsdocImplementsOnClasses = [] | [{
7361
7506
  contexts?: (string | {
@@ -7642,6 +7787,7 @@ type JsdocRequireReturns = [] | [{
7642
7787
  type JsdocRequireReturnsCheck = [] | [{
7643
7788
  exemptAsync?: boolean;
7644
7789
  exemptGenerators?: boolean;
7790
+ noNativeTypes?: boolean;
7645
7791
  reportMissingReturnForUndefinedTypes?: boolean;
7646
7792
  }];
7647
7793
  // ----- jsdoc/require-returns-description -----
@@ -7730,16 +7876,44 @@ type JsdocTextEscaping = [] | [{
7730
7876
  escapeHTML?: boolean;
7731
7877
  escapeMarkdown?: boolean;
7732
7878
  }];
7879
+ // ----- jsdoc/ts-method-signature-style -----
7880
+ type JsdocTsMethodSignatureStyle = [] | [("method" | "property")] | [("method" | "property"), {
7881
+ enableFixer?: boolean;
7882
+ }];
7883
+ // ----- jsdoc/ts-no-unnecessary-template-expression -----
7884
+ type JsdocTsNoUnnecessaryTemplateExpression = [] | [{
7885
+ enableFixer?: boolean;
7886
+ }];
7887
+ // ----- jsdoc/ts-prefer-function-type -----
7888
+ type JsdocTsPreferFunctionType = [] | [{
7889
+ enableFixer?: boolean;
7890
+ }];
7733
7891
  // ----- jsdoc/type-formatting -----
7734
7892
  type JsdocTypeFormatting = [] | [{
7735
7893
  arrayBrackets?: ("angle" | "square");
7894
+ arrowFunctionPostReturnMarkerSpacing?: string;
7895
+ arrowFunctionPreReturnMarkerSpacing?: string;
7736
7896
  enableFixer?: boolean;
7897
+ functionOrClassParameterSpacing?: string;
7898
+ functionOrClassPostGenericSpacing?: string;
7899
+ functionOrClassPostReturnMarkerSpacing?: string;
7900
+ functionOrClassPreReturnMarkerSpacing?: string;
7901
+ functionOrClassTypeParameterSpacing?: string;
7902
+ genericAndTupleElementSpacing?: string;
7737
7903
  genericDot?: boolean;
7904
+ keyValuePostColonSpacing?: string;
7905
+ keyValuePostKeySpacing?: string;
7906
+ keyValuePostOptionalSpacing?: string;
7907
+ keyValuePostVariadicSpacing?: string;
7908
+ methodQuotes?: ("double" | "single");
7738
7909
  objectFieldIndent?: string;
7739
7910
  objectFieldQuote?: ("double" | "single" | null);
7740
7911
  objectFieldSeparator?: ("comma" | "comma-and-linebreak" | "linebreak" | "semicolon" | "semicolon-and-linebreak");
7741
7912
  objectFieldSeparatorOptionalLinebreak?: boolean;
7742
7913
  objectFieldSeparatorTrailingPunctuation?: boolean;
7914
+ parameterDefaultValueSpacing?: string;
7915
+ postMethodNameSpacing?: string;
7916
+ postNewSpacing?: string;
7743
7917
  separatorForSingleObjectField?: boolean;
7744
7918
  stringQuotes?: ("double" | "single");
7745
7919
  typeBracketSpacing?: string;
@@ -8763,12 +8937,14 @@ type NoRestrictedImports = ((string | {
8763
8937
  message?: string;
8764
8938
  importNames?: string[];
8765
8939
  allowImportNames?: string[];
8940
+ allowTypeImports?: boolean;
8766
8941
  })[] | [] | [{
8767
8942
  paths?: (string | {
8768
8943
  name: string;
8769
8944
  message?: string;
8770
8945
  importNames?: string[];
8771
8946
  allowImportNames?: string[];
8947
+ allowTypeImports?: boolean;
8772
8948
  })[];
8773
8949
  patterns?: (string[] | ({
8774
8950
  [k: string]: unknown | undefined;
@@ -11072,13 +11248,123 @@ type ReactDomNoUnknownProperty = [] | [{
11072
11248
  ignore?: string[];
11073
11249
  requireDataLowercase?: boolean;
11074
11250
  }];
11251
+ // ----- react-hooks/automatic-effect-dependencies -----
11252
+ type ReactHooksAutomaticEffectDependencies = [] | [{
11253
+ [k: string]: unknown | undefined;
11254
+ }];
11255
+ // ----- react-hooks/capitalized-calls -----
11256
+ type ReactHooksCapitalizedCalls = [] | [{
11257
+ [k: string]: unknown | undefined;
11258
+ }];
11259
+ // ----- react-hooks/component-hook-factories -----
11260
+ type ReactHooksComponentHookFactories = [] | [{
11261
+ [k: string]: unknown | undefined;
11262
+ }];
11263
+ // ----- react-hooks/config -----
11264
+ type ReactHooksConfig = [] | [{
11265
+ [k: string]: unknown | undefined;
11266
+ }];
11267
+ // ----- react-hooks/error-boundaries -----
11268
+ type ReactHooksErrorBoundaries = [] | [{
11269
+ [k: string]: unknown | undefined;
11270
+ }];
11075
11271
  // ----- react-hooks/exhaustive-deps -----
11076
11272
  type ReactHooksExhaustiveDeps = [] | [{
11077
11273
  additionalHooks?: string;
11078
11274
  enableDangerousAutofixThisMayCauseInfiniteLoops?: boolean;
11275
+ experimental_autoDependenciesHooks?: string[];
11276
+ requireExplicitEffectDeps?: boolean;
11277
+ }];
11278
+ // ----- react-hooks/fbt -----
11279
+ type ReactHooksFbt = [] | [{
11280
+ [k: string]: unknown | undefined;
11281
+ }];
11282
+ // ----- react-hooks/fire -----
11283
+ type ReactHooksFire = [] | [{
11284
+ [k: string]: unknown | undefined;
11285
+ }];
11286
+ // ----- react-hooks/gating -----
11287
+ type ReactHooksGating = [] | [{
11288
+ [k: string]: unknown | undefined;
11289
+ }];
11290
+ // ----- react-hooks/globals -----
11291
+ type ReactHooksGlobals = [] | [{
11292
+ [k: string]: unknown | undefined;
11293
+ }];
11294
+ // ----- react-hooks/hooks -----
11295
+ type ReactHooksHooks = [] | [{
11296
+ [k: string]: unknown | undefined;
11297
+ }];
11298
+ // ----- react-hooks/immutability -----
11299
+ type ReactHooksImmutability = [] | [{
11300
+ [k: string]: unknown | undefined;
11301
+ }];
11302
+ // ----- react-hooks/incompatible-library -----
11303
+ type ReactHooksIncompatibleLibrary = [] | [{
11304
+ [k: string]: unknown | undefined;
11305
+ }];
11306
+ // ----- react-hooks/invariant -----
11307
+ type ReactHooksInvariant = [] | [{
11308
+ [k: string]: unknown | undefined;
11079
11309
  }];
11080
- // ----- react-hooks/react-compiler -----
11081
- type ReactHooksReactCompiler = [] | [{
11310
+ // ----- react-hooks/memoized-effect-dependencies -----
11311
+ type ReactHooksMemoizedEffectDependencies = [] | [{
11312
+ [k: string]: unknown | undefined;
11313
+ }];
11314
+ // ----- react-hooks/no-deriving-state-in-effects -----
11315
+ type ReactHooksNoDerivingStateInEffects = [] | [{
11316
+ [k: string]: unknown | undefined;
11317
+ }];
11318
+ // ----- react-hooks/preserve-manual-memoization -----
11319
+ type ReactHooksPreserveManualMemoization = [] | [{
11320
+ [k: string]: unknown | undefined;
11321
+ }];
11322
+ // ----- react-hooks/purity -----
11323
+ type ReactHooksPurity = [] | [{
11324
+ [k: string]: unknown | undefined;
11325
+ }];
11326
+ // ----- react-hooks/refs -----
11327
+ type ReactHooksRefs = [] | [{
11328
+ [k: string]: unknown | undefined;
11329
+ }];
11330
+ // ----- react-hooks/rule-suppression -----
11331
+ type ReactHooksRuleSuppression = [] | [{
11332
+ [k: string]: unknown | undefined;
11333
+ }];
11334
+ // ----- react-hooks/rules-of-hooks -----
11335
+ type ReactHooksRulesOfHooks = [] | [{
11336
+ additionalHooks?: string;
11337
+ }];
11338
+ // ----- react-hooks/set-state-in-effect -----
11339
+ type ReactHooksSetStateInEffect = [] | [{
11340
+ [k: string]: unknown | undefined;
11341
+ }];
11342
+ // ----- react-hooks/set-state-in-render -----
11343
+ type ReactHooksSetStateInRender = [] | [{
11344
+ [k: string]: unknown | undefined;
11345
+ }];
11346
+ // ----- react-hooks/static-components -----
11347
+ type ReactHooksStaticComponents = [] | [{
11348
+ [k: string]: unknown | undefined;
11349
+ }];
11350
+ // ----- react-hooks/syntax -----
11351
+ type ReactHooksSyntax = [] | [{
11352
+ [k: string]: unknown | undefined;
11353
+ }];
11354
+ // ----- react-hooks/todo -----
11355
+ type ReactHooksTodo = [] | [{
11356
+ [k: string]: unknown | undefined;
11357
+ }];
11358
+ // ----- react-hooks/unsupported-syntax -----
11359
+ type ReactHooksUnsupportedSyntax = [] | [{
11360
+ [k: string]: unknown | undefined;
11361
+ }];
11362
+ // ----- react-hooks/use-memo -----
11363
+ type ReactHooksUseMemo = [] | [{
11364
+ [k: string]: unknown | undefined;
11365
+ }];
11366
+ // ----- react-hooks/void-use-memo -----
11367
+ type ReactHooksVoidUseMemo = [] | [{
11082
11368
  [k: string]: unknown | undefined;
11083
11369
  }];
11084
11370
  // ----- react-naming-convention/component-name -----
@@ -11119,7 +11405,6 @@ type ReactNoForbiddenProps = [] | [{
11119
11405
  includedNodes?: string[];
11120
11406
  prop: string;
11121
11407
  })[];
11122
- [k: string]: unknown | undefined;
11123
11408
  }];
11124
11409
  // ----- react/no-useless-fragment -----
11125
11410
  type ReactNoUselessFragment = [] | [{
@@ -12427,6 +12712,10 @@ type TsNoUnnecessaryTypeAssertion = [] | [{
12427
12712
  checkLiteralConstAssertions?: boolean;
12428
12713
  typesToIgnore?: string[];
12429
12714
  }];
12715
+ // ----- ts/no-unsafe-member-access -----
12716
+ type TsNoUnsafeMemberAccess = [] | [{
12717
+ allowOptionalChaining?: boolean;
12718
+ }];
12430
12719
  // ----- ts/no-unused-expressions -----
12431
12720
  type TsNoUnusedExpressions = [] | [{
12432
12721
  allowShortCircuit?: boolean;
@@ -12444,6 +12733,7 @@ type TsNoUnusedVars = [] | [(("all" | "local") | {
12444
12733
  destructuredArrayIgnorePattern?: string;
12445
12734
  ignoreClassWithStaticInitBlock?: boolean;
12446
12735
  ignoreRestSiblings?: boolean;
12736
+ ignoreUsingDeclarations?: boolean;
12447
12737
  reportUsedIgnorePattern?: boolean;
12448
12738
  vars?: ("all" | "local");
12449
12739
  varsIgnorePattern?: string;
@@ -12913,6 +13203,7 @@ type UnusedImportsNoUnusedImports = [] | [(("all" | "local") | {
12913
13203
  destructuredArrayIgnorePattern?: string;
12914
13204
  ignoreClassWithStaticInitBlock?: boolean;
12915
13205
  ignoreRestSiblings?: boolean;
13206
+ ignoreUsingDeclarations?: boolean;
12916
13207
  reportUsedIgnorePattern?: boolean;
12917
13208
  vars?: ("all" | "local");
12918
13209
  varsIgnorePattern?: string;
@@ -12926,6 +13217,7 @@ type UnusedImportsNoUnusedVars = [] | [(("all" | "local") | {
12926
13217
  destructuredArrayIgnorePattern?: string;
12927
13218
  ignoreClassWithStaticInitBlock?: boolean;
12928
13219
  ignoreRestSiblings?: boolean;
13220
+ ignoreUsingDeclarations?: boolean;
12929
13221
  reportUsedIgnorePattern?: boolean;
12930
13222
  vars?: ("all" | "local");
12931
13223
  varsIgnorePattern?: string;
package/dist/index.js CHANGED
@@ -220,12 +220,11 @@ function isInGitHooksOrLintStaged() {
220
220
  //#endregion
221
221
  //#region src/configs/imports.ts
222
222
  async function imports() {
223
- const pluginImport = await interopDefault(import("eslint-plugin-import-lite"));
224
223
  return [{
225
224
  name: "coderwyd/imports/rules",
226
225
  plugins: {
227
226
  antfu: pluginAntfu,
228
- import: pluginImport
227
+ import: await interopDefault(import("eslint-plugin-import-lite"))
229
228
  },
230
229
  rules: {
231
230
  "antfu/import-dedupe": "error",
@@ -756,8 +755,7 @@ async function react(options = {}) {
756
755
  "react-dom/no-unsafe-target-blank": "warn",
757
756
  "react-dom/no-use-form-state": "error",
758
757
  "react-dom/no-void-elements-with-children": "error",
759
- "react-hooks/exhaustive-deps": "warn",
760
- "react-hooks/rules-of-hooks": "error",
758
+ ...pluginReactHooks.configs.recommended.rules,
761
759
  "react-hooks-extra/no-direct-set-state-in-use-effect": "warn",
762
760
  "react-web-api/no-leaked-event-listener": "warn",
763
761
  "react-web-api/no-leaked-interval": "warn",
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@coderwyd/eslint-config",
3
3
  "type": "module",
4
- "version": "4.7.0",
4
+ "version": "4.7.2",
5
5
  "description": "Donny's ESLint config",
6
6
  "author": "Donny Wang <donny526@outlook.com> (https://github.com/coderwyd/)",
7
7
  "license": "MIT",
8
8
  "homepage": "https://github.com/coderwyd/eslint-config",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/coderwyd/eslint-config.git"
12
+ },
9
13
  "keywords": [
10
14
  "eslint",
11
15
  "eslint-config",
@@ -36,7 +40,7 @@
36
40
  "@eslint-react/eslint-plugin": "^1.5.8",
37
41
  "@unocss/eslint-plugin": ">=0.50.0",
38
42
  "eslint": "^9.5.0",
39
- "eslint-plugin-react-hooks": "^4.6.0 || ^5.0.0",
43
+ "eslint-plugin-react-hooks": "^4.6.0 || ^5.0.0 || ^7.0.0",
40
44
  "eslint-plugin-react-refresh": "^0.4.4",
41
45
  "eslint-plugin-svelte": ">=2.35.1",
42
46
  "eslint-plugin-tailwindcss": "^3.16.0",
@@ -71,30 +75,29 @@
71
75
  "dependencies": {
72
76
  "@antfu/install-pkg": "^1.1.0",
73
77
  "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
74
- "@typescript-eslint/eslint-plugin": "^8.45.0",
75
- "@typescript-eslint/parser": "^8.45.0",
76
- "@vitest/eslint-plugin": "^1.3.13",
78
+ "@typescript-eslint/eslint-plugin": "^8.46.1",
79
+ "@typescript-eslint/parser": "^8.46.1",
80
+ "@vitest/eslint-plugin": "^1.3.20",
77
81
  "eslint-config-flat-gitignore": "^2.1.0",
78
82
  "eslint-config-prettier": "^10.1.8",
79
83
  "eslint-plugin-antfu": "^3.1.1",
80
84
  "eslint-plugin-command": "^3.3.1",
81
85
  "eslint-plugin-de-morgan": "^2.0.0",
82
86
  "eslint-plugin-import-lite": "^0.3.0",
83
- "eslint-plugin-jsdoc": "^60.5.0",
84
- "eslint-plugin-jsonc": "^2.20.1",
87
+ "eslint-plugin-jsdoc": "61.1.2",
88
+ "eslint-plugin-jsonc": "^2.21.0",
85
89
  "eslint-plugin-n": "^17.23.1",
86
90
  "eslint-plugin-no-only-tests": "^3.3.0",
87
- "eslint-plugin-perfectionist": "^4.15.0",
91
+ "eslint-plugin-perfectionist": "^4.15.1",
88
92
  "eslint-plugin-regexp": "^2.10.0",
89
93
  "eslint-plugin-unicorn": "^61.0.2",
90
94
  "eslint-plugin-unused-imports": "^4.2.0",
91
95
  "eslint-plugin-vue": "^10.5.0",
92
- "eslint-plugin-yml": "^1.18.0",
96
+ "eslint-plugin-yml": "^1.19.0",
93
97
  "globals": "^16.4.0",
94
98
  "jsonc-eslint-parser": "^2.4.1",
95
99
  "local-pkg": "^1.1.2",
96
100
  "parse-gitignore": "^2.0.0",
97
- "picocolors": "^1.1.1",
98
101
  "prompts": "^2.4.2",
99
102
  "vue-eslint-parser": "^10.2.0",
100
103
  "yaml-eslint-parser": "^1.3.0",
@@ -102,30 +105,30 @@
102
105
  },
103
106
  "devDependencies": {
104
107
  "@antfu/ni": "^26.1.0",
105
- "@eslint-react/eslint-plugin": "^2.0.3",
108
+ "@eslint-react/eslint-plugin": "^2.2.2",
106
109
  "@eslint/config-inspector": "^1.3.0",
107
110
  "@types/eslint-config-prettier": "^6.11.3",
108
- "@types/node": "^24.6.0",
111
+ "@types/node": "^24.7.2",
109
112
  "@types/prompts": "^2.4.9",
110
113
  "@types/yargs": "^17.0.33",
111
- "@unocss/eslint-plugin": "^66.5.2",
112
- "bumpp": "^10.2.3",
113
- "eslint": "^9.36.0",
114
- "eslint-plugin-react-hooks": "6.0.0-rc1",
115
- "eslint-plugin-react-refresh": "^0.4.22",
114
+ "@unocss/eslint-plugin": "^66.5.3",
115
+ "bumpp": "^10.3.1",
116
+ "eslint": "^9.37.0",
117
+ "eslint-plugin-react-hooks": "7.0.0",
118
+ "eslint-plugin-react-refresh": "^0.4.23",
116
119
  "eslint-plugin-svelte": "^3.12.4",
117
120
  "eslint-plugin-tailwindcss": "^3.18.2",
118
121
  "eslint-typegen": "^2.3.0",
119
- "jiti": "^2.6.0",
122
+ "jiti": "^2.6.1",
120
123
  "nano-staged": "^0.8.0",
121
124
  "prettier": "^3.6.2",
122
- "publint": "^0.3.13",
125
+ "publint": "^0.3.14",
123
126
  "simple-git-hooks": "^2.13.1",
124
- "svelte": "^5.39.6",
127
+ "svelte": "^5.40.0",
125
128
  "svelte-eslint-parser": "^1.3.3",
126
- "tsdown": "^0.15.5",
127
- "typescript": "^5.9.2",
128
- "unplugin-unused": "^0.5.3"
129
+ "tsdown": "^0.15.7",
130
+ "typescript": "^5.9.3",
131
+ "unplugin-unused": "^0.5.4"
129
132
  },
130
133
  "simple-git-hooks": {
131
134
  "pre-commit": "pnpm exec nano-staged"
@@ -140,7 +143,7 @@
140
143
  "lint:fix": "eslint . --fix",
141
144
  "build:inspector": "pnpm build && pnpx @eslint/config-inspector build",
142
145
  "build:typegen": "jiti scripts/typegen.ts",
143
- "release": "bumpp && pnpm publish",
146
+ "release": "bumpp",
144
147
  "typecheck": "tsc --noEmit"
145
148
  }
146
149
  }