Version Coercion
Relevant source files
The following files were used as context for generating this wiki page:
Version Coercion is a feature within the node-semver library designed to provide a forgiving translation of non-semver strings into valid Semantic Versioning (SemVer) objects. It is intended to extract version information from arbitrary text, such as release notes or file paths, by identifying numeric patterns that resemble versions.
The coercion logic identifies the first digit in a string and consumes subsequent characters that satisfy a partial or full version format (e.g., 1, 1.2, or 1.2.3). It handles various edge cases, including component length limits, numeric safety constraints, and optional right-to-left parsing for complex strings.
Sources: README.md:416-427, functions/coerce.js:1-10
Core Coercion Logic
The coercion process follows a specific hierarchy of checks and transformations. If the input is already a SemVer object, it is returned as-is. Numbers are converted to strings before processing. The system then uses regular expressions to isolate version components from the surrounding noise.
Coercion Workflow
The following diagram illustrates the logical flow of the coerce function:
The workflow ensures that the most relevant version-like string is extracted based on the provided direction (Left-to-Right or Right-to-Left).
Sources: functions/coerce.js:1-63
Technical Constraints and Specifications
The coercion system enforces strict limits to ensure performance and validity. These limits prevent issues like Regular Expression Denial of Service (ReDoS) and ensure the resulting version remains within JavaScript's safe integer range.
| Constraint | Value | Description |
|---|---|---|
| Max Total Length | 256 characters | The maximum length allowed for the input version string. |
| Max Component Length | 16 characters | Maximum digits allowed per version part (Major, Minor, Patch). |
| Max Integer Value | Number.MAX_SAFE_INTEGER | Components exceeding 2^53 - 1 are considered invalid. |
| Default Minor/Patch | 0 | If minor or patch components are missing, they default to zero. |
Sources: semver.js:23-27, README.md:424-427, functions/coerce.js:56-61
Coercion Options
The coerce function accepts an optional options object to modify its behavior.
RTL (Right-to-Left) Mode
By default, coercion finds the first match from the left. In RTL mode, the engine searches for the right-most coercible string. This is useful when a string contains multiple version-like patterns, such as a file path 1.2.3/a/b/c/2.3.4, where the latter is the intended version.
includePrerelease Mode
When enabled, the coercion engine will also attempt to capture prerelease and build metadata identifiers following the version core.
// Example Coercion with options
coerce('1.2.3.4-rc.5', { includePrerelease: true }) // Result: 1.2.3-rc.5
coerce('1.2.3.4-rc.5', { includePrerelease: false }) // Result: 1.2.3
Sources: functions/coerce.js:24-49, test/functions/coerce.js:100-112
Implementation Details
The implementation relies on specific internal regular expressions defined in the library's registry (re and t).
- LTR Matching: Uses
re[t.COERCE]orre[t.COERCEFULL]. - RTL Matching: Uses a global search pattern (
re[t.COERCERTL]orre[t.COERCERTLFULL]) that manually updateslastIndexto identify overlapping matches and find the terminus closest to the end of the string. - Safety: Uses
safeRevariants which replace greedy tokens with fixed-length repetitions to prevent ReDoS.
// From functions/coerce.js
const major = match[2]
const minor = match[3] || '0'
const patch = match[4] || '0'
const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ''
const build = options.includePrerelease && match[6] ? `+${match[6]}` : ''
return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options)
Sources: functions/coerce.js:56-62, semver.js:33-55
Examples of Coercion Behavior
The following table demonstrates how various inputs are transformed by the coercion logic based on unit tests.
| Input String | Coerced Result | Note |
|---|---|---|
v1 | 1.0.0 | Leading 'v' is stripped, minor/patch defaulted. |
version 1.2 | 1.2.0 | Surrounding text ignored. |
42.6.7.9.3-alpha | 42.6.7 | Truncated to the first three segments. |
1.2.3.4 | 2.3.4 (if RTL: true) | Extracts right-most valid sequence. |
9999999999999999.1.1 | 1.1.0 | Major component too long (>16 chars), ignored. |
Sources: test/functions/coerce.js:40-120, README.md:419-424
Summary
Version Coercion provides a robust mechanism for extracting Semantic Versions from unstructured data. By balancing flexibility (ignoring non-digit characters) with strict constraints (maximum component lengths and safe integer checks), it ensures that the resulting SemVer objects are safe for subsequent comparison and range-matching operations within the node-semver ecosystem.
Sources: functions/coerce.js, CHANGELOG.md:31