exadev-eslint-config 1.2.0 → 1.2.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
@@ -52,6 +52,25 @@ export default defineConfig([
52
52
  ]);
53
53
  ```
54
54
 
55
+ `typescript-eslint`'s own `tseslint.config()` helper (rather than ESLint's `defineConfig()`) does **not** accept the string form of `extends` at all -- it throws `has an 'extends' array that contains a string ... This is a feature of eslint's defineConfig() helper and is not supported by typescript-eslint`. A `tseslint.config()`-based project passes the config value directly instead:
56
+
57
+ ```ts
58
+ import exadev from '@exadev/eslint-config';
59
+ import tseslint from 'typescript-eslint';
60
+
61
+ export default tseslint.config(
62
+ // ...your own config...
63
+ {
64
+ files: ['**/*.ts'],
65
+ plugins: { exadev },
66
+ extends: [exadev.configs.recommended], // or exadev.configs.barrel
67
+ },
68
+ );
69
+ ```
70
+
71
+ **`recommended`/`barrel` carry no `files`/`ignores` of their own, and applying either unscoped will misfire.** `no-side-effects-in-index` flags any top-level statement that isn't a bare re-export -- applied to an ordinary file with real `export function`/`export const`/`export interface` declarations, every one of them trips it (confirmed directly: 88 false-positive errors on a single real source file in a repo that tried this). Scope the `extends` block itself to just `src/index.ts` if you want `no-side-effects-in-index`'s coverage from `recommended`/`barrel`, or -- what every current consumer of this plugin actually does -- skip `recommended`/`barrel` and wire the four `exadev/*` rules individually, each with your own project's real `files`/`ignores`, exactly as shown in the first example above. That's not a workaround; it's the intended shape once a project's re-export-ban exceptions and barrel location are genuinely project-specific.
72
+ ```
73
+
55
74
  Both `recommended` and `barrel` are usable in a plain JavaScript project with no TypeScript and no `typescript-eslint` installed: this plugin's own four rules operate on plain ESTree import/export/declaration nodes, nothing TypeScript-specific, and neither config references `typescript-eslint` at all.
56
75
 
57
76
  ### The typed-linting bundle: `@exadev/eslint-config/recommended-type-checked`
@@ -95,14 +114,17 @@ This lives in its own module, separate from the main `@exadev/eslint-config` ent
95
114
  pnpm install # requires Node >=20 and pnpm 11.6.0 (pinned via packageManager)
96
115
  pnpm lint
97
116
  pnpm typecheck
117
+ pnpm test
98
118
  pnpm build
99
119
  ```
100
120
 
101
- No test suite exists for these rules currently -- each is verified by real-world usage against the repos it was extracted from, the same way it was verified before being centralized here.
121
+ Each rule has a co-located `*.test.ts` file (`src/rules/no-non-barrel-index.test.ts` etc.) exercising it with ESLint's own `RuleTester`, run under Vitest. `vitest.setup.ts` wires `RuleTester.describe`/`RuleTester.it`/`RuleTester.itOnly` to Vitest's own `describe`/`it` explicitly, rather than turning on Vitest's `test.globals` project-wide, since `RuleTester.run()` only calls `describe`/`it` if something has supplied them. Each test file constructs its own `RuleTester` with `languageOptions.parser` set to `typescript-eslint`'s parser, since these rules' realistic test fixtures use TypeScript-only syntax (e.g. `export type { X } from './y'`) that the default `espree` parser can't read; none of the four rules need type information, so no `project`/`tsconfigRootDir` is configured.
122
+
123
+ `pnpm test` always measures coverage (`coverage.enabled: true` in `vitest.config.ts`, via `@vitest/coverage-v8`) rather than needing a separate `--coverage` flag -- scoped to `src/**/*.ts` excluding the `*.test.ts` files themselves. The text reporter summarises in the terminal; the `html`/`lcov` reporters land in `coverage/`, already gitignored alongside `.eslintcache` and `dist/`.
102
124
 
103
- The `lint`/`typecheck`/`build` npm scripts are thin wrappers around turbo tasks whose own names carry a leading underscore (`_lint`/`_typecheck`/`_build`, declared in `turbo.json`) -- run `pnpm build`, not `turbo run build` directly, since turbo's task names don't match the npm script names.
125
+ The `lint`/`typecheck`/`test`/`build` npm scripts are thin wrappers around turbo tasks whose own names carry a leading underscore (`_lint`/`_typecheck`/`_test`/`_build`, declared in `turbo.json`) -- run `pnpm build`, not `turbo run build` directly, since turbo's task names don't match the npm script names.
104
126
 
105
- `pnpm build` runs `tsdown`, emitting ESM and CJS output plus declaration files from `src/**/*.ts` (platform-neutral, `src/**/*.test.ts` excluded). Before any publish -- local or the CI alias job -- `prepublishOnly` re-runs lint, typecheck, `tsdown`, `publint`, and `attw --pack`, so a broken export shape fails at publish time even outside the main CI pipeline.
127
+ `pnpm build` runs `tsdown`, emitting ESM and CJS output plus declaration files from `src/**/*.ts` (platform-neutral, `src/**/*.test.ts` excluded). Before any publish -- local or the CI alias job -- `prepublishOnly` re-runs lint, typecheck, `test`, `tsdown`, `publint`, and `attw --pack`, so a broken export shape fails at publish time even outside the main CI pipeline.
106
128
 
