@antfu/eslint-config 9.4.1 → 9.5.1

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
@@ -336,36 +336,38 @@ And that's it! Or you can configure each integration individually, for example:
336
336
  import antfu from '@antfu/eslint-config'
337
337
 
338
338
  export default antfu({
339
- // Type of the project. 'lib' for libraries, the default is 'app'
339
+ /** Type of the project. 'lib' for libraries, the default is 'app' */
340
340
  type: 'lib',
341
341
 
342
- // `.eslintignore` is no longer supported in Flat config, use `ignores` instead
343
- // The `ignores` option in the option (first argument) is specifically treated to always be global ignores
344
- // And will **extend** the config's default ignores, not override them
345
- // You can also pass a function to modify the default ignores
342
+ /**
343
+ * `.eslintignore` is no longer supported in Flat config, use `ignores` instead
344
+ * The `ignores` option in the option (first argument) is specifically treated to always be global ignores
345
+ * And will **extend** the config's default ignores, not override them
346
+ * You can also pass a function to modify the default ignores
347
+ */
346
348
  ignores: [
347
349
  '**/fixtures',
348
350
  // ...globs
349
351
  ],
350
352
 
351
- // Parse the `.gitignore` file to get the ignores, on by default
353
+ /** Parse the `.gitignore` file to get the ignores, on by default */
352
354
  gitignore: true,
353
355
 
354
356
  // Enable stylistic formatting rules
355
357
  // stylistic: true,
356
358
 
357
- // Or customize the stylistic rules
359
+ /** Or customize the stylistic rules */
358
360
  stylistic: {
359
361
  indent: 2, // 4, or 'tab'
360
362
  quotes: 'single', // or 'double'
361
363
  braceStyle: 'stroustrup', // '1tbs', or 'allman'
362
364
  },
363
365
 
364
- // TypeScript and Vue are autodetected, you can also explicitly enable them:
366
+ /** TypeScript and Vue are autodetected, you can also explicitly enable them: */
365
367
  typescript: true,
366
368
  vue: true,
367
369
 
368
- // Disable jsonc and yaml support
370
+ /** Disable jsonc and yaml support */
369
371
  jsonc: false,
370
372
  yaml: false,
371
373
  })
@@ -514,14 +516,14 @@ export default antfu(
514
516
  typescript: true
515
517
  },
516
518
  {
517
- // Remember to specify the file glob here, otherwise it might cause the vue plugin to handle non-vue files
519
+ /** Remember to specify the file glob here, otherwise it might cause the vue plugin to handle non-vue files */
518
520
  files: ['**/*.vue'],
519
521
  rules: {
520
522
  'vue/operator-linebreak': ['error', 'before'],
521
523
  },
522
524
  },
