fix: declare the disjoint Node range pdf-parse actually supports - #71
Conversation
package.json claimed `>=20.16.0`, but pdf-parse@2.4.5 declares `>=20.16.0 <21 || >=22.3.0` — a disjoint range. We were therefore claiming support for Node 21.x and 22.0-22.2, where an engine-strict install fails or PDF extraction is unavailable. The README's "20.16.0 or newer" repeated the same overclaim, and that README ships inside the published tarball. CI could not have caught this: the matrix pins `22.x`, which resolves to a current 22 release far past 22.3, so the gap is invisible to it. Adds __tests__/unit/engine-range.test.ts, which reads pdf-parse's own engines field from node_modules and fails if ours ever admits a version pdf-parse rejects. Verified it fails against the previous `>=20.16.0`, naming 21.0.0, 21.7.3, 22.0.0 and 22.2.0. This matters because the range is inherited from a dependency and will otherwise rot silently the next time pdf-parse moves it. semver was only present as an undeclared transitive; it and @types/semver are now proper devDependencies. Neither reaches consumers — the `files` allowlist excludes tests. Reported by Codex on #70. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Shipped in 2.0.0. Verified in the published tarball: Credit where it's due: this came from the Codex review on #70, and it was a genuinely good catch. The overclaim would otherwise have shipped inside 2.0.0 — both as the It's also the kind of defect a green CI run actively disguises. The matrix pins Hence the drift guard rather than just the one-line fix: the range is inherited from a dependency, so a hardcoded string has no way to notice when |
Follow-up to #70, addressing the P2 Codex raised there. The finding is correct and I verified it independently.
The problem
pdf-parse@2.4.5declares:That range is disjoint. Our
package.jsonsaid>=20.16.0, so we claimed support for versions pdf-parse rejects:On those four, users hit an engine-strict install failure or find PDF extraction unavailable at runtime.
The README section added in #70 repeated the same overclaim ("20.16.0 or newer") — and since #70 added
README.mdto thefilesallowlist, that text now ships inside the published tarball.Why CI could not have caught it
The matrix pins
22.x, which resolves to a current 22 release far past 22.3. The gap is structurally invisible to a floating matrix — no amount of green CI would have surfaced it.The fix
package.jsonengines.node→>=20.16.0 <21 || >=22.3.0AGENTS.mdupdated to matchDrift guard
__tests__/unit/engine-range.test.tsreads pdf-parse'senginesfromnode_modulesand asserts ours never admits a version pdf-parse rejects.This is the part that matters beyond today's fix: the range is inherited from a dependency, so it will rot silently the next time pdf-parse moves it. A hardcoded string in
package.jsonhas no mechanism to notice.Verified the test actually catches the bug — reverting
enginesto>=20.16.0fails it, naming21.0.0,21.7.3,22.0.0,22.2.0.semverwas present only as an undeclared transitive dependency; it and@types/semverare now proper devDependencies. Neither reaches consumers — thefilesallowlist excludes tests, and the tarball is unchanged at 80 files / 483 kB.Verification
Local Node 24.15.0: lint clean, build OK, 284/284 tests across 28 suites.
🤖 Generated with Claude Code