@antfu/eslint-config 3.12.2 → 3.14.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/cli.cjs CHANGED
@@ -41,7 +41,7 @@ var import_picocolors = __toESM(require("picocolors"), 1);
41
41
  var package_default = {
42
42
  name: "@antfu/eslint-config",
43
43
  type: "module",
44
- version: "3.12.2",
44
+ version: "3.14.0",
45
45
  packageManager: "pnpm@10.0.0",
46
46
  description: "Anthony's ESLint config",
47
47
  author: "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
@@ -70,8 +70,8 @@ var package_default = {
70
70
  dev: "npx @eslint/config-inspector --config eslint.config.ts",
71
71
  "build:inspector": "pnpm build && npx @eslint/config-inspector build",
72
72
  watch: "tsup --format esm,cjs --watch",
73
- lint: "eslint --flag unstable_ts_config .",
74
- typegen: "esno scripts/typegen.ts",
73
+ lint: "eslint .",
74
+ typegen: "tsx scripts/typegen.ts",
75
75
  prepack: "nr build",
76
76
  release: "bumpp && pnpm publish",
77
77
  test: "vitest",
@@ -136,19 +136,19 @@ var package_default = {
136
136
  }
137
137
  },
138
138
  dependencies: {
139
- "@antfu/install-pkg": "^0.5.0",
140
- "@clack/prompts": "^0.9.0",
139
+ "@antfu/install-pkg": "^1.0.0",
140
+ "@clack/prompts": "^0.9.1",
141
141
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
142
142
  "@eslint/markdown": "^6.2.1",
143
- "@stylistic/eslint-plugin": "^2.12.1",
143
+ "@stylistic/eslint-plugin": "^2.13.0",
144
144
  "@typescript-eslint/eslint-plugin": "^8.19.1",
145
145
  "@typescript-eslint/parser": "^8.19.1",
146
- "@vitest/eslint-plugin": "^1.1.24",
147
- "eslint-config-flat-gitignore": "^0.3.0",
148
- "eslint-flat-config-utils": "^0.4.0",
149
- "eslint-merge-processors": "^0.1.0",
146
+ "@vitest/eslint-plugin": "^1.1.25",
147
+ "eslint-config-flat-gitignore": "^1.0.0",
148
+ "eslint-flat-config-utils": "^1.0.0",
149
+ "eslint-merge-processors": "^1.0.0",
150
150
  "eslint-plugin-antfu": "^2.7.0",
151
- "eslint-plugin-command": "^0.2.7",
151
+ "eslint-plugin-command": "^2.1.0",
152
152
  "eslint-plugin-import-x": "^4.6.1",
153
153
  "eslint-plugin-jsdoc": "^50.6.1",
154
154
  "eslint-plugin-jsonc": "^2.18.2",
@@ -161,10 +161,10 @@ var package_default = {
161
161
  "eslint-plugin-unused-imports": "^4.1.4",
162
162
  "eslint-plugin-vue": "^9.32.0",
163
163
  "eslint-plugin-yml": "^1.16.0",
164
- "eslint-processor-vue-blocks": "^0.1.2",
164
+ "eslint-processor-vue-blocks": "^1.0.0",
165
165
  globals: "^15.14.0",
166
166
  "jsonc-eslint-parser": "^2.4.0",
167
- "local-pkg": "^0.5.1",
167
+ "local-pkg": "^1.0.0",
168
168
  "parse-gitignore": "^2.0.0",
169
169
  picocolors: "^1.1.1",
170
170
  "toml-eslint-parser": "^0.10.0",
@@ -174,27 +174,26 @@ var package_default = {
174
174
  },
175
175
  devDependencies: {
176
176
  "@antfu/eslint-config": "workspace:*",
177
- "@antfu/ni": "^0.23.2",
177
+ "@antfu/ni": "^23.2.0",
178
178
  "@eslint-react/eslint-plugin": "^1.23.2",
179
179
  "@eslint/config-inspector": "^0.7.1",
180
180
  "@prettier/plugin-xml": "^3.4.1",
181
- "@stylistic/eslint-plugin-migrate": "^2.12.1",
181
+ "@stylistic/eslint-plugin-migrate": "^2.13.0",
182
182
  "@types/fs-extra": "^11.0.4",
183
183
  "@types/node": "^22.10.5",
184
184
  "@types/prompts": "^2.4.9",
185
185
  "@types/yargs": "^17.0.33",
186
- "@unocss/eslint-plugin": "^0.65.3",
186
+ "@unocss/eslint-plugin": "^65.4.0",
187
187
  "astro-eslint-parser": "^1.1.0",
188
- bumpp: "^9.9.3",
189
- eslint: "^9.17.0",
188
+ bumpp: "^9.10.0",
189
+ eslint: "^9.18.0",
190
190
  "eslint-plugin-astro": "^1.3.1",
191
- "eslint-plugin-format": "^1.0.0",
191
+ "eslint-plugin-format": "^1.0.1",
192
192
  "eslint-plugin-react-hooks": "^5.1.0",
193
- "eslint-plugin-react-refresh": "^0.4.16",
193
+ "eslint-plugin-react-refresh": "^0.4.18",
194
194
  "eslint-plugin-solid": "^0.14.5",
195
195
  "eslint-plugin-svelte": "^2.46.1",
196
- "eslint-typegen": "^0.3.2",
197
- esno: "^4.8.0",
196
+ "eslint-typegen": "^1.0.0",
198
197
  execa: "^9.5.2",
199
198
  "fast-glob": "^3.3.3",
200
199
  "fs-extra": "^11.2.0",
@@ -204,25 +203,25 @@ var package_default = {
204
203
  "prettier-plugin-slidev": "^1.0.5",
205
204
  rimraf: "^6.0.1",
206
205
  "simple-git-hooks": "^2.11.1",
207
- svelte: "^5.16.6",
206
+ svelte: "^5.17.3",
208
207
  "svelte-eslint-parser": "^0.43.0",
209
208
  tsup: "^8.3.5",
210
209
  tsx: "^4.19.2",
211
- typescript: "^5.7.2",
210
+ typescript: "^5.7.3",
212
211
  vitest: "^2.1.8",
213
212
  vue: "^3.5.13"
214
213
  },
215
214
  resolutions: {
216
215
  "@eslint-community/eslint-utils": "^4.4.1",
217
216
  "@typescript-eslint/utils": "^8.19.1",
218
- eslint: "^9.17.0",
217
+ eslint: "^9.18.0",
219
218
  tsx: "^4.19.2"
220
219
  },
221
220
  "simple-git-hooks": {
222
221
  "pre-commit": "npx lint-staged"
223
222
  },
224
223
  "lint-staged": {
225
- "*": "eslint --flag unstable_ts_config --fix"
224
+ "*": "eslint --fix"
226
225
  }
227
226
  };
228
227
 
@@ -270,6 +269,7 @@ var vscodeSettingsString = `
270
269
  "gql",
271
270
  "graphql",
272
271
  "astro",
272
+ "svelte",
273
273
  "css",
274
274
  "less",
275
275
  "scss",
package/dist/cli.js CHANGED
@@ -12,7 +12,7 @@ import c from "picocolors";
12
12
  var package_default = {
13
13
  name: "@antfu/eslint-config",
14
14
  type: "module",
15
- version: "3.12.2",
15
+ version: "3.14.0",
16
16
  packageManager: "pnpm@10.0.0",
17
17
  description: "Anthony's ESLint config",
18
18
  author: "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
@@ -41,8 +41,8 @@ var package_default = {
41
41
  dev: "npx @eslint/config-inspector --config eslint.config.ts",
42
42
  "build:inspector": "pnpm build && npx @eslint/config-inspector build",
43
43
  watch: "tsup --format esm,cjs --watch",
44
- lint: "eslint --flag unstable_ts_config .",
45
- typegen: "esno scripts/typegen.ts",
44
+ lint: "eslint .",
45
+ typegen: "tsx scripts/typegen.ts",
46
46
  prepack: "nr build",
47
47
  release: "bumpp && pnpm publish",
48
48
  test: "vitest",
@@ -107,19 +107,19 @@ var package_default = {
107
107
  }
108
108
  },
109
109
  dependencies: {
110
- "@antfu/install-pkg": "^0.5.0",
111
- "@clack/prompts": "^0.9.0",
110
+ "@antfu/install-pkg": "^1.0.0",
111
+ "@clack/prompts": "^0.9.1",
112
112
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
113
113
  "@eslint/markdown": "^6.2.1",
114
- "@stylistic/eslint-plugin": "^2.12.1",
114
+ "@stylistic/eslint-plugin": "^2.13.0",
115
115
  "@typescript-eslint/eslint-plugin": "^8.19.1",
116
116
  "@typescript-eslint/parser": "^8.19.1",
117
- "@vitest/eslint-plugin": "^1.1.24",
118
- "eslint-config-flat-gitignore": "^0.3.0",
119
- "eslint-flat-config-utils": "^0.4.0",
120
- "eslint-merge-processors": "^0.1.0",
117
+ "@vitest/eslint-plugin": "^1.1.25",
118
+ "eslint-config-flat-gitignore": "^1.0.0",
119
+ "eslint-flat-config-utils": "^1.0.0",
120
+ "eslint-merge-processors": "^1.0.0",
121
121
  "eslint-plugin-antfu": "^2.7.0",
122
- "eslint-plugin-command": "^0.2.7",
122
+ "eslint-plugin-command": "^2.1.0",
123
123
  "eslint-plugin-import-x": "^4.6.1",
124
124
  "eslint-plugin-jsdoc": "^50.6.1",
125
125
  "eslint-plugin-jsonc": "^2.18.2",
@@ -132,10 +132,10 @@ var package_default = {
132
132
  "eslint-plugin-unused-imports": "^4.1.4",
133
133
  "eslint-plugin-vue": "^9.32.0",
134
134
  "eslint-plugin-yml": "^1.16.0",
135
- "eslint-processor-vue-blocks": "^0.1.2",
135
+ "eslint-processor-vue-blocks": "^1.0.0",
136
136
  globals: "^15.14.0",
137
137
  "jsonc-eslint-parser": "^2.4.0",
138
- "local-pkg": "^0.5.1",
138
+ "local-pkg": "^1.0.0",
139
139
  "parse-gitignore": "^2.0.0",
140
140
  picocolors: "^1.1.1",
141
141
  "toml-eslint-parser": "^0.10.0",
@@ -145,27 +145,26 @@ var package_default = {
145
145
  },
146
146
  devDependencies: {
147
147
  "@antfu/eslint-config": "workspace:*",
148
- "@antfu/ni": "^0.23.2",
148
+ "@antfu/ni": "^23.2.0",
149
149
  "@eslint-react/eslint-plugin": "^1.23.2",
150
150
  "@eslint/config-inspector": "^0.7.1",
151
151
  "@prettier/plugin-xml": "^3.4.1",
152
- "@stylistic/eslint-plugin-migrate": "^2.12.1",
152
+ "@stylistic/eslint-plugin-migrate": "^2.13.0",
153
153
  "@types/fs-extra": "^11.0.4",
154
154
  "@types/node": "^22.10.5",
155
155
  "@types/prompts": "^2.4.9",
156
156
  "@types/yargs": "^17.0.33",
157
- "@unocss/eslint-plugin": "^0.65.3",
157
+ "@unocss/eslint-plugin": "^65.4.0",
158
158
  "astro-eslint-parser": "^1.1.0",
159
- bumpp: "^9.9.3",
160
- eslint: "^9.17.0",
159
+ bumpp: "^9.10.0",
160
+ eslint: "^9.18.0",
161
161
  "eslint-plugin-astro": "^1.3.1",
162
- "eslint-plugin-format": "^1.0.0",
162
+ "eslint-plugin-format": "^1.0.1",
163
163
  "eslint-plugin-react-hooks": "^5.1.0",
164
- "eslint-plugin-react-refresh": "^0.4.16",
164
+ "eslint-plugin-react-refresh": "^0.4.18",
165
165
  "eslint-plugin-solid": "^0.14.5",
166
166
  "eslint-plugin-svelte": "^2.46.1",
167
- "eslint-typegen": "^0.3.2",
168
- esno: "^4.8.0",
167
+ "eslint-typegen": "^1.0.0",
169
168
  execa: "^9.5.2",
170
169
  "fast-glob": "^3.3.3",
171
170
  "fs-extra": "^11.2.0",
@@ -175,25 +174,25 @@ var package_default = {
175
174
  "prettier-plugin-slidev": "^1.0.5",
176
175
  rimraf: "^6.0.1",
177
176
  "simple-git-hooks": "^2.11.1",
178
- svelte: "^5.16.6",
177
+ svelte: "^5.17.3",
179
178
  "svelte-eslint-parser": "^0.43.0",
180
179
  tsup: "^8.3.5",
181
180
  tsx: "^4.19.2",
182
- typescript: "^5.7.2",
181
+ typescript: "^5.7.3",
183
182
  vitest: "^2.1.8",
184
183
  vue: "^3.5.13"
185
184
  },
186
185
  resolutions: {
187
186
  "@eslint-community/eslint-utils": "^4.4.1",
188
187
  "@typescript-eslint/utils": "^8.19.1",
189
- eslint: "^9.17.0",
188
+ eslint: "^9.18.0",
190
189
  tsx: "^4.19.2"
191
190
  },
192
191
  "simple-git-hooks": {
193
192
  "pre-commit": "npx lint-staged"
194
193
  },
195
194
  "lint-staged": {
196
- "*": "eslint --flag unstable_ts_config --fix"
195
+ "*": "eslint --fix"
197
196
  }
198
197
  };
199
198
 
@@ -241,6 +240,7 @@ var vscodeSettingsString = `
241
240
  "gql",
242
241
  "graphql",
243
242
  "astro",
243
+ "svelte",
244
244
  "css",
245
245
  "less",
246
246
  "scss",
package/dist/index.cjs CHANGED
@@ -107,7 +107,7 @@ __export(index_exports, {
107
107
  });
108
108
  module.exports = __toCommonJS(index_exports);
109
109
 
110
- // node_modules/.pnpm/tsup@8.3.5_jiti@2.4.2_postcss@8.4.49_tsx@4.19.2_typescript@5.7.2_yaml@2.6.1/node_modules/tsup/assets/cjs_shims.js
110
+ // node_modules/.pnpm/tsup@8.3.5_jiti@2.4.2_postcss@8.4.49_tsx@4.19.2_typescript@5.7.3_yaml@2.6.1/node_modules/tsup/assets/cjs_shims.js
111
111
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
112
112
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
113
113
 
@@ -1304,6 +1304,12 @@ var RemixPackages = [
1304
1304
  "@remix-run/serve",
1305
1305
  "@remix-run/dev"
1306
1306
  ];
1307
+ var ReactRouterPackages = [
1308
+ "@react-router/node",
1309
+ "@react-router/react",
1310
+ "@react-router/serve",
1311
+ "@react-router/dev"
1312
+ ];
1307
1313
  var NextJsPackages = [
1308
1314
  "next"
1309
1315
  ];
@@ -1338,6 +1344,7 @@ async function react(options = {}) {
1338
1344
  ]);
1339
1345
  const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some((i) => (0, import_local_pkg3.isPackageExists)(i));
1340
1346
  const isUsingRemix = RemixPackages.some((i) => (0, import_local_pkg3.isPackageExists)(i));
1347
+ const isUsingReactRouter = ReactRouterPackages.some((i) => (0, import_local_pkg3.isPackageExists)(i));
1341
1348
  const isUsingNext = NextJsPackages.some((i) => (0, import_local_pkg3.isPackageExists)(i));
1342
1349
  const plugins = pluginReact.configs.all.plugins;
1343
1350
  return [
@@ -1349,7 +1356,8 @@ async function react(options = {}) {
1349
1356
  "react-hooks": pluginReactHooks,
1350
1357
  "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1351
1358
  "react-naming-convention": plugins["@eslint-react/naming-convention"],
1352
- "react-refresh": pluginReactRefresh
1359
+ "react-refresh": pluginReactRefresh,
1360
+ "react-web-api": plugins["@eslint-react/web-api"]
1353
1361
  }
1354
1362
  },
1355
1363
  {
@@ -1400,7 +1408,7 @@ async function react(options = {}) {
1400
1408
  "viewport",
1401
1409
  "generateViewport"
1402
1410
  ] : [],
1403
- ...isUsingRemix ? [
1411
+ ...isUsingRemix || isUsingReactRouter ? [
1404
1412
  "meta",
1405
1413
  "links",
1406
1414
  "headers",
@@ -1410,6 +1418,11 @@ async function react(options = {}) {
1410
1418
  ]
1411
1419
  }
1412
1420
  ],
1421
+ // recommended rules from @eslint-react/web-api
1422
+ "react-web-api/no-leaked-event-listener": "warn",
1423
+ "react-web-api/no-leaked-interval": "warn",
1424
+ "react-web-api/no-leaked-resize-observer": "warn",
1425
+ "react-web-api/no-leaked-timeout": "warn",
1413
1426
  // recommended rules from @eslint-react
1414
1427
  "react/ensure-forward-ref-using-ref": "warn",
1415
1428
  "react/jsx-no-duplicate-props": "warn",
package/dist/index.d.cts CHANGED
@@ -468,7 +468,7 @@ interface RuleOptions {
468
468
  */
469
469
  'default-case'?: Linter.RuleEntry<DefaultCase>
470
470
  /**
471
- * Enforce `default` clauses in switch statements to be last
471
+ * Enforce `default` clauses in `switch` statements to be last
472
472
  * @see https://eslint.org/docs/latest/rules/default-case-last
473
473
  */
474
474
  'default-case-last'?: Linter.RuleEntry<[]>
@@ -2972,6 +2972,26 @@ interface RuleOptions {
2972
2972
  */
2973
2973
  'react-naming-convention/use-state'?: Linter.RuleEntry<[]>
2974
2974
  'react-refresh/only-export-components'?: Linter.RuleEntry<ReactRefreshOnlyExportComponents>
2975
+ /**
2976
+ * enforce that every 'addEventListener' in a component or custom Hook has a corresponding 'removeEventListener'.
2977
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-event-listener
2978
+ */
2979
+ 'react-web-api/no-leaked-event-listener'?: Linter.RuleEntry<[]>
2980
+ /**
2981
+ * enforce that every 'setInterval' in a component or custom Hook has a corresponding 'clearInterval'.
2982
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-interval
2983
+ */
2984
+ 'react-web-api/no-leaked-interval'?: Linter.RuleEntry<[]>
2985
+ /**
2986
+ * enforce cleanup of 'ResizeObserver' instances in components and custom Hooks.
2987
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-resize-observer
2988
+ */
2989
+ 'react-web-api/no-leaked-resize-observer'?: Linter.RuleEntry<[]>
2990
+ /**
2991
+ * enforce that every 'setTimeout' in a component or custom Hook has a corresponding 'clearTimeout'.
2992
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-timeout
2993
+ */
2994
+ 'react-web-api/no-leaked-timeout'?: Linter.RuleEntry<[]>
2975
2995
  /**
2976
2996
  * disallow using shorthand boolean attributes
2977
2997
  * @see https://eslint-react.xyz/docs/rules/avoid-shorthand-boolean
@@ -3793,7 +3813,7 @@ interface RuleOptions {
3793
3813
  */
3794
3814
  'solid/style-prop'?: Linter.RuleEntry<SolidStyleProp>
3795
3815
  /**
3796
- * Enforce sorted import declarations within modules
3816
+ * Enforce sorted `import` declarations within modules
3797
3817
  * @see https://eslint.org/docs/latest/rules/sort-imports
3798
3818
  */
3799
3819
  'sort-imports'?: Linter.RuleEntry<SortImports>
@@ -12120,6 +12140,7 @@ type StyleKeySpacing = []|[({
12120
12140
  mode?: ("strict" | "minimum")
12121
12141
  beforeColon?: boolean
12122
12142
  afterColon?: boolean
12143
+ ignoredNodes?: ("ObjectExpression" | "ObjectPattern" | "ImportDeclaration" | "ExportNamedDeclaration" | "ExportAllDeclaration" | "TSTypeLiteral" | "TSInterfaceBody" | "ClassBody")[]
12123
12144
  } | {
12124
12145
  singleLine?: {
12125
12146
  mode?: ("strict" | "minimum")
@@ -12635,6 +12656,7 @@ type StyleNoExtraParens = ([]|["functions"] | []|["all"]|["all", {
12635
12656
  enforceForNewInMemberExpressions?: boolean
12636
12657
  enforceForFunctionPrototypeMethods?: boolean
12637
12658
  allowParensAfterCommentPattern?: string
12659
+ nestedConditionalExpressions?: boolean
12638
12660
  }])
12639
12661
  // ----- style/no-mixed-operators -----
12640
12662
  type StyleNoMixedOperators = []|[{
@@ -12732,14 +12754,14 @@ type StyleOperatorLinebreak = []|[(("after" | "before" | "none") | null)]|[(("af
12732
12754
  }
12733
12755
  }]
12734
12756
  // ----- style/padded-blocks -----
12735
- type StylePaddedBlocks = []|[(("always" | "never") | {
12736
- blocks?: ("always" | "never")
12737
- switches?: ("always" | "never")
12738
- classes?: ("always" | "never")
12739
- })]|[(("always" | "never") | {
12740
- blocks?: ("always" | "never")
12741
- switches?: ("always" | "never")
12742
- classes?: ("always" | "never")
12757
+ type StylePaddedBlocks = []|[(("always" | "never" | "start" | "end") | {
12758
+ blocks?: ("always" | "never" | "start" | "end")
12759
+ switches?: ("always" | "never" | "start" | "end")
12760
+ classes?: ("always" | "never" | "start" | "end")
12761
+ })]|[(("always" | "never" | "start" | "end") | {
12762
+ blocks?: ("always" | "never" | "start" | "end")
12763
+ switches?: ("always" | "never" | "start" | "end")
12764
+ classes?: ("always" | "never" | "start" | "end")
12743
12765
  }), {
12744
12766
  allowSingleLineBlocks?: boolean
12745
12767
  }]
@@ -14882,6 +14904,7 @@ type VueKeySpacing = []|[({
14882
14904
  mode?: ("strict" | "minimum")
14883
14905
  beforeColon?: boolean
14884
14906
  afterColon?: boolean
14907
+ ignoredNodes?: ("ObjectExpression" | "ObjectPattern" | "ImportDeclaration" | "ExportNamedDeclaration" | "ExportAllDeclaration" | "TSTypeLiteral" | "TSInterfaceBody" | "ClassBody")[]
14885
14908
  } | {
14886
14909
  singleLine?: {
14887
14910
  mode?: ("strict" | "minimum")
@@ -15408,6 +15431,7 @@ type VueNoExtraParens = ([]|["functions"] | []|["all"]|["all", {
15408
15431
  enforceForNewInMemberExpressions?: boolean
15409
15432
  enforceForFunctionPrototypeMethods?: boolean
15410
15433
  allowParensAfterCommentPattern?: string
15434
+ nestedConditionalExpressions?: boolean
15411
15435
  }])
15412
15436
  // ----- vue/no-irregular-whitespace -----
15413
15437
  type VueNoIrregularWhitespace = []|[{
package/dist/index.d.ts CHANGED
@@ -468,7 +468,7 @@ interface RuleOptions {
468
468
  */
469
469
  'default-case'?: Linter.RuleEntry<DefaultCase>
470
470
  /**
471
- * Enforce `default` clauses in switch statements to be last
471
+ * Enforce `default` clauses in `switch` statements to be last
472
472
  * @see https://eslint.org/docs/latest/rules/default-case-last
473
473
  */
474
474
  'default-case-last'?: Linter.RuleEntry<[]>
@@ -2972,6 +2972,26 @@ interface RuleOptions {
2972
2972
  */
2973
2973
  'react-naming-convention/use-state'?: Linter.RuleEntry<[]>
2974
2974
  'react-refresh/only-export-components'?: Linter.RuleEntry<ReactRefreshOnlyExportComponents>
2975
+ /**
2976
+ * enforce that every 'addEventListener' in a component or custom Hook has a corresponding 'removeEventListener'.
2977
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-event-listener
2978
+ */
2979
+ 'react-web-api/no-leaked-event-listener'?: Linter.RuleEntry<[]>
2980
+ /**
2981
+ * enforce that every 'setInterval' in a component or custom Hook has a corresponding 'clearInterval'.
2982
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-interval
2983
+ */
2984
+ 'react-web-api/no-leaked-interval'?: Linter.RuleEntry<[]>
2985
+ /**
2986
+ * enforce cleanup of 'ResizeObserver' instances in components and custom Hooks.
2987
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-resize-observer
2988
+ */
2989
+ 'react-web-api/no-leaked-resize-observer'?: Linter.RuleEntry<[]>
2990
+ /**
2991
+ * enforce that every 'setTimeout' in a component or custom Hook has a corresponding 'clearTimeout'.
2992
+ * @see https://eslint-react.xyz/docs/rules/web-api-no-leaked-timeout
2993
+ */
2994
+ 'react-web-api/no-leaked-timeout'?: Linter.RuleEntry<[]>
2975
2995
  /**
2976
2996
  * disallow using shorthand boolean attributes
2977
2997
  * @see https://eslint-react.xyz/docs/rules/avoid-shorthand-boolean
@@ -3793,7 +3813,7 @@ interface RuleOptions {
3793
3813
  */
3794
3814
  'solid/style-prop'?: Linter.RuleEntry<SolidStyleProp>
3795
3815
  /**
3796
- * Enforce sorted import declarations within modules
3816
+ * Enforce sorted `import` declarations within modules
3797
3817
  * @see https://eslint.org/docs/latest/rules/sort-imports
3798
3818
  */
3799
3819
  'sort-imports'?: Linter.RuleEntry<SortImports>
@@ -12120,6 +12140,7 @@ type StyleKeySpacing = []|[({
12120
12140
  mode?: ("strict" | "minimum")
12121
12141
  beforeColon?: boolean
12122
12142
  afterColon?: boolean
12143
+ ignoredNodes?: ("ObjectExpression" | "ObjectPattern" | "ImportDeclaration" | "ExportNamedDeclaration" | "ExportAllDeclaration" | "TSTypeLiteral" | "TSInterfaceBody" | "ClassBody")[]
12123
12144
  } | {
12124
12145
  singleLine?: {
12125
12146
  mode?: ("strict" | "minimum")
@@ -12635,6 +12656,7 @@ type StyleNoExtraParens = ([]|["functions"] | []|["all"]|["all", {
12635
12656
  enforceForNewInMemberExpressions?: boolean
12636
12657
  enforceForFunctionPrototypeMethods?: boolean
12637
12658
  allowParensAfterCommentPattern?: string
12659
+ nestedConditionalExpressions?: boolean
12638
12660
  }])
12639
12661
  // ----- style/no-mixed-operators -----
12640
12662
  type StyleNoMixedOperators = []|[{
@@ -12732,14 +12754,14 @@ type StyleOperatorLinebreak = []|[(("after" | "before" | "none") | null)]|[(("af
12732
12754
  }
12733
12755
  }]
12734
12756
  // ----- style/padded-blocks -----
12735
- type StylePaddedBlocks = []|[(("always" | "never") | {
12736
- blocks?: ("always" | "never")
12737
- switches?: ("always" | "never")
12738
- classes?: ("always" | "never")
12739
- })]|[(("always" | "never") | {
12740
- blocks?: ("always" | "never")
12741
- switches?: ("always" | "never")
12742
- classes?: ("always" | "never")
12757
+ type StylePaddedBlocks = []|[(("always" | "never" | "start" | "end") | {
12758
+ blocks?: ("always" | "never" | "start" | "end")
12759
+ switches?: ("always" | "never" | "start" | "end")
12760
+ classes?: ("always" | "never" | "start" | "end")
12761
+ })]|[(("always" | "never" | "start" | "end") | {
12762
+ blocks?: ("always" | "never" | "start" | "end")
12763
+ switches?: ("always" | "never" | "start" | "end")
12764
+ classes?: ("always" | "never" | "start" | "end")
12743
12765
  }), {
12744
12766
  allowSingleLineBlocks?: boolean
12745
12767
  }]
@@ -14882,6 +14904,7 @@ type VueKeySpacing = []|[({
14882
14904
  mode?: ("strict" | "minimum")
14883
14905
  beforeColon?: boolean
14884
14906
  afterColon?: boolean
14907
+ ignoredNodes?: ("ObjectExpression" | "ObjectPattern" | "ImportDeclaration" | "ExportNamedDeclaration" | "ExportAllDeclaration" | "TSTypeLiteral" | "TSInterfaceBody" | "ClassBody")[]
14885
14908
  } | {
14886
14909
  singleLine?: {
14887
14910
  mode?: ("strict" | "minimum")
@@ -15408,6 +15431,7 @@ type VueNoExtraParens = ([]|["functions"] | []|["all"]|["all", {
15408
15431
  enforceForNewInMemberExpressions?: boolean
15409
15432
  enforceForFunctionPrototypeMethods?: boolean
15410
15433
  allowParensAfterCommentPattern?: string
15434
+ nestedConditionalExpressions?: boolean
15411
15435
  }])
15412
15436
  // ----- vue/no-irregular-whitespace -----
15413
15437
  type VueNoIrregularWhitespace = []|[{
package/dist/index.js CHANGED
@@ -1191,6 +1191,12 @@ var RemixPackages = [
1191
1191
  "@remix-run/serve",
1192
1192
  "@remix-run/dev"
1193
1193
  ];
1194
+ var ReactRouterPackages = [
1195
+ "@react-router/node",
1196
+ "@react-router/react",
1197
+ "@react-router/serve",
1198
+ "@react-router/dev"
1199
+ ];
1194
1200
  var NextJsPackages = [
1195
1201
  "next"
1196
1202
  ];
@@ -1225,6 +1231,7 @@ async function react(options = {}) {
1225
1231
  ]);
1226
1232
  const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some((i) => isPackageExists3(i));
1227
1233
  const isUsingRemix = RemixPackages.some((i) => isPackageExists3(i));
1234
+ const isUsingReactRouter = ReactRouterPackages.some((i) => isPackageExists3(i));
1228
1235
  const isUsingNext = NextJsPackages.some((i) => isPackageExists3(i));
1229
1236
  const plugins = pluginReact.configs.all.plugins;
1230
1237
  return [
@@ -1236,7 +1243,8 @@ async function react(options = {}) {
1236
1243
  "react-hooks": pluginReactHooks,
1237
1244
  "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1238
1245
  "react-naming-convention": plugins["@eslint-react/naming-convention"],
1239
- "react-refresh": pluginReactRefresh
1246
+ "react-refresh": pluginReactRefresh,
1247
+ "react-web-api": plugins["@eslint-react/web-api"]
1240
1248
  }
1241
1249
  },
1242
1250
  {
@@ -1287,7 +1295,7 @@ async function react(options = {}) {
1287
1295
  "viewport",
1288
1296
  "generateViewport"
1289
1297
  ] : [],
1290
- ...isUsingRemix ? [
1298
+ ...isUsingRemix || isUsingReactRouter ? [
1291
1299
  "meta",
1292
1300
  "links",
1293
1301
  "headers",
@@ -1297,6 +1305,11 @@ async function react(options = {}) {
1297
1305
  ]
1298
1306
  }
1299
1307
  ],
1308
+ // recommended rules from @eslint-react/web-api
1309
+ "react-web-api/no-leaked-event-listener": "warn",
1310
+ "react-web-api/no-leaked-interval": "warn",
1311
+ "react-web-api/no-leaked-resize-observer": "warn",
1312
+ "react-web-api/no-leaked-timeout": "warn",
1300
1313
  // recommended rules from @eslint-react
1301
1314
  "react/ensure-forward-ref-using-ref": "warn",
1302
1315
  "react/jsx-no-duplicate-props": "warn",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@antfu/eslint-config",
3
3
  "type": "module",
4
- "version": "3.12.2",
4
+ "version": "3.14.0",
5
5
  "description": "Anthony's ESLint config",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
7
7
  "license": "MIT",
@@ -81,19 +81,19 @@
81
81
  }
82
82
  },
83
83
  "dependencies": {
84
- "@antfu/install-pkg": "^0.5.0",
85
- "@clack/prompts": "^0.9.0",
84
+ "@antfu/install-pkg": "^1.0.0",
85
+ "@clack/prompts": "^0.9.1",
86
86
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
87
87
  "@eslint/markdown": "^6.2.1",
88
- "@stylistic/eslint-plugin": "^2.12.1",
88
+ "@stylistic/eslint-plugin": "^2.13.0",
89
89
  "@typescript-eslint/eslint-plugin": "^8.19.1",
90
90
  "@typescript-eslint/parser": "^8.19.1",
91
- "@vitest/eslint-plugin": "^1.1.24",
92
- "eslint-config-flat-gitignore": "^0.3.0",
93
- "eslint-flat-config-utils": "^0.4.0",
94
- "eslint-merge-processors": "^0.1.0",
91
+ "@vitest/eslint-plugin": "^1.1.25",
92
+ "eslint-config-flat-gitignore": "^1.0.0",
93
+ "eslint-flat-config-utils": "^1.0.0",
94
+ "eslint-merge-processors": "^1.0.0",
95
95
  "eslint-plugin-antfu": "^2.7.0",
96
- "eslint-plugin-command": "^0.2.7",
96
+ "eslint-plugin-command": "^2.1.0",
97
97
  "eslint-plugin-import-x": "^4.6.1",
98
98
  "eslint-plugin-jsdoc": "^50.6.1",
99
99
  "eslint-plugin-jsonc": "^2.18.2",
@@ -106,10 +106,10 @@
106
106
  "eslint-plugin-unused-imports": "^4.1.4",
107
107
  "eslint-plugin-vue": "^9.32.0",
108
108
  "eslint-plugin-yml": "^1.16.0",
109
- "eslint-processor-vue-blocks": "^0.1.2",
109
+ "eslint-processor-vue-blocks": "^1.0.0",
110
110
  "globals": "^15.14.0",
111
111
  "jsonc-eslint-parser": "^2.4.0",
112
- "local-pkg": "^0.5.1",
112
+ "local-pkg": "^1.0.0",
113
113
  "parse-gitignore": "^2.0.0",
114
114
  "picocolors": "^1.1.1",
115
115
  "toml-eslint-parser": "^0.10.0",
@@ -118,27 +118,26 @@
118
118
  "yargs": "^17.7.2"
119
119
  },
120
120
  "devDependencies": {
121
- "@antfu/ni": "^0.23.2",
121
+ "@antfu/ni": "^23.2.0",
122
122
  "@eslint-react/eslint-plugin": "^1.23.2",
123
123
  "@eslint/config-inspector": "^0.7.1",
124
124
  "@prettier/plugin-xml": "^3.4.1",
125
- "@stylistic/eslint-plugin-migrate": "^2.12.1",
125
+ "@stylistic/eslint-plugin-migrate": "^2.13.0",
126
126
  "@types/fs-extra": "^11.0.4",
127
127
  "@types/node": "^22.10.5",
128
128
  "@types/prompts": "^2.4.9",
129
129
  "@types/yargs": "^17.0.33",
130
- "@unocss/eslint-plugin": "^0.65.3",
130
+ "@unocss/eslint-plugin": "^65.4.0",
131
131
  "astro-eslint-parser": "^1.1.0",
132
- "bumpp": "^9.9.3",
133
- "eslint": "^9.17.0",
132
+ "bumpp": "^9.10.0",
133
+ "eslint": "^9.18.0",
134
134
  "eslint-plugin-astro": "^1.3.1",
135
- "eslint-plugin-format": "^1.0.0",
135
+ "eslint-plugin-format": "^1.0.1",
136
136
  "eslint-plugin-react-hooks": "^5.1.0",
137
- "eslint-plugin-react-refresh": "^0.4.16",
137
+ "eslint-plugin-react-refresh": "^0.4.18",
138
138
  "eslint-plugin-solid": "^0.14.5",
139
139
  "eslint-plugin-svelte": "^2.46.1",
140
- "eslint-typegen": "^0.3.2",
141
- "esno": "^4.8.0",
140
+ "eslint-typegen": "^1.0.0",
142
141
  "execa": "^9.5.2",
143
142
  "fast-glob": "^3.3.3",
144
143
  "fs-extra": "^11.2.0",
@@ -148,26 +147,26 @@
148
147
  "prettier-plugin-slidev": "^1.0.5",
149
148
  "rimraf": "^6.0.1",
150
149
  "simple-git-hooks": "^2.11.1",
151
- "svelte": "^5.16.6",
150
+ "svelte": "^5.17.3",
152
151
  "svelte-eslint-parser": "^0.43.0",
153
152
  "tsup": "^8.3.5",
154
153
  "tsx": "^4.19.2",
155
- "typescript": "^5.7.2",
154
+ "typescript": "^5.7.3",
156
155
  "vitest": "^2.1.8",
157
156
  "vue": "^3.5.13",
158
- "@antfu/eslint-config": "3.12.2"
157
+ "@antfu/eslint-config": "3.14.0"
159
158
  },
160
159
  "resolutions": {
161
160
  "@eslint-community/eslint-utils": "^4.4.1",
162
161
  "@typescript-eslint/utils": "^8.19.1",
163
- "eslint": "^9.17.0",
162
+ "eslint": "^9.18.0",
164
163
  "tsx": "^4.19.2"
165
164
  },
166
165
  "simple-git-hooks": {
167
166
  "pre-commit": "npx lint-staged"
168
167
  },
169
168
  "lint-staged": {
170
- "*": "eslint --flag unstable_ts_config --fix"
169
+ "*": "eslint --fix"
171
170
  },
172
171
  "scripts": {
173
172
  "build": "nr typegen && tsup --format esm,cjs --clean --dts",
@@ -175,8 +174,8 @@
175
174
  "dev": "npx @eslint/config-inspector --config eslint.config.ts",
176
175
  "build:inspector": "pnpm build && npx @eslint/config-inspector build",
177
176
  "watch": "tsup --format esm,cjs --watch",
178
- "lint": "eslint --flag unstable_ts_config .",
179
- "typegen": "esno scripts/typegen.ts",
177
+ "lint": "eslint .",
178
+ "typegen": "tsx scripts/typegen.ts",
180
179
  "release": "bumpp && pnpm publish",
181
180
  "test": "vitest",
182
181
  "typecheck": "tsc --noEmit"