107
129
  ## Architecture
108
130
 
@@ -123,12 +145,12 @@ Conventional commits are enforced by commitlint, restricted to the type-enum def
123
145
  ## Gotchas and quirks
124
146
 
125
147
  - `.attw.json` ignores the `false-export-default` rule: tsdown/rolldown's CJS output for this plugin's sole default export doesn't emit the `export =` form `arethetypeswrong`'s check wants under legacy `node10` resolution. The resolution modes an ESLint flat config actually uses (`node16`, `bundler`) are unaffected, so the rule is suppressed rather than moving the plugin away from ESLint's own documented default-export shape.
126
- - Husky hooks: `pre-commit` runs lint-staged (`eslint --fix` on staged `*.ts`), `commit-msg` runs commitlint against the message, `pre-push` runs `typecheck` and `build` -- pushing here rebuilds the whole package first.
148
+ - Husky hooks: `pre-commit` runs lint-staged (`eslint --fix` on staged `*.ts`), `commit-msg` runs commitlint against the message, `pre-push` runs `typecheck`, `test`, and `build` -- pushing here re-runs the whole test suite and rebuilds the package first.
127
149
  - The CI release job sets `HUSKY=0` (so the commit-msg hook never fires against the automated release commit) and blanks `NPM_TOKEN`/`NODE_AUTH_TOKEN` explicitly rather than omitting them, so an inherited token can't win over npm's OIDC trusted-publishing exchange.
128
150
 
129
151
  ## Contributing
130
152
 
131
- Conventional commits are enforced by commitlint via a husky `commit-msg` hook, and re-checked in CI. CI runs commitlint, lint, and typecheck+build+attw on every push and pull request; the release job only runs on a push to `main`, after all three pass.
153
+ Conventional commits are enforced by commitlint via a husky `commit-msg` hook, and re-checked in CI. CI runs commitlint, lint, and typecheck+test+build+attw on every push and pull request; the release job only runs on a push to `main`, after all three pass.
132
154
 
133
155
  ## Release
134
156
 
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const require_plugin = require("./plugin-Dixk0WAc.cjs");
1
+ const require_plugin = require("./plugin-DZKXx2me.cjs");
2
2
  module.exports = require_plugin.plugin;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as plugin } from "./plugin-Cq16p_yl.js";
1
+ import { t as plugin } from "./plugin-PQMeiTvg.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.2.0",
6
+ version: "1.2.2",
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.2.0",
10
+ version: "1.2.2",
11
11
  namespace: "exadev"
12
12
  },
13
13
  rules: {
package/dist/plugin.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const require_plugin = require("./plugin-Dixk0WAc.cjs");
1
+ const require_plugin = require("./plugin-DZKXx2me.cjs");
2
2
  module.exports = require_plugin.plugin;
package/dist/plugin.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as plugin } from "./plugin-Cq16p_yl.js";
1
+ import { t as plugin } from "./plugin-PQMeiTvg.js";
2
2
  export { plugin as default };
@@ -20,7 +20,7 @@ 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-Dixk0WAc.cjs");
23
+ const require_plugin = require("./plugin-DZKXx2me.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
@@ -1,4 +1,4 @@
1
- import { t as plugin } from "./plugin-Cq16p_yl.js";
1
+ import { t as plugin } from "./plugin-PQMeiTvg.js";
2
2
  import tseslint from "typescript-eslint";
3
3
  //#region src/recommended-type-checked.ts
4
4
  const recommendedTypeChecked = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exadev-eslint-config",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Shared custom ESLint rules and plugin for ExaDev projects",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -61,6 +61,7 @@
61
61
  "@semantic-release/changelog": "^7.0.0",
62
62
  "@semantic-release/git": "^11.0.1",
63
63
  "@types/node": "^24.9.2",
64
+ "@vitest/coverage-v8": "^4.1.10",
64
65
  "eslint": "^10.8.0",
65
66
  "husky": "^9.1.7",
66
67
  "lint-staged": "^17.2.0",
@@ -69,7 +70,8 @@
69
70
  "tsdown": "^0.22.13",
70
71
  "turbo": "^2.10.8",
71
72
  "typescript": "^6.0.3",
72
- "typescript-eslint": "^8.65.0"
73
+ "typescript-eslint": "^8.65.0",
74
+ "vitest": "^4.1.10"
73
75
  },
74
76
  "scripts": {
75
77
  "build": "turbo run _build",
@@ -78,6 +80,8 @@
78
80
  "_lint": "eslint . --fix --cache --max-warnings 0",
79
81
  "typecheck": "turbo run _typecheck",
80
82
  "_typecheck": "tsc -p tsconfig.json",
83
+ "test": "turbo run _test",
84
+ "_test": "vitest run",
81
85
  "release": "semantic-release"
82
86
  }
83
87
  }