@exadev/eslint-config 1.3.0 → 1.4.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
@@ -94,10 +94,12 @@ export default tseslint.config(
94
94
  );
95
95
  ```
96
96
 
97
- This bundles `typescript-eslint`'s own `recommendedTypeChecked` and `stylisticTypeChecked` presets (`recommendedTypeChecked` already subsumes plain `recommended` outright -- every one of its 46 rules is a strict subset of `recommendedTypeChecked`'s 73, confirmed by inspecting the actual rule maps) alongside this plugin's own four rules, `linterOptions.noInlineConfig`, and `@typescript-eslint/consistent-type-assertions` set to `never` (no `as`/angle-bracket type assertions -- narrow with a guard or parse with Zod instead).
97
+ This bundles `typescript-eslint`'s own `recommendedTypeChecked` and `stylisticTypeChecked` presets (`recommendedTypeChecked` already subsumes plain `recommended` outright -- every one of its 46 rules is a strict subset of `recommendedTypeChecked`'s 73, confirmed by inspecting the actual rule maps) alongside this plugin's own four rules, `linterOptions.noInlineConfig`, `@typescript-eslint/consistent-type-assertions` set to `never` (no `as`/angle-bracket type assertions -- narrow with a guard or parse with Zod instead), and `@typescript-eslint/ban-ts-comment` raised to ban `@ts-expect-error` outright alongside the preset's own existing `@ts-ignore`/`@ts-nocheck` bans -- with `noInlineConfig` already removing `eslint-disable` as an escape hatch, this leaves no way to suppress a type error inline anywhere in a consuming project.
98
98
 
99
99
  It's a real bundling, not a rule reference that assumes the consumer already has `typescript-eslint` set up: `recommendedTypeChecked`'s own base config registers the `@typescript-eslint` plugin and sets `languageOptions.parser` itself. **A consumer adopting this bundle must remove its own `...tseslint.configs.recommended`/`recommendedTypeChecked`/`stylisticTypeChecked` spreads** rather than keep them alongside it -- ESLint flat config rejects two different plugin object instances registered under the same namespace. What a consumer still supplies itself is `languageOptions.parserOptions.project`/`projectService` pointing at its own tsconfig(s); `recommendedTypeChecked`'s base config never sets that, since it's genuinely project-specific.
100
100
 
101
+ **Test files (`**/*.{test,spec}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}`) get two narrow relaxations of this package's own additions above, and only those two.** A compile-time-only `@ts-expect-error` proving a construct genuinely fails to type-check is a well-established, legitimate test pattern -- TypeScript's own "unused `@ts-expect-error` directive" diagnostic already catches one that stops being needed, independent of this rule -- so a test file reverts to the rule's own pre-ban default, `allow-with-description`, rather than the outright ban. `@ts-ignore`/`@ts-nocheck` stay banned even in test files: `@ts-expect-error` is strictly better for both, so there's no legitimate test-specific reason to reach for either. `consistent-type-assertions` relaxes to `assertionStyle: 'as'` in test files -- letting a test construct a partial/stub value with a real `as` assertion where the full type wouldn't otherwise accept it -- while the legacy angle-bracket `<Type>value` form stays banned everywhere, tests included. Nothing inherited from `recommendedTypeChecked`/`stylisticTypeChecked` itself is relaxed in test files; only this package's own two additions are.
102
+
101
103
  This lives in its own module, separate from the main `@exadev/eslint-config` entry point, specifically so importing the main package never attempts to resolve `typescript-eslint`. A plain object property (or a lazy getter) on the base plugin's own `configs` map can't achieve that: ESLint's `extends` resolution is synchronous, so a dynamic `import()` doesn't help either -- it just hides the same requirement behind an unawaited promise. Splitting into a genuinely separate module sidesteps the problem at the right layer: Node's own module resolution only loads a module when something actually imports it.
102
104
 
103
105
  ## Rules
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const require_plugin = require("./plugin-BYYl-Vq6.cjs");
1
+ const require_plugin = require("./plugin-CeP2_L7r.cjs");
2
2
  module.exports = require_plugin.plugin;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as plugin } from "./plugin-l6VVqtbv.js";
1
+ import { t as plugin } from "./plugin-CrJp1Z9Y.js";
2
2
  export { plugin as default };
@@ -3,7 +3,7 @@
3
3
  const plugin = {
4
4
  meta: {
5
5
  name: "@exadev/eslint-config",
6
- version: "1.3.0",
6
+ version: "1.4.0",
7
7
  namespace: "exadev"
8
8
  },
9
9
  rules: {
@@ -7,7 +7,7 @@ import noSideEffectsInIndex from "./rules/no-side-effects-in-index.js";
7
7
  const plugin = {
8
8
  meta: {
9
9
  name: "@exadev/eslint-config",
10
- version: "1.3.0",
10
+ version: "1.4.0",
11
11
  namespace: "exadev"
12
12
  },
13
13
  rules: {
package/dist/plugin.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const require_plugin = require("./plugin-BYYl-Vq6.cjs");
1
+ const require_plugin = require("./plugin-CeP2_L7r.cjs");
2
2
  module.exports = require_plugin.plugin;
package/dist/plugin.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as plugin } from "./plugin-l6VVqtbv.js";
1
+ import { t as plugin } from "./plugin-CrJp1Z9Y.js";
2
2
  export { plugin as default };
@@ -20,10 +20,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
20
20
  enumerable: true
21
21
  }) : target, mod));
22
22
  //#endregion
23
- const require_plugin = require("./plugin-BYYl-Vq6.cjs");
23
+ const require_plugin = require("./plugin-CeP2_L7r.cjs");
24
24
  let typescript_eslint = require("typescript-eslint");
25
25
  typescript_eslint = __toESM(typescript_eslint, 1);
26
26
  //#region src/recommended-type-checked.ts
27
+ const TEST_FILE_PATTERNS = "**/*.{test,spec}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}";
27
28
  const recommendedTypeChecked = [
28
29
  ...typescript_eslint.default.configs.recommendedTypeChecked,
29
30
  ...typescript_eslint.default.configs.stylisticTypeChecked,
@@ -38,6 +39,13 @@ const recommendedTypeChecked = [
38
39
  "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "never" }],
39
40
  "@typescript-eslint/ban-ts-comment": ["error", { "ts-expect-error": true }]
40
41
  }
42
+ },
43
+ {
44
+ files: [TEST_FILE_PATTERNS],
45
+ rules: {
46
+ "@typescript-eslint/ban-ts-comment": ["error", { "ts-expect-error": "allow-with-description" }],
47
+ "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "as" }]
48
+ }
41
49
  }
