@will-stone/eslint-config 13.0.0 → 15.0.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.
Files changed (3) hide show
  1. package/README.md +13 -14
  2. package/dist/index.js +60 -22
  3. package/package.json +64 -38
package/README.md CHANGED
@@ -10,6 +10,19 @@ My personal [ESLint](https://eslint.org/) config.
10
10
  npm i -D eslint @will-stone/eslint-config
11
11
  ```
12
12
 
13
+ ### Optional Peer Dependencies
14
+
15
+ If you are using any of the following packages, you will also need to install
16
+ the corresponding plugin.
17
+
18
+ | Package | Plugin |
19
+ | ------------- | ----------------------------------------------- |
20
+ | `astro` | `astro-eslint-parser eslint-plugin-astro` |
21
+ | `jest` | `eslint-plugin-jest` |
22
+ | `react` | `eslint-plugin-react eslint-plugin-react-hooks` |
23
+ | `tailwindcss` | `eslint-plugin-tailwindcss` |
24
+ | `vitest` | `@vitest/eslint-plugin` |
25
+
13
26
  ### Create config file
14
27
 
15
28
  ```js
@@ -32,20 +45,6 @@ For example:
32
45
  }
33
46
  ```
34
47
 
35
- ### VS Code support (auto fix)
36
-
37
- Install
38
- [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint).
39
-
40
- Add the following settings to your `.vscode/settings.json`:
41
-
42
- ```jsonc
43
- {
44
- // Enable the ESlint flat config support
45
- "eslint.experimental.useFlatConfig": true,
46
- }
47
- ```
48
-
49
48
  ### Lint Staged
50
49
 
51
50
  If you would like to apply lint and auto-fix before every commit, you can add
package/dist/index.js CHANGED
@@ -1,22 +1,35 @@
1
1
  // src/configs/astro.ts
2
2
  import parserTypescript from "@typescript-eslint/parser";
3
- import parserAstro from "astro-eslint-parser";
4
- import pluginAstro from "eslint-plugin-astro";
3
+
4
+ // src/utils/interop-default.ts
5
+ async function interopDefault(m) {
6
+ const resolved = await m;
7
+ return resolved.default || resolved;
8
+ }
9
+
10
+ // src/configs/astro.ts
5
11
  async function astro(_options) {
12
+ const [pluginAstro, parserAstro] = await Promise.all([
13
+ interopDefault(import("eslint-plugin-astro")),
14
+ interopDefault(import("astro-eslint-parser"))
15
+ ]);
6
16
  return [
7
17
  {
8
18
  files: ["**/*.astro"],
9
19
  languageOptions: {
20
+ globals: pluginAstro.environments.astro.globals,
10
21
  parser: parserAstro,
11
22
  parserOptions: {
12
23
  extraFileExtensions: [".astro"],
13
24
  parser: parserTypescript
14
- }
25
+ },
26
+ sourceType: "module"
15
27
  },
16
28
  name: "will-stone/astro",
17
29
  plugins: {
18
30
  astro: pluginAstro
19
31
  },
32
+ processor: "astro/client-side-ts",
20
33
  rules: {
21
34
  // Astro passes Components to the view which this rule doesn't like.
22
35
  "no-useless-assignment": "off",
@@ -392,14 +405,12 @@ async function ignores() {
392
405
 
393
406
  // src/configs/imports.ts
394
407
  import * as pluginImport from "eslint-plugin-import-x";
395
- import pluginSimpleImport from "eslint-plugin-simple-import-sort";
396
408
  async function imports() {
397
409
  return [
398
410
  {
399
411
  name: "will-stone/imports",
400
412
  plugins: {
401
- "import-x": pluginImport,
402
- "simple-import-sort": pluginSimpleImport
413
+ "import-x": pluginImport
403
414
  },
404
415
  rules: {
405
416
  "import-x/consistent-type-specifier-style": [
@@ -413,8 +424,6 @@ async function imports() {
413
424
  "import-x/no-empty-named-blocks": "warn",
414
425
  "import-x/no-rename-default": "off",
415
426
  "import-x/prefer-default-export": "off",
416
- "simple-import-sort/exports": "warn",
417
- "simple-import-sort/imports": "warn",
418
427
  // The rest of the rules, off until required
419
428
  "import-x/default": "off",
420
429
  "import-x/dynamic-import-chunkname": "off",
@@ -451,7 +460,16 @@ async function imports() {
451
460
  "import-x/no-unused-modules": "off",
452
461
  "import-x/no-useless-path-segments": "off",
453
462
  "import-x/no-webpack-loader-syntax": "off",
454
- "import-x/order": "off",
463
+ "import-x/order": [
464
+ "warn",
465
+ {
466
+ alphabetize: {
467
+ caseInsensitive: true,
468
+ order: "asc"
469
+ },
470
+ "newlines-between": "always"
471
+ }
472
+ ],
455
473
  "import-x/unambiguous": "off"
456
474
  }
457
475
  }
@@ -459,9 +477,9 @@ async function imports() {
459
477
  }
460
478
 
461
479
  // src/configs/jest.ts
462
- import pluginJest from "eslint-plugin-jest";
463
480
  import globals2 from "globals";
464
481
  async function jest(_options) {
482
+ const pluginJest = await interopDefault(import("eslint-plugin-jest"));
465
483
  return [
466
484
  {
467
485
  files: ["**/__mocks__/**/*", "**/*.{spec,test}.{js,cjs,mjs,jsx,ts,tsx}"],
@@ -612,12 +630,14 @@ async function node() {
612
630
  }
613
631
 
614
632
  // src/configs/react.ts
615
- import { fixupPluginRules } from "@eslint/compat";
616
- import pluginJsxA11y from "eslint-plugin-jsx-a11y";
617
- import pluginReact from "eslint-plugin-react";
618
- import pluginReactHooks from "eslint-plugin-react-hooks";
619
633
  import globals4 from "globals";
620
634
  async function react(_options) {
635
+ const [pluginJsxA11y, pluginReact, pluginReactHooks] = await Promise.all([
636
+ // @ts-expect-error -- no types
637
+ interopDefault(import("eslint-plugin-jsx-a11y")),
638
+ interopDefault(import("eslint-plugin-react")),
639
+ interopDefault(import("eslint-plugin-react-hooks"))
640
+ ]);
621
641
  return [
622
642
  {
623
643
  files: ["**/*.{jsx,tsx}"],
@@ -632,9 +652,8 @@ async function react(_options) {
632
652
  name: "will-stone/react",
633
653
  plugins: {
634
654
  "jsx-a11y": pluginJsxA11y,
635
- // @ts-expect-error -- no idea why this is tripping.
636
655
  react: pluginReact,
637
- "react-hooks": fixupPluginRules(pluginReactHooks)
656
+ "react-hooks": pluginReactHooks
638
657
  },
639
658
  rules: {
640
659
  "jsx-a11y/alt-text": "error",
@@ -952,10 +971,12 @@ async function tailwind(rawOptions) {
952
971
  }
953
972
 
954
973
  // src/configs/typescript.ts
955
- import pluginTypescript from "@typescript-eslint/eslint-plugin";
956
- import * as parserTypescript2 from "@typescript-eslint/parser";
957
974
  async function typescript(rawOptions) {
958
975
  const options = !rawOptions || typeof rawOptions === "boolean" ? {} : rawOptions;
976
+ const [pluginTypescript, parserTypescript2] = await Promise.all([
977
+ interopDefault(import("@typescript-eslint/eslint-plugin")),
978
+ interopDefault(import("@typescript-eslint/parser"))
979
+ ]);
959
980
  return [
960
981
  {
961
982
  files: ["**/*.{ts,tsx,astro}"],
@@ -1061,6 +1082,7 @@ async function typescript(rawOptions) {
1061
1082
  "@typescript-eslint/no-implied-eval": "off",
1062
1083
  "@typescript-eslint/no-meaningless-void-operator": "off",
1063
1084
  "@typescript-eslint/no-misused-promises": "off",
1085
+ "@typescript-eslint/no-misused-spread": "off",
1064
1086
  "@typescript-eslint/no-mixed-enums": "off",
1065
1087
  "@typescript-eslint/no-redundant-type-constituents": "off",
1066
1088
  "@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
@@ -1206,6 +1228,8 @@ async function unicorn() {
1206
1228
  "no-nested-ternary": "off",
1207
1229
  "unicorn/better-regex": "warn",
1208
1230
  "unicorn/catch-error-name": "error",
1231
+ "unicorn/consistent-assert": "warn",
1232
+ "unicorn/consistent-date-clone": "warn",
1209
1233
  "unicorn/consistent-destructuring": "warn",
1210
1234
  "unicorn/consistent-empty-array-spread": "warn",
1211
1235
  "unicorn/consistent-existence-index-check": "warn",
@@ -1225,6 +1249,7 @@ async function unicorn() {
1225
1249
  "unicorn/import-style": "off",
1226
1250
  "unicorn/new-for-builtins": "warn",
1227
1251
  "unicorn/no-abusive-eslint-disable": "error",
1252
+ "unicorn/no-accessor-recursion": "error",
1228
1253
  "unicorn/no-anonymous-default-export": "error",
1229
1254
  "unicorn/no-array-callback-reference": "off",
1230
1255
  "unicorn/no-array-for-each": "warn",
@@ -1241,6 +1266,7 @@ async function unicorn() {
1241
1266
  "unicorn/no-for-loop": "warn",
1242
1267
  "unicorn/no-hex-escape": "warn",
1243
1268
  "unicorn/no-instanceof-array": "warn",
1269
+ "unicorn/no-instanceof-builtins": "warn",
1244
1270
  "unicorn/no-invalid-fetch-options": "error",
1245
1271
  "unicorn/no-invalid-remove-event-listener": "error",
1246
1272
  "unicorn/no-keyword-prefix": [
@@ -1255,6 +1281,7 @@ async function unicorn() {
1255
1281
  "unicorn/no-length-as-slice-end": "warn",
1256
1282
  "unicorn/no-lonely-if": "warn",
1257
1283
  "unicorn/no-magic-array-flat-depth": "error",
1284
+ "unicorn/no-named-default": "warn",
1258
1285
  "unicorn/no-negated-condition": "warn",
1259
1286
  "unicorn/no-negation-in-equality-check": "error",
1260
1287
  "unicorn/no-nested-ternary": "off",
@@ -1357,14 +1384,13 @@ async function unicorn() {
1357
1384
  }
1358
1385
 
1359
1386
  // src/configs/vitest.ts
1360
- import { fixupPluginRules as fixupPluginRules2 } from "@eslint/compat";
1361
- import pluginVitest from "eslint-plugin-vitest";
1362
1387
  async function vitest(_options) {
1388
+ const pluginVitest = await interopDefault(import("@vitest/eslint-plugin"));
1363
1389
  return [
1364
1390
  {
1365
1391
  files: ["**/*.{spec,test}.{js,cjs,mjs,jsx,ts,tsx}"],
1366
1392
  name: "will-stone/vitest",
1367
- plugins: { vitest: fixupPluginRules2(pluginVitest) },
1393
+ plugins: { vitest: pluginVitest },
1368
1394
  rules: {
1369
1395
  "vitest/consistent-test-filename": "warn",
1370
1396
  "vitest/consistent-test-it": "warn",
@@ -1414,17 +1440,29 @@ async function vitest(_options) {
1414
1440
  "vitest/no-import-node-test": "warn",
1415
1441
  // Every test must have an expect, this is covered by expect-expect rule.
1416
1442
  "vitest/prefer-expect-assertions": "off",
1443
+ "vitest/prefer-strict-boolean-matchers": "warn",
1417
1444
  // These two could be dangerous as you may actually want to ensure that
1418
1445
  // something is exactly `false` or `true`, and not something that
1419
1446
  // equates to that if run through Boolean().
1420
1447
  "vitest/prefer-to-be-falsy": "off",
1421
1448
  "vitest/prefer-to-be-truthy": "off",
1422
1449
  "vitest/require-local-test-context-for-concurrent-snapshots": "error",
1450
+ "vitest/require-mock-type-parameters": "warn",
1423
1451
  // No need to nest everything in useless describe blocks:
1424
1452
  "vitest/require-top-level-describe": "off",
1425
1453
  "vitest/valid-describe-callback": "error",
1426
1454
  "vitest/valid-expect": "error",
1427
- "vitest/valid-title": "warn"
1455
+ "vitest/valid-expect-in-promise": "error",
1456
+ "vitest/valid-title": "warn",
1457
+ "vitest/prefer-vi-mocked": "warn",
1458
+ "vitest/padding-around-after-all-blocks": "warn",
1459
+ "vitest/padding-around-after-each-blocks": "warn",
1460
+ "vitest/padding-around-all": "warn",
1461
+ "vitest/padding-around-before-all-blocks": "warn",
1462
+ "vitest/padding-around-before-each-blocks": "warn",
1463
+ "vitest/padding-around-describe-blocks": "warn",
1464
+ "vitest/padding-around-expect-groups": "warn",
1465
+ "vitest/padding-around-test-blocks": "warn"
1428
1466
  }
1429
1467
  }
1430
1468
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@will-stone/eslint-config",
3
- "version": "13.0.0",
3
+ "version": "15.0.0",
4
4
  "description": "Will Stone's ESLint config",
5
5
  "keywords": [
6
6
  "eslint-config"
@@ -18,8 +18,9 @@
18
18
  "dist"
19
19
  ],
20
20
  "scripts": {
21
- "build": "tsup src/index.ts --format esm --clean --dts",
22
- "dev": "tsup src/index.ts --format esm --watch & config-inspector --config ./eslint-config-for-inspector.js",
21
+ "build": "tsup src/index.ts --format esm --clean --dts --shims",
22
+ "predev": "npm run build",
23
+ "dev": "tsup src/index.ts --format esm --shims --watch & config-inspector --config ./eslint-config-for-inspector.js",
23
24
  "lint": "npm run stub && eslint .",
24
25
  "prepare": "simple-git-hooks",
25
26
  "prepublishOnly": "npm run build",
@@ -41,49 +42,74 @@
41
42
  },
42
43
  "prettier": "@will-stone/prettier-config",
43
44
  "dependencies": {
44
- "@eslint/compat": "^1.2.3",
45
- "@typescript-eslint/eslint-plugin": "^8.16.0",
46
- "@typescript-eslint/parser": "^8.16.0",
47
- "astro-eslint-parser": "^1.1.0",
45
+ "@typescript-eslint/eslint-plugin": "^8.27.0",
46
+ "@typescript-eslint/parser": "^8.27.0",
48
47
  "confusing-browser-globals": "^1.0.11",
49
- "eslint-config-flat-gitignore": "^0.3.0",
50
- "eslint-plugin-astro": "^1.3.1",
51
- "eslint-plugin-import-x": "^4.4.3",
52
- "eslint-plugin-jest": "^28.9.0",
48
+ "eslint-config-flat-gitignore": "^2.1.0",
49
+ "eslint-plugin-import-x": "^4.9.1",
53
50
  "eslint-plugin-jsx-a11y": "^6.10.2",
54
- "eslint-plugin-n": "^17.14.0",
55
- "eslint-plugin-react": "^7.37.2",
56
- "eslint-plugin-react-hooks": "^5.0.0",
57
- "eslint-plugin-simple-import-sort": "^12.1.1",
58
- "eslint-plugin-tailwindcss": "^3.17.5",
59
- "eslint-plugin-unicorn": "^56.0.1",
60
- "eslint-plugin-vitest": "^0.5.4",
61
- "globals": "^15.12.0",
62
- "globby": "^14.0.2",
63
- "type-fest": "^4.28.1"
51
+ "eslint-plugin-n": "^17.16.2",
52
+ "eslint-plugin-unicorn": "^58.0.0",
53
+ "globals": "^16.0.0",
54
+ "globby": "^14.1.0",
55
+ "type-fest": "^4.38.0"
64
56
  },
65
57
  "devDependencies": {
66
- "@commits-with-character/conventional-changelog-preset": "^1.0.0",
67
- "@eslint/config-inspector": "^0.5.6",
68
- "@release-it/conventional-changelog": "^9.0.3",
58
+ "@commits-with-character/conventional-changelog-preset": "^2.0.0",
59
+ "@eslint/config-inspector": "^1.0.2",
60
+ "@release-it/conventional-changelog": "^10.0.0",
69
61
  "@types/confusing-browser-globals": "^1.0.3",
70
62
  "@types/eslint": "^9.6.1",
71
- "@types/node": "^22.10.0",
72
- "@typescript-eslint/utils": "^8.16.0",
73
- "@will-stone/prettier-config": "^8.0.1",
74
- "lint-staged": "^15.2.10",
75
- "memfs": "^4.14.0",
76
- "prettier": "^3.4.1",
77
- "release-it": "^17.10.0",
78
- "simple-git-hooks": "^2.11.1",
79
- "tsup": "^8.3.5",
80
- "typescript": "^5.7.2",
81
- "vitest": "^2.1.6"
63
+ "@types/node": "^22.13.13",
64
+ "@typescript-eslint/utils": "^8.27.0",
65
+ "@vitest/eslint-plugin": "^1.1.38",
66
+ "@will-stone/prettier-config": "^9.0.1",
67
+ "astro-eslint-parser": "^1.2.2",
68
+ "eslint-plugin-astro": "^1.3.1",
69
+ "eslint-plugin-jest": "^28.11.0",
70
+ "eslint-plugin-react": "^7.37.4",
71
+ "eslint-plugin-react-hooks": "^5.2.0",
72
+ "eslint-plugin-tailwindcss": "^3.18.0",
73
+ "lint-staged": "^15.5.0",
74
+ "memfs": "^4.17.0",
75
+ "prettier": "^3.5.3",
76
+ "release-it": "^18.1.2",
77
+ "simple-git-hooks": "^2.12.1",
78
+ "tsup": "^8.4.0",
79
+ "typescript": "^5.8.2",
80
+ "vitest": "^3.0.9"
82
81
  },
83
82
  "peerDependencies": {
84
- "eslint": ">=9.15.0"
83
+ "@vitest/eslint-plugin": "^1.1.38",
84
+ "astro-eslint-parser": "^1.2.2",
85
+ "eslint": ">=9.23.0",
86
+ "eslint-plugin-astro": "^1.3.1",
87
+ "eslint-plugin-jest": "^28.11.0",
88
+ "eslint-plugin-react": "^7.37.4",
89
+ "eslint-plugin-react-hooks": "^5.2.0",
90
+ "eslint-plugin-tailwindcss": "^3.18.0"
85
91
  },
86
- "overrides": {
87
- "eslint": ">=9.15.0"
92
+ "peerDependenciesMeta": {
93
+ "@vitest/eslint-plugin": {
94
+ "optional": true
95
+ },
96
+ "astro-eslint-parser": {
97
+ "optional": true
98
+ },
99
+ "eslint-plugin-astro": {
100
+ "optional": true
101
+ },
102
+ "eslint-plugin-jest": {
103
+ "optional": true
104
+ },
105
+ "eslint-plugin-react": {
106
+ "optional": true
107
+ },
108
+ "eslint-plugin-react-hooks": {
109
+ "optional": true
110
+ },
111
+ "eslint-plugin-tailwindcss": {
112
+ "optional": true
113
+ }
88
114
  }
89
115
  }