@will-stone/eslint-config 19.0.0 → 20.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.
package/README.md CHANGED
@@ -18,7 +18,6 @@ the corresponding plugin.
18
18
  | Package | Plugin |
19
19
  | ------------- | ----------------------------------------------- |
20
20
  | `astro` | `astro-eslint-parser eslint-plugin-astro` |
21
- | `jest` | `eslint-plugin-jest` |
22
21
  | `react` | `eslint-plugin-react eslint-plugin-react-hooks` |
23
22
  | `tailwindcss` | `eslint-plugin-tailwindcss` |
24
23
  | `vitest` | `@vitest/eslint-plugin` |
package/dist/index.d.ts CHANGED
@@ -6,15 +6,19 @@ import { TSESLint } from "@typescript-eslint/utils";
6
6
  */
7
7
  type Options = {
8
8
  astro?: boolean;
9
- jest?: boolean;
10
9
  react?: boolean;
11
10
  tailwind?: {
12
11
  config?: string;
13
12
  cssFiles?: string[];
14
13
  } | boolean;
15
- typescript?: boolean;
14
+ typescript?: boolean | {
15
+ tsconfigPath?: string;
16
+ };
16
17
  vitest?: boolean;
17
18
  };
19
+ /**
20
+ * A context of data and options passed to all configs.
21
+ */
18
22
  //#endregion
19
23
  //#region src/index.d.ts