42
50
  ];
43
51
  //#endregion
@@ -1,6 +1,7 @@
1
- import { t as plugin } from "./plugin-l6VVqtbv.js";
1
+ import { t as plugin } from "./plugin-CrJp1Z9Y.js";
2
2
  import tseslint from "typescript-eslint";
3
3
  //#region src/recommended-type-checked.ts
4
+ const TEST_FILE_PATTERNS = "**/*.{test,spec}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}";
4
5
  const recommendedTypeChecked = [
5
6
  ...tseslint.configs.recommendedTypeChecked,
6
7
  ...tseslint.configs.stylisticTypeChecked,
@@ -15,6 +16,13 @@ const recommendedTypeChecked = [
15
16
  "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "never" }],
16
17
  "@typescript-eslint/ban-ts-comment": ["error", { "ts-expect-error": true }]
17
18
  }
19
+ },
20
+ {
21
+ files: [TEST_FILE_PATTERNS],
22
+ rules: {
23
+ "@typescript-eslint/ban-ts-comment": ["error", { "ts-expect-error": "allow-with-description" }],
24
+ "@typescript-eslint/consistent-type-assertions": ["error", { assertionStyle: "as" }]
25
+ }
18
26
  }
19
27
  ];
20
28
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exadev/eslint-config",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Shared custom ESLint rules and plugin for ExaDev projects",
5
5
  "type": "module",
6
6
  "sideEffects": false,