Minimum Version Calculation
Relevant source files
The following files were used as context for generating this wiki page:
- ranges/min-version.js
- test/ranges/min-version.js
- semver.js
- classes/range.js (Included via
semver.jsimplementation) - classes/semver.js (Included via
semver.jsimplementation) - index.js
- README.md
Minimum Version Calculation is a core utility within the node-semver library designed to determine the lowest possible semantic version that satisfies a given range. This functionality is essential for dependency resolution where a system needs to identify the baseline requirement for a package. Unlike minSatisfying, which picks the lowest version from a provided list, minVersion calculates the theoretical absolute minimum allowed by the range syntax itself.
Sources: ranges/min-version.js, README.md:255-256
Core Logic and Architecture
The calculation logic is encapsulated in the minVersion function. It operates by parsing a range string into a Range object, which consists of one or more "OR-ed" sets of comparators. The function iterates through these sets to find the lowest possible version across all logical branches of the range.
Calculation Process
- Initial Checks: The function first checks if standard baseline versions
0.0.0or0.0.0-0satisfy the range usingrange.test(). If they do, they are returned immediately as the absolute minimum. - Comparator Iteration: If basic baselines do not satisfy the range, the engine iterates through each comparator set.
- Operator Handling: For each comparator in a set, the logic evaluates the operator:
>(Greater Than): Increments the patch version (e.g.,>1.0.0becomes1.0.1) or appends a.0to a prerelease (e.g.,>1.0.0-alphabecomes1.0.0-alpha.0).>=(Greater Than or Equal) or Empty/=: Uses the version as-is (e.g.,>=1.2.3becomes1.2.3).<or<=: These are ignored as they define upper bounds rather than minimums.
- Selection: The function tracks the highest minimum within a single comparator set (intersection) and then the lowest minimum across different sets (union).
Sources: ranges/min-version.js:7-60, semver.js:1296-1349
Logic Flow Diagram
The following diagram illustrates the decision-making process for determining the minimum version from a range.
Sources: ranges/min-version.js:10-63
Key Functions and Components
| Component | Description | Reference |
|---|---|---|
minVersion(range, loose) | Main entry point that calculates the lowest version for a range. | ranges/min-version.js:7 |
Range | Class that parses range strings (e.g., `^1.2.3 | |
SemVer | Class representing a single version; used to increment or clone versions during calculation. | semver.js:296 |
gt(v1, v2, loose) | Comparison function used to compare candidate minimum versions. | semver.js:644 |
Behavior by Range Type
The calculation varies significantly based on the advanced syntax used in the range.
Examples of Calculated Minimums
| Range Input | Resulting Min Version | Logic Applied |
|---|---|---|
* | 0.0.0 | Baseline test satisfies. |
1.0.0 | 1.0.0 | Exact equality. |
~1.1.0 | 1.1.0 | Desugars to >=1.1.0 <1.2.0. |
^1.1.1-beta | 1.1.1-beta | Prerelease inclusion. |
>1.0.0 | 1.0.1 | Increment patch of non-prerelease. |
>1.0.0-beta | 1.0.0-beta.0 | Append .0 to prerelease. |
1.1 - 1.8.0 | 1.1.0 | Partial version expansion. |
<2 | 0.0.0 | Lowest possible global version. |
Sources: test/ranges/min-version.js:10-62, semver.js:933-1090
Implementation Details
The implementation ensures that cloning occurs when manipulating versions to avoid side effects on the Range or Comparator objects.
// From ranges/min-version.js
comparators.forEach((comparator) => {
// Clone to avoid manipulating the comparator's semver object.
const compver = new SemVer(comparator.semver.version)
switch (comparator.operator) {
case '>':
if (compver.prerelease.length === 0) {
compver.patch++
} else {
compver.prerelease.push(0)
}
compver.raw = compver.format()
/* fallthrough */
case '':
case '>=':
if (!setMin || gt(compver, setMin)) {
setMin = compver
}
break
// ...
}
})
Sources: ranges/min-version.js:26-42
Error Handling and Edge Cases
If a range is logically impossible (e.g., >4 <3), the function will return null because no version, including the calculated candidates, can satisfy the range.test(minver) check at the end of the process.
Sources: ranges/min-version.js:63, test/ranges/min-version.js:70
Minimum Version Calculation provides a deterministic way to find the floor of a version range by evaluating the structural constraints of semantic versioning, ensuring that the resulting version is the absolute lowest point of entry for the specified range.