523
525
  {
524
- // Without `files`, they are general rules for all files (Markdown excluded see note below)
526
+ /** Without `files`, they are general rules for all files (Markdown excluded, see note below) */
525
527
  rules: {
526
528
  'style/semi': ['error', 'never'],
527
529
  },
@@ -548,7 +550,7 @@ export default antfu({
548
550
  overrides: {
549
551
  'ts/consistent-type-definitions': ['error', 'interface'],
550
552
  },
551
- // type aware rules overrides should write here
553
+ /** type aware rules overrides should write here */
552
554
  overridesTypeAware: {
553
555
  'ts/no-unsafe-assignment': ['warn'],
554
556
  }
@@ -814,6 +816,52 @@ Running `npx eslint` should prompt you to install the required dependencies, oth
814
816
  npm i -D @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/template-parser
815
817
  ```
816
818
 
819
+ #### Anti-Slop
820
+
821
+ > [!WARNING]
822
+ > Experimental: the enabled rule set is maintained in-house and may change in any release without following semver.
823
+
824
+ To guard against low-value code patterns commonly introduced by AI agents, you can explicitly turn on the anti-slop rules:
825
+
826
+ ```js
827
+ // eslint.config.js
828
+ import antfu from '@antfu/eslint-config'
829
+
830
+ export default antfu({
831
+ antislop: true,
832
+ })
833
+ ```
834
+
835
+ This enables [`eslint-plugin-slop`](https://github.com/antfu/eslint-plugin-slop) and a curated, in-house maintained subset of [`eslint-plugin-sonarjs`](https://github.com/SonarSource/SonarJS) rules focusing on redundant and duplicated code. It also disallows explicit `any` when TypeScript is enabled (inspired by [this writeup on keeping AI-authored code clean](https://zenn.dev/singularity/articles/clean-code-ci-for-ai-era)).
836
+
837
+ You can toggle each plugin and pass options to `eslint-plugin-slop`:
838
+
839
+ ```js
840
+ // eslint.config.js
841
+ import antfu from '@antfu/eslint-config'
842
+
843
+ export default antfu({
844
+ antislop: {
845
+ sonarjs: false,
846
+ /**
847
+ * an object enables `eslint-plugin-slop` and is forwarded to it
848
+ * via `settings.slop`, for example to only inspect recently changed code
849
+ */
850
+ slop: {
851
+ inspection: { mode: 'recent-changes', tracebackCommits: 5 },
852
+ },
853
+ },
854
+ })
855
+ ```
856
+
857
+ Running `npx eslint` should prompt you to install the required dependencies, otherwise, you can install them manually:
858
+
859
+ ```bash
860
+ npm i -D eslint-plugin-slop eslint-plugin-sonarjs
861
+ ```
862
+
863
+ Since linters only see one file at a time, we recommend pairing this option with [`jscpd`](https://github.com/kucherenko/jscpd) to detect copy-paste duplication across files, and [`knip`](https://knip.dev) to find unused files, dependencies, and exports.
864
+
817
865
  ### Optional Rules
818
866
 
819
867
  This config also provides some optional plugins/rules for extended usage.
package/dist/cli.mjs CHANGED
@@ -8,7 +8,7 @@ import { cac } from "cac";
8
8
  import parse from "parse-gitignore";
9
9
  import { execSync } from "node:child_process";
10
10
  //#region package.json
11
- var version = "9.4.1";
11
+ var version = "9.5.1";
12
12
  //#endregion
13
13
  //#region src/cli/constants.ts
14
14
  const vscodeSettingsString = `
@@ -188,21 +188,22 @@ async function updatePackageJson(result) {
188
188
  const pkgContent = await fsPromises.readFile(pathPackageJSON, "utf-8");
189
189
  const pkg = JSON.parse(pkgContent);
190
190
  pkg.devDependencies ??= {};
191
- pkg.devDependencies["@antfu/eslint-config"] = `^${version}`;
192
- pkg.devDependencies.eslint ??= versionsMap.eslint;
191
+ const devDependencies = pkg.devDependencies;
192
+ devDependencies["@antfu/eslint-config"] = `^${version}`;
193
+ devDependencies.eslint ??= versionsMap.eslint;
193
194
  const addedPackages = [];
194
195
  if (result.extra.length) result.extra.forEach((item) => {
195
196
  switch (item) {
196
197
  case "formatter":
197
198
  [...dependenciesMap.formatter, ...result.frameworks.includes("astro") ? dependenciesMap.formatterAstro : []].forEach((f) => {
198
199
  if (!f) return;
199
- pkg.devDependencies[f] = versionsMap[f];
200
+ devDependencies[f] = versionsMap[f];
200
201
  addedPackages.push(f);
201
202
  });
202
203
  break;
203
204
  case "unocss":
204
205
  dependenciesMap.unocss.forEach((f) => {
205
- pkg.devDependencies[f] = versionsMap[f];
206
+ devDependencies[f] = versionsMap[f];
206
207
  addedPackages.push(f);
207
208
  });
208
209
  break;
@@ -211,7 +212,7 @@ async function updatePackageJson(result) {
211
212
  for (const framework of result.frameworks) {
212
213
  const deps = dependenciesMap[framework];
213
214
  if (deps) deps.forEach((f) => {
214
- pkg.devDependencies[f] = versionsMap[f];
215
+ devDependencies[f] = versionsMap[f];
215
216
  addedPackages.push(f);
216
217
  });
217
218
  }
@@ -259,7 +260,7 @@ async function run(options = {}) {
259
260
  if (!argSkipPrompt) {
260
261
  result = await p.group({
261
262
  uncommittedConfirmed: () => {
262
- if (argSkipPrompt || isGitClean()) return Promise.resolve(true);
263
+ if (isGitClean()) return Promise.resolve(true);
263
264
  return p.confirm({
264
265
  initialValue: false,
265
266
  message: "There are uncommitted changes in the current repository, are you sure to continue?"