20
24
  /**
package/dist/index.js CHANGED
@@ -2,11 +2,12 @@ import parserTypescript from "@typescript-eslint/parser";
2
2
  import restrictedGlobals from "confusing-browser-globals";
3
3
  import globals from "globals";
4
4
  import gitignore from "eslint-config-flat-gitignore";
5
+ import jsdocPlugin from "eslint-plugin-jsdoc";
5
6
  import pluginNode from "eslint-plugin-n";
6
7
  import pluginPackageJson from "eslint-plugin-package-json";
7
8
  import pluginPerfectionist from "eslint-plugin-perfectionist";
8
9
  import stylistic from "@stylistic/eslint-plugin";
9
- import pluginTsdoc from "eslint-plugin-tsdoc";
10
+ import pluginTypescript from "@typescript-eslint/eslint-plugin";
10
11
  import pluginUnicorn from "eslint-plugin-unicorn";
11
12
  import { globbySync } from "globby";
12
13
  import { readFileSync } from "node:fs";
@@ -62,7 +63,7 @@ async function interopDefault(m) {
62
63
 
63
64
  //#endregion
64
65
  //#region src/configs/astro.ts
65
- async function astro(_options) {
66
+ async function astro(_configContext) {
66
67
  const [pluginAstro, parserAstro] = await Promise.all([interopDefault(import("eslint-plugin-astro")), interopDefault(import("astro-eslint-parser"))]);
67
68
  return [{
68
69
  files: [GLOB_ASTRO],
@@ -140,7 +141,7 @@ async function astro(_options) {
140
141
 
141
142
  //#endregion
142
143
  //#region src/configs/base.ts
143
- async function base() {
144
+ function base() {
144
145
  return [{
145
146
  languageOptions: { globals: {
146
147
  ...globals.browser,
@@ -366,7 +367,7 @@ async function base() {
366
367
 
367
368
  //#endregion
368
369
  //#region src/configs/ignores.ts
369
- async function ignores() {
370
+ function ignores() {
370
371
  return [{
371
372
  ignores: GLOB_EXCLUDE,
372
373
  name: "will-stone/ignores"
@@ -377,97 +378,84 @@ async function ignores() {
377
378
  }
378
379
 
379
380
  //#endregion
380
- //#region src/configs/jest.ts
381
- async function jest(_options) {
382
- const pluginJest = await interopDefault(import("eslint-plugin-jest"));
383
- return [
384
- {
385
- files: GLOB_TESTS,
386
- languageOptions: { globals: globals.jest },
387
- name: "will-stone/jest/globals"
388
- },
389
- {
390
- files: [GLOB_TESTS],
391
- name: "will-stone/jest/base",
392
- plugins: { jest: pluginJest },
393
- rules: {
394
- "jest/consistent-test-it": ["error", {
395
- fn: "test",
396
- withinDescribe: "it"
397
- }],
398
- "jest/expect-expect": "error",
399
- "jest/max-expects": "off",
400
- "jest/max-nested-describe": "off",
401
- "jest/no-alias-methods": "error",
402
- "jest/no-commented-out-tests": "error",
403
- "jest/no-conditional-expect": "error",
404
- "jest/no-conditional-in-test": "error",
405
- "jest/no-confusing-set-timeout": "error",
406
- "jest/no-deprecated-functions": "warn",
407
- "jest/no-disabled-tests": "warn",
408
- "jest/no-done-callback": "error",
409
- "jest/no-duplicate-hooks": "error",
410
- "jest/no-export": "error",
411
- "jest/no-focused-tests": "error",
412
- "jest/no-hooks": "off",
413
- "jest/no-identical-title": "error",
414
- "jest/no-interpolation-in-snapshots": "error",
415
- "jest/no-jasmine-globals": "warn",
416
- "jest/no-large-snapshots": "off",
417
- "jest/no-mocks-import": "error",
418
- "jest/no-restricted-jest-methods": "off",
419
- "jest/no-restricted-matchers": "off",
420
- "jest/no-standalone-expect": "error",
421
- "jest/no-test-prefixes": "warn",
422
- "jest/no-test-return-statement": "error",
423
- "jest/padding-around-after-all-blocks": "warn",
424
- "jest/padding-around-after-each-blocks": "warn",
425
- "jest/padding-around-all": "warn",
426
- "jest/padding-around-before-all-blocks": "warn",
427
- "jest/padding-around-before-each-blocks": "warn",
428
- "jest/padding-around-describe-blocks": "warn",
429
- "jest/padding-around-expect-groups": "warn",
430
- "jest/padding-around-test-blocks": "warn",
431
- "jest/prefer-called-with": "off",
432
- "jest/prefer-comparison-matcher": "warn",
433
- "jest/prefer-each": "error",
434
- "jest/prefer-equality-matcher": "error",
435
- "jest/prefer-expect-assertions": "off",
436
- "jest/prefer-expect-resolves": "warn",
437
- "jest/prefer-hooks-in-order": "error",
438
- "jest/prefer-hooks-on-top": "error",
439
- "jest/prefer-importing-jest-globals": "off",
440
- "jest/prefer-jest-mocked": "warn",
441
- "jest/prefer-lowercase-title": "off",
442
- "jest/prefer-mock-promise-shorthand": "warn",
443
- "jest/prefer-snapshot-hint": "error",
444
- "jest/prefer-spy-on": "error",
445
- "jest/prefer-strict-equal": "error",
446
- "jest/prefer-to-be": "warn",
447
- "jest/prefer-to-contain": "error",
448
- "jest/prefer-to-have-length": "error",
449
- "jest/prefer-todo": "error",
450
- "jest/require-hook": "error",
451
- "jest/require-to-throw-message": "error",
452
- "jest/require-top-level-describe": "off",
453
- "jest/unbound-method": "off",
454
- "jest/valid-describe-callback": "error",
455
- "jest/valid-expect": "error",
456
- "jest/valid-expect-in-promise": "error",
457
- "jest/valid-title": "error"
458
- }
459
- },
460
- {
461
- files: ["**/*.{spec,test}.{ts,tsx}"],
462
- name: "will-stone/jest/typescript",
463
- rules: { "jest/no-untyped-mock-factory": "warn" }
381
+ //#region src/configs/jsdoc.ts
382
+ function jsdoc() {
383
+ return [{
384
+ files: [GLOB_TS, GLOB_TSX],
385
+ name: "will-stone/jsdoc",
386
+ plugins: { jsdoc: jsdocPlugin },
387
+ rules: {
388
+ "jsdoc/check-access": "off",
389
+ "jsdoc/check-alignment": "warn",
390
+ "jsdoc/check-examples": "off",
391
+ "jsdoc/check-indentation": "off",
392
+ "jsdoc/check-line-alignment": [
393
+ "warn",
394
+ "never",
395
+ { wrapIndent: " " }
396
+ ],
397
+ "jsdoc/check-param-names": "warn",
398
+ "jsdoc/check-property-names": "off",
399
+ "jsdoc/check-syntax": "off",
400
+ "jsdoc/check-tag-names": ["warn", {
401
+ definedTags: ["jest-environment"],
402
+ typed: false
403
+ }],
404
+ "jsdoc/check-template-names": "off",
405
+ "jsdoc/check-types": "off",
406
+ "jsdoc/check-values": "warn",
407
+ "jsdoc/convert-to-jsdoc-comments": "off",
408
+ "jsdoc/empty-tags": "warn",
409
+ "jsdoc/implements-on-classes": "off",
410
+ "jsdoc/imports-as-dependencies": "off",
411
+ "jsdoc/informative-docs": "warn",
412
+ "jsdoc/lines-before-block": "off",
413
+ "jsdoc/match-description": "off",
414
+ "jsdoc/match-name": "off",
415
+ "jsdoc/multiline-blocks": "off",
416
+ "jsdoc/no-bad-blocks": "warn",
417
+ "jsdoc/no-blank-block-descriptions": "warn",
418
+ "jsdoc/no-blank-blocks": "off",
419
+ "jsdoc/no-defaults": "warn",
420
+ "jsdoc/no-missing-syntax": "off",
421
+ "jsdoc/no-multi-asterisks": "warn",
422
+ "jsdoc/no-restricted-syntax": "off",
423
+ "jsdoc/no-types": "warn",
424
+ "jsdoc/no-undefined-types": "off",
425
+ "jsdoc/require-asterisk-prefix": "warn",
426
+ "jsdoc/require-description": "off",
427
+ "jsdoc/require-description-complete-sentence": "warn",
428
+ "jsdoc/require-example": "off",
429
+ "jsdoc/require-file-overview": "off",
430
+ "jsdoc/require-hyphen-before-param-description": "warn",
431
+ "jsdoc/require-jsdoc": "off",
432
+ "jsdoc/require-param": "off",
433
+ "jsdoc/require-param-description": "warn",
434
+ "jsdoc/require-param-name": "warn",
435
+ "jsdoc/require-param-type": "off",
436
+ "jsdoc/require-property": "off",
437
+ "jsdoc/require-property-description": "off",
438
+ "jsdoc/require-property-name": "off",
439
+ "jsdoc/require-property-type": "off",
440
+ "jsdoc/require-returns": "off",
441
+ "jsdoc/require-returns-check": "warn",
442
+ "jsdoc/require-returns-description": "warn",
443
+ "jsdoc/require-returns-type": "off",
444
+ "jsdoc/require-template": "off",
445
+ "jsdoc/require-throws": "warn",
446
+ "jsdoc/require-yields": "warn",
447
+ "jsdoc/require-yields-check": "warn",
448
+ "jsdoc/sort-tags": "warn",
449
+ "jsdoc/tag-lines": "off",
450
+ "jsdoc/text-escaping": "off",
451
+ "jsdoc/valid-types": "off"
464
452
  }
465
- ];
453
+ }];
466
454
  }
