Skip to content

Update notices use locale collation instead of SemVer prerelease ordering #534

Description

@sylvesterkaczmarek

Summary

isNewerVersion() compares prerelease suffixes with:

new Intl.Collator("en", { numeric: true }).compare(candidate[4], installed[4])

SemVer prerelease precedence is not locale collation. Non-numeric identifiers are compared by ASCII code points and are case-sensitive, while numeric identifiers compare numerically and have lower precedence than non-numeric identifiers.

A concrete mismatch is case ordering:

  • current: 1.0.0-A
  • npm latest: 1.0.0-a

SemVer says 1.0.0-a has higher precedence because ASCII a sorts after A. English Intl.Collator orders a before A, so the current update check suppresses a valid update. The reverse pair can produce a false update notice.

Impact

This only affects prerelease versions, but update notices can be missing or incorrect for valid SemVer identifiers containing case differences. The same helper also delegates dot-separated identifier semantics to a locale API rather than implementing the SemVer rules it is intended to enforce.

Expected behavior

Compare prerelease identifiers according to SemVer:

  1. split on .;
  2. numeric vs numeric: compare integer value;
  3. numeric has lower precedence than non-numeric;
  4. non-numeric vs non-numeric: compare ASCII lexically;
  5. if all shared identifiers are equal, the longer identifier list has higher precedence.

Suggested fix

Replace the Intl.Collator comparison with a small deterministic prerelease comparator and add regressions for case-sensitive ASCII ordering, numeric identifiers, numeric-vs-text precedence, and prefix-length ordering.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions