@antfu/eslint-config 6.7.1 → 6.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/README.md CHANGED
@@ -868,7 +868,7 @@ Well, you can still use Prettier to format files that are not supported well by
868
868
 
869
869
  ### oxlint?
870
870
 
871
- We do have a plan to integrate [oxlint](https://github.com/Asiashield/oxlint) in someway to speed up the linting process. However there are still some blocks we are waiting for. Track the progress [in this issue: **Oxlint Integration Plan**](https://github.com/antfu/eslint-config/issues/767).
871
+ We do have a plan to integrate [oxlint](https://github.com/oxc-project/oxc) in someway to speed up the linting process. However there are still some blocks we are waiting for. Track the progress [in this issue: **Oxlint Integration Plan**](https://github.com/antfu/eslint-config/issues/767).
872
872
 
873
873
  ### dprint?
874
874
 
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import process from "node:process";
2
- import fs from "node:fs/promises";
3
- import fs$1 from "node:fs";
2
+ import fsPromises from "node:fs/promises";
3
+ import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import * as p from "@clack/prompts";
6
6
  import c, { green } from "ansis";
@@ -9,7 +9,7 @@ import parse from "parse-gitignore";
9
9
  import { execSync } from "node:child_process";
10
10
 
11
11
  //#region package.json
12
- var version = "6.7.1";
12
+ var version = "6.7.2";
13
13
 
14
14
  //#endregion
15
15
  //#region src/cli/constants.ts
@@ -143,13 +143,13 @@ async function updateEslintFiles(result) {
143
143
  const cwd = process.cwd();
144
144
  const pathESLintIgnore = path.join(cwd, ".eslintignore");
145
145
  const pathPackageJSON = path.join(cwd, "package.json");
146
- const pkgContent = await fs.readFile(pathPackageJSON, "utf-8");
146
+ const pkgContent = await fsPromises.readFile(pathPackageJSON, "utf-8");
147
147
  const configFileName = JSON.parse(pkgContent).type === "module" ? "eslint.config.js" : "eslint.config.mjs";
148
148
  const pathFlatConfig = path.join(cwd, configFileName);
149
149
  const eslintIgnores = [];
150
- if (fs$1.existsSync(pathESLintIgnore)) {
150
+ if (fs.existsSync(pathESLintIgnore)) {
151
151
  p.log.step(c.cyan`Migrating existing .eslintignore`);
152
- const globs = parse(await fs.readFile(pathESLintIgnore, "utf-8")).globs();
152
+ const globs = parse(await fsPromises.readFile(pathESLintIgnore, "utf-8")).globs();
153
153
  for (const glob of globs) if (glob.type === "ignore") eslintIgnores.push(...glob.patterns);
154
154
  else if (glob.type === "unignore") eslintIgnores.push(...glob.patterns.map((pattern) => `!${pattern}`));
155
155
  }
@@ -159,9 +159,9 @@ async function updateEslintFiles(result) {
159
159
  if (result.extra.includes("unocss")) configLines.push(`unocss: true,`);
160
160
  for (const framework of result.frameworks) configLines.push(`${framework}: true,`);
161
161
  const eslintConfigContent = getEslintConfigContent(configLines.map((i) => ` ${i}`).join("\n"), []);
162
- await fs.writeFile(pathFlatConfig, eslintConfigContent);
162
+ await fsPromises.writeFile(pathFlatConfig, eslintConfigContent);
163
163
  p.log.success(c.green`Created ${configFileName}`);
164
- const files = fs$1.readdirSync(cwd);
164
+ const files = fs.readdirSync(cwd);
165
165
  const legacyConfig = [];
166
166
  files.forEach((file) => {
167
167
  if (/eslint|prettier/.test(file) && !/eslint\.config\./.test(file)) legacyConfig.push(file);
@@ -173,14 +173,14 @@ async function updateEslintFiles(result) {
173
173
  //#region src/cli/constants-generated.ts
174
174
  const versionsMap = {
175
175
  "@eslint-react/eslint-plugin": "^2.3.13",
176
- "@next/eslint-plugin-next": "^16.0.10",
176
+ "@next/eslint-plugin-next": "^16.1.0",
177
177
  "@unocss/eslint-plugin": "^66.5.10",
178
178
  "astro-eslint-parser": "^1.2.2",
179
179
  "eslint": "^9.39.2",
180
180
  "eslint-plugin-astro": "^1.5.0",
181
181
  "eslint-plugin-format": "^1.1.0",
182
182
  "eslint-plugin-react-hooks": "^7.0.1",
183
- "eslint-plugin-react-refresh": "^0.4.24",
183
+ "eslint-plugin-react-refresh": "^0.4.26",
184
184
  "eslint-plugin-solid": "^0.14.5",
185
185
  "eslint-plugin-svelte": "^3.13.1",
186
186
  "prettier-plugin-astro": "^0.14.1",
@@ -194,7 +194,7 @@ async function updatePackageJson(result) {
194
194
  const cwd = process.cwd();
195
195
  const pathPackageJSON = path.join(cwd, "package.json");
196
196
  p.log.step(c.cyan`Bumping @antfu/eslint-config to v${version}`);
197
- const pkgContent = await fs.readFile(pathPackageJSON, "utf-8");
197
+ const pkgContent = await fsPromises.readFile(pathPackageJSON, "utf-8");
198
198
  const pkg = JSON.parse(pkgContent);
199
199
  pkg.devDependencies ??= {};
200
200
  pkg.devDependencies["@antfu/eslint-config"] = `^${version}`;
@@ -225,7 +225,7 @@ async function updatePackageJson(result) {
225
225
  });
226
226
  }
227
227
  if (addedPackages.length) p.note(c.dim(addedPackages.join(", ")), "Added packages");
228
- await fs.writeFile(pathPackageJSON, JSON.stringify(pkg, null, 2));
228
+ await fsPromises.writeFile(pathPackageJSON, JSON.stringify(pkg, null, 2));
229
229
  p.log.success(c.green`Changes wrote to package.json`);
230
230
  }
231
231
 
@@ -236,16 +236,16 @@ async function updateVscodeSettings(result) {
236
236
  if (!result.updateVscodeSettings) return;
237
237
  const dotVscodePath = path.join(cwd, ".vscode");
238
238
  const settingsPath = path.join(dotVscodePath, "settings.json");
239
- if (!fs$1.existsSync(dotVscodePath)) await fs.mkdir(dotVscodePath, { recursive: true });
240
- if (!fs$1.existsSync(settingsPath)) {
241
- await fs.writeFile(settingsPath, `{${vscodeSettingsString}}\n`, "utf-8");
239
+ if (!fs.existsSync(dotVscodePath)) await fsPromises.mkdir(dotVscodePath, { recursive: true });
240
+ if (!fs.existsSync(settingsPath)) {
241
+ await fsPromises.writeFile(settingsPath, `{${vscodeSettingsString}}\n`, "utf-8");
242
242
  p.log.success(green`Created .vscode/settings.json`);
243
243
  } else {
244
- let settingsContent = await fs.readFile(settingsPath, "utf8");
244
+ let settingsContent = await fsPromises.readFile(settingsPath, "utf8");
245
245
  settingsContent = settingsContent.trim().replace(/\s*\}$/, "");
246
246
  settingsContent += settingsContent.endsWith(",") || settingsContent.endsWith("{") ? "" : ",";
247
247
  settingsContent += `${vscodeSettingsString}}\n`;
248
- await fs.writeFile(settingsPath, settingsContent, "utf-8");
248
+ await fsPromises.writeFile(settingsPath, settingsContent, "utf-8");
249
249
  p.log.success(green`Updated .vscode/settings.json`);
250
250
  }
251
251
  }
@@ -256,7 +256,7 @@ async function run(options = {}) {
256
256
  const argSkipPrompt = !!process.env.SKIP_PROMPT || options.yes;
257
257
  const argTemplate = options.frameworks?.map((m) => m?.trim()).filter(Boolean);
258
258
  const argExtra = options.extra?.map((m) => m?.trim()).filter(Boolean);
259
- if (fs$1.existsSync(path.join(process.cwd(), "eslint.config.js"))) {
259
+ if (fs.existsSync(path.join(process.cwd(), "eslint.config.js"))) {
260
260
  p.log.warn(c.yellow`eslint.config.js already exists, migration wizard exited.`);
261
261
  return process.exit(1);
262
262
  }
package/dist/index.d.mts CHANGED
@@ -682,6 +682,11 @@ interface RuleOptions {
682
682
  * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/consistent-type-specifier-style/README.md
683
683
  */
684
684
  'import/consistent-type-specifier-style'?: Linter.RuleEntry<ImportConsistentTypeSpecifierStyle>;
685
+ /**
686
+ * Ensure all exports appear after other statements.
687
+ * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/exports-last/README.md
688
+ */
689
+ 'import/exports-last'?: Linter.RuleEntry<[]>;
685
690
  /**
686
691
  * Ensure all imports appear before other statements.
687
692
  * @see https://github.com/9romise/eslint-plugin-import-lite/blob/main/src/rules/first/README.md
@@ -1779,7 +1784,7 @@ interface RuleOptions {
1779
1784
  */
1780
1785
  'next/inline-script-id'?: Linter.RuleEntry<[]>;
1781
1786
  /**
1782
- * Prefer `next/script` component when using the inline script for Google Analytics.
1787
+ * Prefer `@next/third-parties/google` when using the inline script for Google Analytics and Tag Manager.
1783
1788
  * @see https://nextjs.org/docs/messages/next-script-for-ga
1784
1789
  */
1785
1790
  'next/next-script-for-ga'?: Linter.RuleEntry<[]>;
@@ -5412,6 +5417,11 @@ interface RuleOptions {
5412
5417
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md
5413
5418
  */
5414
5419
  'test/no-test-return-statement'?: Linter.RuleEntry<[]>;
5420
+ /**
5421
+ * Disallow unnecessary async function wrapper for expected promises
5422
+ * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-unneeded-async-expect-function.md
5423
+ */
5424
+ 'test/no-unneeded-async-expect-function'?: Linter.RuleEntry<[]>;
5415
5425
  /**
5416
5426
  * Enforce padding around `afterAll` blocks
5417
5427
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-all-blocks.md
@@ -6231,6 +6241,11 @@ interface RuleOptions {
6231
6241
  * @see https://typescript-eslint.io/rules/no-useless-constructor
6232
6242
  */
6233
6243
  'ts/no-useless-constructor'?: Linter.RuleEntry<[]>;
6244
+ /**
6245
+ * Disallow default values that will never be used
6246
+ * @see https://typescript-eslint.io/rules/no-useless-default-assignment
6247
+ */
6248
+ 'ts/no-useless-default-assignment'?: Linter.RuleEntry<[]>;
6234
6249
  /**
6235
6250
  * Disallow empty exports that don't change anything in a module file
6236
6251
  * @see https://typescript-eslint.io/rules/no-useless-empty-export
package/dist/index.mjs CHANGED
@@ -1,8 +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
+ import fsPromises from "node:fs/promises";
4
4
  import { fileURLToPath } from "node:url";
5
- import fs$1 from "node:fs";
5
+ import fs from "node:fs";
6
6
  import path from "node:path";
7
7
  import { isPackageExists } from "local-pkg";
8
8
  import createCommand from "eslint-plugin-command/config";
@@ -27,7 +27,7 @@ async function findUp(name, { cwd = process.cwd(), type = "file", stopAt } = {})
27
27
  while (directory) {
28
28
  const filePath = isAbsoluteName ? name : path.join(directory, name);
29
29
  try {
30
- const stats = await fs.stat(filePath);
30
+ const stats = await fsPromises.stat(filePath);
31
31
  if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) return filePath;
32
32
  } catch {}
33
33
  if (directory === stopAt || directory === root) break;
@@ -42,7 +42,7 @@ function findUpSync(name, { cwd = process.cwd(), type = "file", stopAt } = {}) {
42
42
  while (directory) {
43
43
  const filePath = isAbsoluteName ? name : path.join(directory, name);
44
44
  try {
45
- const stats = fs$1.statSync(filePath, { throwIfNoEntry: false });
45
+ const stats = fs.statSync(filePath, { throwIfNoEntry: false });
46
46
  if (type === "file" && stats?.isFile() || type === "directory" && stats?.isDirectory()) return filePath;
47
47
  } catch {}
48
48
  if (directory === stopAt || directory === root) break;
@@ -1143,7 +1143,7 @@ async function perfectionist() {
1143
1143
  async function detectCatalogUsage() {
1144
1144
  const workspaceFile = await findUp("pnpm-workspace.yaml");
1145
1145
  if (!workspaceFile) return false;
1146
- const yaml$1 = await fs.readFile(workspaceFile, "utf-8");
1146
+ const yaml$1 = await fsPromises.readFile(workspaceFile, "utf-8");
1147
1147
  return yaml$1.includes("catalog:") || yaml$1.includes("catalogs:");
1148
1148
  }
1149
1149
  async function pnpm(options) {
@@ -1161,7 +1161,10 @@ async function pnpm(options) {
1161
1161
  name: "antfu/pnpm/package-json",
1162
1162
  plugins: { pnpm: pluginPnpm },
1163
1163
  rules: {
1164
- ...catalogs ? { "pnpm/json-enforce-catalog": ["error", { autofix: !isInEditor }] } : {},
1164
+ ...catalogs ? { "pnpm/json-enforce-catalog": ["error", {
1165
+ autofix: !isInEditor,
1166
+ ignores: ["@types/vscode"]
1167
+ }] } : {},
1165
1168
  "pnpm/json-prefer-workspace-settings": ["error", { autofix: !isInEditor }],
1166
1169
  "pnpm/json-valid-catalog": ["error", { autofix: !isInEditor }]
1167
1170
  }
@@ -1321,8 +1324,10 @@ async function react(options = {}) {
1321
1324
  },
1322
1325
  name: "antfu/react/rules",
1323
1326
  rules: {
1327
+ "react/jsx-key-before-spread": "warn",
1324
1328
  "react/jsx-no-comment-textnodes": "warn",
1325
1329
  "react/jsx-no-duplicate-props": "warn",
1330
+ "react/jsx-uses-react": "warn",
1326
1331
  "react/jsx-uses-vars": "warn",
1327
1332
  "react/no-access-state-in-setstate": "error",
1328
1333
  "react/no-array-index-key": "warn",
@@ -1339,11 +1344,12 @@ async function react(options = {}) {
1339
1344
  "react/no-create-ref": "error",
1340
1345
  "react/no-default-props": "error",
1341
1346
  "react/no-direct-mutation-state": "error",
1342
- "react/no-duplicate-key": "warn",
1347
+ "react/no-duplicate-key": "error",
1343
1348
  "react/no-forward-ref": "warn",
1344
1349
  "react/no-implicit-key": "warn",
1345
1350
  "react/no-missing-key": "error",
1346
1351
  "react/no-nested-component-definitions": "error",
1352
+ "react/no-nested-lazy-component-declarations": "error",
1347
1353
  "react/no-prop-types": "error",
1348
1354
  "react/no-redundant-should-component-update": "error",
1349
1355
  "react/no-set-state-in-component-did-mount": "warn",
@@ -1354,10 +1360,6 @@ async function react(options = {}) {
1354
1360
  "react/no-unsafe-component-will-mount": "warn",
1355
1361
  "react/no-unsafe-component-will-receive-props": "warn",
1356
1362
  "react/no-unsafe-component-will-update": "warn",
1357
- "react/no-unstable-context-value": "warn",
1358
- "react/no-unstable-default-props": "warn",
1359
- "react/no-unused-class-component-members": "warn",
1360
- "react/no-unused-state": "warn",
1361
1363
  "react/no-use-context": "warn",
1362
1364
  "react/no-useless-forward-ref": "warn",
1363
1365
  "react/prefer-use-state-lazy-initialization": "warn",
@@ -1366,14 +1368,11 @@ async function react(options = {}) {
1366
1368
  "react-dom/no-find-dom-node": "error",
1367
1369
  "react-dom/no-flush-sync": "error",
1368
1370
  "react-dom/no-hydrate": "error",
1369
- "react-dom/no-missing-button-type": "warn",
1370
- "react-dom/no-missing-iframe-sandbox": "warn",
1371
1371
  "react-dom/no-namespace": "error",
1372
1372
  "react-dom/no-render": "error",
1373
1373
  "react-dom/no-render-return-value": "error",
1374
1374
  "react-dom/no-script-url": "warn",
1375
1375
  "react-dom/no-unsafe-iframe-sandbox": "warn",
1376
- "react-dom/no-unsafe-target-blank": "warn",
1377
1376
  "react-dom/no-use-form-state": "error",
1378
1377
  "react-dom/no-void-elements-with-children": "error",
1379
1378
  "react-hooks/rules-of-hooks": "error",
@@ -2030,7 +2029,7 @@ async function typescript(options = {}) {
2030
2029
  }] : [],
2031
2030
  ...erasableOnly ? [{
2032
2031
  name: "antfu/typescript/erasable-syntax-only",
2033
- plugins: { "erasable-syntax-only": await interopDefault(import("./lib-CJKU7XKI.mjs")) },
2032
+ plugins: { "erasable-syntax-only": await interopDefault(import("./lib-Bxfuo2Ed.mjs")) },
2034
2033
  rules: {
2035
2034
  "erasable-syntax-only/enums": "error",
2036
2035
  "erasable-syntax-only/import-aliases": "error",