Equality and Relational Operators
Relevant source files
The following files were used as context for generating this wiki page:
Equality and Relational Operators in node-semver provide the logic necessary to compare Semantic Versioning (SemVer) strings and objects. These operators allow developers to determine if a version is greater than, less than, or equal to another, following the specific precedence rules defined by the SemVer 2.0.0 specification.
The system is built on a foundation of internal comparison functions that handle major, minor, and patch segments, as well as complex pre-release tag comparisons. These are exposed through high-level utility functions like gt, lt, and a polymorphic cmp function that handles various operator strings.
Core Comparison Logic
The primary comparison engine resides within the SemVer class and specialized identifier comparison functions. Comparison is performed by evaluating version segments in order: Major, Minor, Patch, and finally Pre-release.
Comparison Precedence
- Main Version: Compared numerically (Major -> Minor -> Patch).
- Pre-release Presence: A version without a pre-release tag always has higher precedence than an otherwise identical version with a pre-release tag.
- Pre-release Identifiers: Compared segment by segment. Numeric segments are compared numerically, and non-numeric segments are compared lexically in ASCII sort order.
The following diagram illustrates the high-level decision flow when comparing two versions:
The logic ensures that 1.2.3 is greater than 1.2.3-alpha.
Sources: semver.js:527-567, classes/semver.js:189-201
Global Operator Functions
The library exports several discrete functions for specific relational checks. These functions typically wrap the compare logic and return a boolean value.
| Function | Operator | Description |
|---|---|---|
eq(a, b, loose) | == | Returns true if version A is equivalent to version B. |
neq(a, b, loose) | != | Returns true if version A is not equivalent to version B. |
gt(a, b, loose) | > | Returns true if version A is greater than version B. |
gte(a, b, loose) | >= | Returns true if version A is greater than or equal to version B. |
lt(a, b, loose) | < | Returns true if version A is less than version B. |
lte(a, b, loose) | <= | Returns true if version A is less than or equal to version B. |
Sources: semver.js:705-731, index.js:23-28
The Polymorphic cmp Function
The cmp function acts as a centralized dispatcher that accepts a version string or object, an operator string, and a second version for comparison. It supports standard relational operators as well as strict identity checks (=== and !==).
Supported Operators
- Identity:
===,!==(Checks raw version strings or object version properties). - Equality: ``,
=,==. - Inequality:
!=. - Relational:
>,>=,<,<=.
const cmp = (a, op, b, loose) => {
switch (op) {
case '===':
if (typeof a === 'object') a = a.version
if (typeof b === 'object') b = b.version
return a === b
case '!==':
if (typeof a === 'object') a = a.version
if (typeof b === 'object') b = b.version
return a !== b
case '':
case '=':
case '==':
return eq(a, b, loose)
// ... other cases
default:
throw new TypeError(`Invalid operator: ${op}`)
}
}
Sources: functions/cmp.js:9-48, semver.js:733-772
Comparator and Range Intersections
Beyond simple version-to-version comparison, the library provides tools to check if different comparison requirements (Comparators) or sets of requirements (Ranges) overlap.
Comparator Intersection Logic
The intersects method on the Comparator class determines if there is any version that could satisfy two different comparators simultaneously. This is used to optimize range evaluations and detect impossible constraints (e.g., >2.0.0 <1.0.0).
Implementation Details
Identifier Comparison
Identifiers (the individual parts of a version or pre-release string) are compared using compareIdentifiers. This function differentiates between numeric and non-numeric strings:
- If both are numeric, they are compared as numbers.
- If one is numeric and the other is not, the numeric identifier is considered to have lower precedence.
- If both are non-numeric, they are compared lexically.
Sources: semver.js:638-653
Loose Mode
Most comparison functions accept a loose parameter (or an options object containing loose). When enabled, the parser allows for non-standard SemVer strings, such as those with a v prefix, leading zeros in numeric segments, or extra whitespace, before performing the comparison.
Sources: semver.js:275-320, test/integration/whitespace.js:15-28
Summary
The Equality and Relational Operators in node-semver provide a robust framework for comparing software versions. By implementing the precedence rules of the SemVer specification and offering flexible interfaces like high-level boolean functions and the polymorphic cmp dispatcher, the system ensures accurate version resolution and dependency management.