467
455
 
468
456
  //#endregion
469
457
  //#region src/configs/node.ts
470
- async function node() {
458
+ function node() {
471
459
  return [{
472
460
  languageOptions: { globals: globals.node },
473
461
  name: "will-stone/node",
@@ -518,7 +506,7 @@ async function node() {
518
506
 
519
507
  //#endregion
520
508
  //#region src/configs/package-json.ts
521
- async function packageJson() {
509
+ function packageJson() {
522
510
  return [{
523
511
  ...pluginPackageJson.configs.recommended,
524
512
  name: "will-stone/package.json",
@@ -550,7 +538,7 @@ async function packageJson() {
550
538
 
551
539
  //#endregion
552
540
  //#region src/configs/perfectionist.ts
553
- async function perfectionist() {
541
+ function perfectionist() {
554
542
  return [{
555
543
  name: "will-stone/perfectionist",
556
544
  plugins: { perfectionist: pluginPerfectionist },
@@ -571,7 +559,7 @@ async function perfectionist() {
571
559
 
572
560
  //#endregion
573
561
  //#region src/configs/react.ts
574
- async function react(_options) {
562
+ async function react(_configContext) {
575
563
  const [pluginJsxA11y, pluginReact, pluginReactHooks] = await Promise.all([
576
564
  interopDefault(import("eslint-plugin-jsx-a11y")),
577
565
  interopDefault(import("eslint-plugin-react")),
@@ -837,7 +825,7 @@ async function react(_options) {
837
825
 
838
826
  //#endregion
839
827
  //#region src/configs/style.ts
840
- async function style() {
828
+ function style() {
841
829
  return [{
842
830
  name: "will-stone/style",
843
831
  plugins: { "@stylistic": stylistic },
@@ -859,7 +847,7 @@ async function style() {
859
847
 
860
848
  //#endregion
861
849
  //#region src/configs/tailwind.ts
862
- async function tailwind(rawOptions) {
850
+ async function tailwind({ options: { tailwind: rawOptions } }) {
863
851
  const options = !rawOptions || rawOptions === true ? {} : rawOptions;
864
852
  const plugin = await interopDefault(import("eslint-plugin-tailwindcss"));
865
853
  return [{
@@ -883,22 +871,10 @@ async function tailwind(rawOptions) {
883
871
  }];
884
872
  }
885
873
 
886
- //#endregion
887
- //#region src/configs/tsdoc.ts
888
- async function tsdoc() {
889
- return [{
890
- files: [GLOB_TS, GLOB_TSX],
891
- name: "will-stone/tsdoc",
892
- plugins: { tsdoc: pluginTsdoc },
893
- rules: { "tsdoc/syntax": "error" }
894
- }];
895
- }
896
-
897
874
  //#endregion
898
875
  //#region src/configs/typescript.ts
899
- async function typescript(rawOptions) {
876
+ function typescript({ options: { typescript: rawOptions } }) {
900
877
  const options = !rawOptions || typeof rawOptions === "boolean" ? {} : rawOptions;
901
- const [pluginTypescript, parserTypescript$1] = await Promise.all([interopDefault(import("@typescript-eslint/eslint-plugin")), interopDefault(import("@typescript-eslint/parser"))]);
902
878
  return [{
903
879
  files: [
904
880
  GLOB_ASTRO_TS,
@@ -906,7 +882,7 @@ async function typescript(rawOptions) {
906
882
  GLOB_TSX
907
883
  ],
908
884
  languageOptions: {
909
- parser: parserTypescript$1,
885
+ parser: parserTypescript,
910
886
  parserOptions: { ...options.tsconfigPath ? {
911
887
  projectService: {
912
888
  allowDefaultProject: ["./*.js"],
@@ -1090,7 +1066,7 @@ async function typescript(rawOptions) {
1090
1066
 
1091
1067
  //#endregion
1092
1068
  //#region src/configs/unicorn.ts
1093
- async function unicorn() {
1069
+ function unicorn() {
1094
1070
  return [{
1095
1071
  name: "will-stone/unicorn",
1096
1072
  plugins: { unicorn: pluginUnicorn },
@@ -1235,7 +1211,7 @@ async function unicorn() {
1235
1211
 
1236
1212
  //#endregion
1237
1213
  //#region src/configs/vitest.ts
1238
- async function vitest(_options) {
1214
+ async function vitest(_configContext) {
1239
1215
  const pluginVitest = await interopDefault(import("@vitest/eslint-plugin"));
1240
1216
  return [{
1241
1217
  files: GLOB_TESTS,
@@ -1334,8 +1310,8 @@ const defaultConfigs = [
1334
1310
  name: "package.json"
1335
1311
  },
1336
1312
  {
1337
- config: tsdoc,
1338
- name: "TSDoc"
1313
+ config: jsdoc,
1314
+ name: "JSDoc"
1339
1315
  },
1340
1316
  {
1341
1317
  config: style,
@@ -1344,27 +1320,19 @@ const defaultConfigs = [
1344
1320
  {
1345
1321
  config: perfectionist,
1346
1322
  name: "Perfectionist"
1323
+ },
1324
+ {
1325
+ config: typescript,
1326
+ name: "Typescript"
1347
1327
  }
1348
1328
  ];
1349
1329
  const autoConfigs = [
1350
- {
1351
- config: typescript,
1352
- dep: "typescript",
1353
- name: "Typescript",
1354
- optionName: "typescript"
1355
- },
1356
1330
  {
1357
1331
  config: astro,
1358
1332
  dep: "astro",
1359
1333
  name: "Astro.js",
1360
1334
  optionName: "astro"
1361
1335
  },
1362
- {
1363
- config: jest,
1364
- dep: "jest",
1365
- name: "Jest",
1366
- optionName: "jest"
1367
- },
1368
1336
  {
1369
1337
  config: react,
1370
1338
  dep: "react",
@@ -1414,23 +1382,24 @@ function checkDepsExist(depNames) {
1414
1382
 
1415
1383
  //#endregion
1416
1384
  //#region src/index.ts
1385
+ const defaultOptions = {};
1417
1386
  /**
1418
1387
  * Construct an array of ESLint flat config items.
1419
1388
  */
1420
- async function config(options) {
1389
+ async function config(options = defaultOptions) {
1421
1390
  const configs = [];
1422
1391
  const autoConfigDeps = Object.values(autoConfigs).map(({ dep }) => dep);
1423
1392
  const existingAutoConfigDeps = checkDepsExist(autoConfigDeps);
1424
- for await (const defaultConfig of defaultConfigs) configs.push(await defaultConfig.config());
1425
1393
  const enabledAutoConfigs = autoConfigs.filter(({ dep, optionName }) => {
1426
1394
  return options?.[optionName] || existingAutoConfigDeps[dep] && options?.[optionName] !== false;
1427
1395
  });
1428
1396
  if (enabledAutoConfigs.length > 0) console.log("Auto-configured plugins:");
1429
- for await (const autoConfig of enabledAutoConfigs) {
1397
+ const configContext = { options };
1398
+ for (const defaultConfig of defaultConfigs) configs.push(defaultConfig.config(configContext));
1399
+ await Promise.all(enabledAutoConfigs.map(async (autoConfig) => {
1430
1400
  console.log(`- ${autoConfig.name}`);
1431
- const autoConfigOptions = options?.[autoConfig.optionName];
1432
- configs.push(await autoConfig.config(autoConfigOptions));
1433
- }
1401
+ configs.push(await autoConfig.config(configContext));
1402
+ }));
1434
1403
  const merged = configs.flat();
1435
1404
  return merged;
1436
1405
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@will-stone/eslint-config",
3
- "version": "19.0.0",
3
+ "version": "20.0.0",
4
4
  "description": "Will Stone's ESLint config",
5
5
  "keywords": [
6
6
  "eslint-config"
@@ -20,11 +20,9 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "build": "tsdown",
23
- "predev": "pnpm build",
24
- "dev": "tsdown --watch & config-inspector --config ./eslint-config-for-inspector.js",
25
- "lint": "pnpm build && eslint .",
23
+ "dev": "config-inspector --config ./eslint-config-for-inspector.js",
24
+ "lint": "eslint .",
26
25
  "prepare": "husky",
27
- "prepublishOnly": "pnpm build",
28
26
  "release": "release-it",
29
27
  "test": "vitest",
30
28
  "typecheck": "tsc --noEmit"
@@ -35,11 +33,11 @@
35
33
  "@typescript-eslint/parser": "^8.33.1",
36
34
  "confusing-browser-globals": "^1.0.11",
37
35
  "eslint-config-flat-gitignore": "^2.1.0",
36
+ "eslint-plugin-jsdoc": "^54.1.0",
38
37
  "eslint-plugin-jsx-a11y": "^6.10.2",
39
38
  "eslint-plugin-n": "^17.19.0",
40
39
  "eslint-plugin-package-json": "^0.33.2",
41
40
  "eslint-plugin-perfectionist": "^4.14.0",
42
- "eslint-plugin-tsdoc": "^0.4.0",
43
41
  "eslint-plugin-unicorn": "^59.0.1",
44
42
  "globals": "^16.2.0",
45
43
  "globby": "^14.1.0",
@@ -57,11 +55,11 @@
57
55
  "@will-stone/prettier-config": "^11.0.1",
58
56
  "astro-eslint-parser": "^1.2.2",
59
57
  "eslint-plugin-astro": "^1.3.1",
60
- "eslint-plugin-jest": "^28.12.0",
61
58
  "eslint-plugin-react": "^7.37.5",
62
59
  "eslint-plugin-react-hooks": "^5.2.0",
63
60
  "eslint-plugin-tailwindcss": "^3.18.0",
64
61
  "husky": "^9.1.7",
62
+ "jiti": "^2.5.1",
65
63
  "lint-staged": "^16.1.0",
66
64
  "memfs": "^4.17.2",
67
65
  "prettier": "^3.5.3",
@@ -75,7 +73,6 @@
75
73
  "astro-eslint-parser": "^1.2.2",
76
74
  "eslint": ">=9.23.0",
77
75
  "eslint-plugin-astro": "^1.3.1",
78
- "eslint-plugin-jest": "^28.11.0",
79
76
  "eslint-plugin-react": "^7.37.4",
80
77
  "eslint-plugin-react-hooks": "^5.2.0",
81
78
  "eslint-plugin-tailwindcss": "^3.18.0"
@@ -90,9 +87,6 @@
90
87
  "eslint-plugin-astro": {
91
88
  "optional": true
92
89
  },
93
- "eslint-plugin-jest": {
94
- "optional": true
95
- },
96
90
  "eslint-plugin-react": {
97
91
  "optional": true
98
92
  },
@@ -103,7 +97,7 @@
103
97
  "optional": true
104
98
  }
105
99
  },
106
- "packageManager": "pnpm@10.11.1",
100
+ "packageManager": "pnpm@10.14.0",
107
101
  "engines": {
108
102
  "node": ">=22"
109
103
  },