Skip to content

chore(deps-dev): upgrade vitest, coverage-v8 and jsdom; drop EOL Node versions - #22

Merged
jackmisner merged 1 commit into
mainfrom
chore/upgrade-test-toolchain
Aug 20, 2026
Merged

chore(deps-dev): upgrade vitest, coverage-v8 and jsdom; drop EOL Node versions#22
jackmisner merged 1 commit into
mainfrom
chore/upgrade-test-toolchain

Conversation

@jackmisner

@jackmisner jackmisner commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Supersedes Dependabot PRs #17, #18 and #19, three of which could not pass on their own. #20 (TypeScript 7) is blocked upstream and is handled separately — see below.

Advisories: 6 → 1

vitest 4 clears the esbuild → vite → vitest chain that survived the last dependency pass.

The one remaining is esbuild@0.27.7 — LOW severity, arbitrary file read via the dev server on Windows. The fix is esbuild 0.28.2, but tsup pins esbuild: ^0.27.0, so it cannot be resolved from here. This project runs no dev server and does not build on Windows, so real exposure is nil.

Why these three had to move together

@vitest/coverage-v8@4 peer-requires the exact matching vitest version. Dependabot raised them as two separate PRs, and each failed npm ci on the peer conflict — neither could land without the other:

npm error   peer vitest@"2.1.9" from @vitest/coverage-v8@2.1.9
npm error   dev vitest@"^4.1.10" from the root project

That's a consequence of the ungrouped-majors rule I added last week. It's the right default in general and wrong for a lockstep family, so dependabot.yml now groups the vitest packages across all update types, majors included.

No test or config changes were needed for vitest 4. All 635 tests pass unmodified, and the v8 coverage provider and thresholds work as before.

CI drops Node 18 and 20

Neither can run the new toolchain:

Package Requires
jsdom 30 ^22.22.2 || ^24.15.0 || >=26.0.0
vitest 4 ^20.0.0 || ^22.0.0 || >=24.0.0

Both versions are also past end-of-life — Node 18 in April 2025, Node 20 (Iron) in April 2026 — so CI was spending time proving the library works on runtimes nobody should be shipping on. The matrix is now 22 (LTS maintenance), 24 (active LTS) and 26 (current).

engines.node>=20.0.0

Deliberately one line lower than CI exercises, and worth being explicit about the trade:

  • The published bundle has no Node-version-specific code — it uses URL/URLSearchParams and nothing else. The constraint comes entirely from the test toolchain, which consumers never install.
  • Claiming >=22.0.0 would match exactly what's verified, but would make npm warn a large share of consumers away from a package that works fine for them.
  • Claiming >=16.0.0 is no longer defensible now that nothing below 22 is exercised at all.

>=20.0.0 is the honest middle. Nothing below Node 22 is verified, and CLAUDE.md records that plainly so the next person doesn't mistake the claim for evidence.

TypeScript 7 (PR #20) — closed, majors now ignored

It fails in npm run build, not type-check:

TypeError: Cannot read properties of undefined (reading 'useCaseSensitiveFileNames')
    at rollup-plugin-dts@6.1.1_typescript@5.7.3/.../rollup-plugin-dts.cjs

tsup bundles rollup-plugin-dts pinned against TypeScript 5.x, and TS 7 removed the API it calls, so declaration emit dies. Nothing in this repo can fix it. dependabot.yml now ignores typescript majors with the reason recorded and a note to remove the entry once tsup ships a TS 7-compatible rollup-plugin-dts — the same documented-blocker pattern used elsewhere for peer-capped toolchain deps.

Test Plan

  • npm test — 635 passing, unchanged from main, no test or config edits needed for vitest 4
  • npm run coverage — 93.77% statements / 88.36% branches, above the 80% gate
  • npm run type-check / lint / format:check — clean
  • npm run build — succeeds, all three entries emitted with declarations
  • Built artifact smoke-tested in bare Node: root entry, /server entry, and the rejection report all behave correctly
  • npm audit — 6 → 1 (low, dev-only, unfixable without upstream tsup)
  • CI green on Node 22/24/26 (plus format) — all four checks passing

Follow-ups

  1. Four GitHub Actions are 1–3 majors behind (checkout v4→v7, setup-node v4→v7, codecov v4→v7, gh-release v2→v3). Dependabot should raise these as one grouped PR; it hasn't yet, worth checking the ecosystem is running.
  2. The esbuild low advisory clears itself when tsup widens its esbuild range.
  3. Worth a 0.3.0 release once this lands — the /server entry, rejection reporting and the three capture options from feat: server-side normalization, rejection reporting and capture options #21 are all unreleased.

Supersedes the four Dependabot PRs, three of which could not pass on
their own.

Advisories go 6 -> 1. The esbuild -> vite -> vitest chain that survived
the last dependency pass is cleared by vitest 4. The one remaining is
esbuild 0.27.7 (LOW, arbitrary file read via the dev server on Windows);
the fix is esbuild 0.28.2 but tsup pins `esbuild: ^0.27.0`, so it cannot
be resolved here. This project runs no dev server and does not build on
Windows, so exposure is nil.

vitest and @vitest/coverage-v8 had to move together: coverage-v8@4
peer-requires the exact matching vitest, so Dependabot's separate PRs
each failed `npm ci` on the peer conflict — neither could land without
the other. That was a consequence of the ungrouped-majors rule added
last week, which is right in general and wrong for a lockstep family, so
dependabot.yml now groups the vitest packages across ALL update types.

No test or config changes were needed for vitest 4 — all 635 tests pass
unmodified, and the v8 coverage provider and thresholds work as before.

CI drops Node 18 and 20. Both are past end-of-life (18 in April 2025, 20
in April 2026) and neither can run the new toolchain: jsdom 30 requires
`^22.22.2 || ^24.15.0 || >=26`, vitest 4 requires `^20 || ^22 || >=24`.
The matrix is now 22 (LTS maintenance), 24 (active LTS) and 26 (current).

engines.node moves to >=20.0.0. This is deliberately one line lower than
CI exercises: the published bundle contains no Node-version-specific code
and the constraint comes entirely from the test toolchain, so claiming
>=22 would warn a large share of consumers away from a package that works
fine for them. Nothing below 22 is verified, and CLAUDE.md says so.

TypeScript 7 is not included. It fails in `npm run build`: tsup bundles
rollup-plugin-dts pinned against typescript 5.7.3, and TS 7 removed the
`useCaseSensitiveFileNames` API it calls, so declaration emit dies.
Nothing in this repo can fix it, so its majors are now ignored with the
reason recorded and a note to remove the entry once tsup catches up.
🤖 Generated with [Nori](https://noriagentic.com)

Co-Authored-By: Nori <contact@tilework.tech>
@jackmisner
jackmisner merged commit 8700f8c into main Aug 20, 2026
4 checks passed
@jackmisner
jackmisner deleted the chore/upgrade-test-toolchain branch August 20, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant