@glion/util-semver
v0.15.3
Published
Tiny, fast HL7v2 version and range utilities (basic comparators only)
Maintainers
Readme
@glion/util-semver
Parser, comparators, and range matcher for HL7v2-style numeric version strings.
What it does
Parses, compares, and matches HL7v2 versions like 2.5.1 or 2.3. Supports the =, <, <=, >, >= comparators and AND-combined ranges (">=2.0 <3.0"), plus helpers for sorting, increment, diff, and finding max/min versions that satisfy a range. Intentionally narrower than full semver: no prerelease, build metadata, wildcards, or ^/~ operators. Versions are capped at int32 and input lengths are bounded to protect against malformed input.
Install
npm install @glion/util-semverUse
import {
parse,
clean,
valid,
compare,
eq,
gt,
satisfies,
sort,
maxSatisfying,
minSatisfying,
increment,
diff,
Range,
} from "@glion/util-semver";
// Parse versions
parse("2.3"); // { major: 2, minor: 3, patch: 0 }
clean("2"); // "2.0.0"
valid("2.5.1"); // true
// Compare versions
compare("2.3.1", "2.4"); // -1
eq("2.5.0", "2.5"); // true
gt("2.5.1", "2.5.0"); // true
// Ranges
satisfies("2.5.1", ">=2.0 <3.0"); // true
satisfies("2.5.1", "2.5.1"); // true (exact match)
// Collection operations
sort(["2.5", "2.3.1", "2.10"]); // ["2.3.1", "2.5", "2.10"]
maxSatisfying(["2.3", "2.5", "3.0"], ">=2.0 <3.0"); // "2.5"
minSatisfying(["2.3", "2.5", "3.0"], ">=2.0 <3.0"); // "2.3"
// Manipulation
increment("2.5.1", "minor"); // "2.6.0"
diff("2.5.1", "2.6.0"); // "minor"API
Parsing and validation
parse(version: string): Hl7Version
Parses a version string into a structured object.
parse("2.5.1"); // { major: 2, minor: 5, patch: 1 }
parse("2.3"); // { major: 2, minor: 3, patch: 0 }
parse("2"); // { major: 2, minor: 0, patch: 0 }Throws VersionParseError if the format is invalid.
clean(version: string): string
Converts a version to canonical major.minor.patch format.
clean("2"); // "2.0.0"
clean("2.5"); // "2.5.0"
clean(" 2.5 "); // "2.5.0"Throws VersionParseError if the format is invalid.
valid(version: string): boolean
Checks if a string is a valid version. Never throws.
valid("2.5.1"); // true
valid("2"); // true
valid("HELLO"); // falseComparison
compare(a, b): -1 | 0 | 1
Compares two versions.
compare("2.3.1", "2.4"); // -1 (a < b)
compare("2.5.1", "2.5.1"); // 0 (a = b)
compare("2.6", "2.5.9"); // 1 (a > b)Comparison operators
eq(a, b)— equal tolt(a, b)— less thanlte(a, b)— less than or equalgt(a, b)— greater thangte(a, b)— greater than or equal
eq("2.5.0", "2.5"); // true
lt("2.3", "2.4"); // true
gte("2.5.1", "2.5"); // trueRange matching
satisfies(version, range): boolean
Checks if a version satisfies a range expression.
satisfies("2.5.1", ">=2.0 <3.0"); // true
satisfies("2.5.1", "2.5.1"); // true (exact match)
satisfies("2.5.1", ">=2.6"); // falseFor repeated checks, use a Range object to avoid re-parsing:
const range = new Range(">=2.0 <3.0");
for (const version of versions) {
if (satisfies(version, range)) {
/* ... */
}
}Range class
Pre-parsed range for efficient reuse.
const range = new Range(">=2.0 <3.0");
range.test("2.5.1"); // true
range.test("3.0.0"); // false
// Works with all range functions
satisfies("2.5.1", range);
maxSatisfying(versions, range);
minSatisfying(versions, range);Collection operations
sort(versions: string[]): string[]
Sorts versions in ascending order. Returns a new array; does not mutate.
sort(["2.5", "2.3.1", "2.10.0"]);
// ["2.3.1", "2.5", "2.10.0"]maxSatisfying(versions, range): string | null
Finds the highest version that satisfies a range.
maxSatisfying(["2.3.0", "2.5.1", "3.0.0"], ">=2.0 <3.0"); // "2.5.1"
maxSatisfying(["2.3.0", "2.5.1"], ">=3.0"); // nullminSatisfying(versions, range): string | null
Finds the lowest version that satisfies a range.
minSatisfying(["2.3.0", "2.5.1", "3.0.0"], ">=2.0 <3.0"); // "2.3.0"Version manipulation
increment(version, release): string
Increments a version component. Lower components reset to zero.
increment("2.5.1", "major"); // "3.0.0"
increment("2.5.1", "minor"); // "2.6.0"
increment("2.5.1", "patch"); // "2.5.2"diff(v1, v2): 'major' | 'minor' | 'patch' | null
Determines which component differs between versions.
diff("2.5.1", "3.0.0"); // "major"
diff("2.5.1", "2.6.0"); // "minor"
diff("2.5.1", "2.5.2"); // "patch"
diff("2.5.1", "2.5.1"); // nullErrors
import { VersionParseError, RangeParseError } from "@glion/util-semver";
try {
parse("INVALID");
} catch (e) {
if (e instanceof VersionParseError) {
console.log(e.input); // "INVALID"
console.log(e.reason); // "expected format: major.minor.patch..."
}
}
try {
satisfies("2.5.1", "INVALID_RANGE");
} catch (e) {
if (e instanceof RangeParseError) {
console.log(e.token);
console.log(e.reason);
}
}valid(version)never throws — returnsfalsefor invalid input.parse(),clean(),compare(),satisfies(), etc. throw on invalid input.
Version comparison rules
Version format
- Generic numeric versions:
major[.minor][.patch]. - Missing components default to 0:
"2"→{ major: 2, minor: 0, patch: 0 }. - Whitespace is trimmed:
" 2.5.1 "→"2.5.1". - No prerelease or build metadata.
- No wildcards, hyphen ranges, or
^/~operators.
Range syntax
Operators:
=or omitted — exact match<— less than<=— less than or equal>— greater than>=— greater than or equal
Multiple comparators are space-separated with AND semantics — all must be satisfied:
"2.5.1"; // Exact match
">=2.0"; // Greater than or equal to 2.0
">=2.0 <3.0"; // Between 2.0 (inclusive) and 3.0 (exclusive)
">=2.3 <2.6 >2.4"; // Multiple AND conditionsInput limits
- Versions are capped at 100 characters; ranges at 1000 characters. Longer inputs throw
VersionParseErrororRangeParseError. - Version components are capped at 2³¹−1; overflow throws
VersionParseError.
Part of Glion
@glion/util-semver is part of Glion, the application framework for HL7v2. See the Glion README for the full package catalog and architecture.
