Skip to content

fix: prerelease version compare, non-integer avatar box, HEAD for reachability - #76

Merged
otnc merged 3 commits into
mainfrom
fix/version-compare-coords-and-reachability
Aug 29, 2026
Merged

fix: prerelease version compare, non-integer avatar box, HEAD for reachability#76
otnc merged 3 commits into
mainfrom
fix/version-compare-coords-and-reachability

Conversation

@otnc

@otnc otnc commented Aug 29, 2026

Copy link
Copy Markdown
Owner

What does this change?

Three independent correctness fixes found during a codebase review, each its own commit:

  1. isNewerVersion: a prerelease (12.0.0-rc.1) compared as newer than the release it precedes (12.0.0), backwards from real semver precedence — parseInt truncated "0-rc" down to its digits but still counted the suffix's own numeric parts (.1) as a real extra segment. Now drops everything from the first -/+ before segmenting. Added version.test.ts — this had no dedicated tests despite package/Twemoji/font update checks all depending on it.
  2. desaturateRegion: rounds its box outward to integer pixels before getImageData/putImageData, instead of passing the ratio-based (rarely integer) layout box straight through. Added a test for drawAvatar's grayscale fallback path, which had no coverage at all — verified it fails without the fix and passes with it.
  3. env's reachability check: uses HEAD instead of GET — it only cares whether a request completes at all (even an error response proves the network/TLS are fine, per its own doc comment), so it never needed the body. Added HttpClient.head().

Checklist

  • npm run ci passes (Biome lint and format)
  • npm run typecheck passes
  • npm run test passes
  • npm run build && npm run check:build passes
  • Tests cover the change
  • README updated, if the public API changed

otnc added 3 commits August 29, 2026 20:47
toSegments() split on "." without first dropping a "-rc.1"/"+build5"
suffix, so parseInt's usual truncate-at-the-first-non-digit-character
behavior ("0-rc" -> 0) left the suffix's own numeric parts as extra,
uncompared segments. "12.0.0-rc.1" parsed as [12, 0, 0, 1] against
"12.0.0"'s [12, 0, 0], so isNewerVersion('12.0.0', '12.0.0-rc.1') came back
true — a prerelease read as newer than the release it precedes, backwards
from real semver precedence, and the reverse comparison flagged the release
itself as not up to date even when it just shipped.

Fixed by dropping everything from the first "-"/"+" before segmenting.
This can't tell a prerelease apart from its release anymore (both parse to
the same core), but every real caller (npm dist-tags, Twemoji/Google Fonts
release tags) is a plain core version anyway, and comparing bare cores can
only ever call them equal — never flip which one is "newer".

Added version.test.ts; isNewerVersion had no dedicated tests despite package
update, Twemoji update and font update checks all depending on it.
box comes straight from ratio-based layout math (widthRatio * canvas width,
etc.) and is rarely integer-aligned, but getImageData/putImageData need
integer x/y/width/height. Passed through as-is, the fractional edge of the
region could be clipped or misaligned in the ctx.filter-unsupported
grayscale fallback, depending on how the binding coerces the values.

Floors the origin and ceils the far edge instead, so the integer rectangle
is always a superset of the original fractional one — the desaturated
region can end up a fraction of a pixel larger than painted, never smaller.

Added a test exercising this fallback path directly (drawAvatar had no
tests at all): forced supportsFilter() to false via a new test seam and
checked a pixel at the box's fractional far edge, which failed before this
fix and passes after it.
checkReachable() only cares whether a request completes at all — even an
error response proves the network and TLS are fine, per its own doc comment
— so it never needed the body a GET downloads. registry.npmjs.org's
`/makeitaquote/latest` in particular returns a full package manifest just to
confirm the registry is reachable.

Adds a head() method to HttpClient (identical to get(), just a different
method) rather than a special case: a non-2xx or even a 405 for HEAD itself
still proves reachability under this function's own definition, so no
per-host allowance is needed for a server that doesn't implement HEAD well.
@otnc
otnc merged commit 16105b5 into main Aug 29, 2026
7 checks passed
@otnc
otnc deleted the fix/version-compare-coords-and-reachability branch August 29, 2026 12:15
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