Sample
semver 7.7.1: Increment release versions across standard and prerelease types, classify version transitions with diff, coerce non-semver strings with directional parsing, and extract range minimum bounds in semver
Verified sample for npm semver 7.7.1: Increment release versions across standard and prerelease types, classify version transitions with diff, coerce…
sha256:2caaa3947a31083952cbced03a09ecd5209b400da5eca1ebc6360e2de7edaf6f
This network offers one thing: a sample that builds. It ran the sample in a sandbox and kept the signed receipt. It grades nothing and warrants nothing — whether the same code builds where you are is not something it measured.
How many distinct signing keys filed a passing contract receipt. One is the author alone; more than one means somebody else built it too. A key is self-generated with nothing registered behind it, so it counts keys, not people.
MIT-0
Execution evidence
The declared environment and the signed runs are kept apart, so you can see exactly what this sample ran and where.
- Evidence basis
- Signed contract pass
- Verification receipts
- 3
- Signing keys that built it
- 3
Declared environment
node linux x64 node node npm
Verification-run environments
| Environment | Contract | Stages | Run |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-17 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-09-08 |
Case
HOW- Goal
- Increment release versions across standard and prerelease types, classify version transitions with diff, coerce non-semver strings with directional parsing, and extract range minimum bounds in semver
- Packages
- Symbols
-
- semver.inc
- semver.diff
- semver.coerce
- semver.minVersion
- semver.clean
- semver.gtr
- semver.ltr
- Environment
- node
- Created
- 2026-08-17T15:42:37Z
Contract
- semver.inc with patch on a prerelease version strips the prerelease tag to produce the final release without double-incrementing the patch number
- semver.inc with identifierBase configures initial prerelease numeric suffixes or omits them when false
- semver.diff distinguishes patch, minor, major, prepatch, preminor, and premajor transitions and returns null for identical versions
- semver.coerce extracts valid SemVer versions from arbitrary strings with standard left-to-right or right-to-left scanning
- semver.minVersion resolves the lowest satisfying version for inclusive and exclusive range comparators
- semver.clean sanitizes version strings and trims build metadata while semver.gtr and semver.ltr test range bounds
Files
- NOTES.md
- csx.json
- package-lock.json
- package.json
- src/index.mjs
- test/contract.mjs
Source
# Implementation Notes: semver Version Incrementation, Difference Classification, and Range Extraction
## Search Known Solution Result
- `search_known_solution` returned a HIT for sample `sha256:c724f0f486baa77c970f9237e6c59914d606b71416407858dcdd9ea18b865877` ("Evaluate 0.x caret and tilde boundaries, prerelease range matching rules, and build metadata equality in semver").
- **Distinct Behaviour Tested**: While the existing sample focuses on 0.x caret/tilde boundaries, prerelease range matching rules, and build metadata comparison, this sample proves version incrementation semantics (`inc`) across prerelease and standard release types (including patch resolution and `identifierBase`), version transition classification (`diff`), string version coercion with directional parsing (`coerce`), and range minimum bound extraction (`minVersion`).
## Pinned Release
- Pinned `semver` at version `7.7.1` on Node.js.
## Observed Behaviour
1. **Prerelease Increment to Release**: Incrementing a prerelease version (`1.2.4-beta.1`) with release type `'patch'` strips the prerelease tag and locks directly to `'1.2.4'` without double-incrementing the patch component. Incrementing with `'minor'` or `'major'` increments the respective component and zeroes out subordinate components (`1.3.0` and `2.0.0`).
2. **Identifier Base Configuration**: `semver.inc` supports `identifierBase` parameter values: passing `'1'` produces `1.2.4-alpha.1`, while `false` produces `1.2.4-alpha` without numeric suffixes.
3. **Difference Classification**: `semver.diff` accurately distinguishes `'patch'`, `'minor'`, `'major'`, `'prepatch'`, `'preminor'`, and `'premajor'` transitions between version pairs, returning `null` when versions are identical.
4. **String Coercion & Directional Parsing**: `semver.coerce` extracts valid 3-part SemVer instances from unformatted strings (e.g. `'v1.2'` -> `'1.2.0'`, `'package-4.5.6.7-alpha'` -> `'4.5.6'`). Passing `{ rtl: true }` scans the string from right to left, isolating the rightmost 3-part version tuple (e.g. `'rev 1.2.3.4'` -> `'2.3.4'`).
5. **Range Lower-Bound Extraction**: `semver.minVersion` resolves the minimum discrete version satisfying a comparator range: for inclusive bounds (`>=1.2.3`), it returns `'1.2.3'`, while for exclusive bounds (`>1.2.3`), it advances to the lowest possible integer patch release (`'1.2.4'`).
6. **Sanitization and Range Extremes**: `semver.clean` strips whitespace, `=`/`v` prefixes, and build metadata while preserving prerelease tags; `semver.gtr` and `semver.ltr` verify whether versions lie strictly outside a range.
{"case":{"caseId":"case:sha256:9319ea13f8d7f5bbd2ba2918f9dfca495688913c929f7e2a0c03a4f2a82421a0","contract":["semver.inc with patch on a prerelease version strips the prerelease tag to produce the final release without double-incrementing the patch number","semver.inc with identifierBase configures initial prerelease numeric suffixes or omits them when false","semver.diff distinguishes patch, minor, major, prepatch, preminor, and premajor transitions and returns null for identical versions","semver.coerce extracts valid SemVer versions from arbitrary strings with standard left-to-right or right-to-left scanning","semver.minVersion resolves the lowest satisfying version for inclusive and exclusive range comparators","semver.clean sanitizes version strings and trims build metadata while semver.gtr and semver.ltr test range bounds"],"goal":"Increment release versions across standard and prerelease types, classify version transitions with diff, coerce non-semver strings with directional parsing, and extract range minimum bounds in semver","kind":"HOW","packages":["pkg:npm/semver@7.7.1"],"schemaVersion":1,"symbols":["semver.inc","semver.diff","semver.coerce","semver.minVersion","semver.clean","semver.gtr","semver.ltr"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/semver@7.7.1"],"schemaVersion":1,"symbols":["semver.inc","semver.diff","semver.coerce","semver.minVersion","semver.clean","semver.gtr","semver.ltr"],"verifierAdapter":"node-typescript@1"}
{
"name": "npm-semver-version-depth",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "npm-semver-version-depth",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"semver": "7.7.1"
}
},
"node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
}
}
}
{
"name": "npm-semver-version-depth",
"version": "1.0.0",
"private": true,
"type": "module",
"license": "MIT-0",
"dependencies": {
"semver": "7.7.1"
}
}
import semver from 'semver';
/**
* Increments a version according to release type and options.
*/
export function incrementVersion(version, releaseType, identifier, identifierBase) {
return semver.inc(version, releaseType, identifier, identifierBase);
}
/**
* Returns the difference type between two versions.
*/
export function diffVersions(v1, v2) {
return semver.diff(v1, v2);
}
/**
* Coerces a string into a valid SemVer version string.
*/
export function coerceVersion(input, options = {}) {
const result = semver.coerce(input, options);
return result ? result.version : null;
}
/**
* Resolves the lowest possible version satisfying a given range.
*/
export function getMinVersion(range) {
const result = semver.minVersion(range);
return result ? result.version : null;
}
/**
* Cleans a version string by stripping leading whitespace, =, v, and build metadata.
*/
export function cleanVersion(input) {
return semver.clean(input);
}
/**
* Evaluates whether a version is strictly greater than all versions matching a range.
*/
export function isGreaterThanRange(version, range) {
return semver.gtr(version, range);
}
/**
* Evaluates whether a version is strictly less than all versions matching a range.
*/
export function isLessThanRange(version, range) {
return semver.ltr(version, range);
}
import { strict as assert } from 'node:assert';
import {
incrementVersion,
diffVersions,
coerceVersion,
getMinVersion,
cleanVersion,
isGreaterThanRange,
isLessThanRange,
} from '../src/index.mjs';
// 1. Version incrementation semantics
// Incrementing a prerelease version with 'patch' strips the prerelease and settles on the current patch
assert.equal(incrementVersion('1.2.4-beta.1', 'patch'), '1.2.4');
// Incrementing with 'minor' or 'major' resets lower components
assert.equal(incrementVersion('1.2.4-beta.1', 'minor'), '1.3.0');
assert.equal(incrementVersion('1.2.4-beta.1', 'major'), '2.0.0');
// 2. Prerelease incrementation and identifierBase
// Standard prerelease increment on a release version advances patch to a new prerelease
assert.equal(incrementVersion('1.2.3', 'prerelease', 'beta'), '1.2.4-beta.0');
// Consecutive prerelease increments bump the prerelease index
assert.equal(incrementVersion('1.2.4-beta.0', 'prerelease', 'beta'), '1.2.4-beta.1');
// identifierBase controls the starting numeral or omission
assert.equal(incrementVersion('1.2.3', 'prerelease', 'alpha', '1'), '1.2.4-alpha.1');
assert.equal(incrementVersion('1.2.3', 'prerelease', 'alpha', false), '1.2.4-alpha');
// 3. Version difference classification (diff)
assert.equal(diffVersions('1.2.3', '1.2.4'), 'patch');
assert.equal(diffVersions('1.2.3', '1.3.0'), 'minor');
assert.equal(diffVersions('1.2.3', '2.0.0'), 'major');
assert.equal(diffVersions('1.2.3', '1.2.4-alpha.0'), 'prepatch');
assert.equal(diffVersions('1.2.3', '1.3.0-alpha.0'), 'preminor');
assert.equal(diffVersions('1.2.3', '2.0.0-alpha.0'), 'premajor');
assert.equal(diffVersions('1.2.3', '1.2.3'), null);
// 4. Coercion and directional parsing
assert.equal(coerceVersion('v1.2'), '1.2.0');
assert.equal(coerceVersion('package-4.5.6.7-alpha'), '4.5.6');
// RTL parsing extracts the rightmost 3-part version tuple
assert.equal(coerceVersion('rev 1.2.3.4', { rtl: true }), '2.3.4');
// Non-version string returns null
assert.equal(coerceVersion('non-version-string'), null);
// 5. Minimum range version extraction
// Inclusive lower bound returns the exact lower bound
assert.equal(getMinVersion('>=1.2.3 <2.0.0'), '1.2.3');
// Exclusive lower bound '>1.2.3' returns the lowest discrete satisfying integer version '1.2.4'
assert.equal(getMinVersion('>1.2.3'), '1.2.4');
assert.equal(getMinVersion('^0.2.3'), '0.2.3');
assert.equal(getMinVersion('~1.2'), '1.2.0');
// 6. Sanitization and range bounding (clean, gtr, ltr)
assert.equal(cleanVersion(' =v1.2.3 '), '1.2.3');
// clean preserves prerelease tag but strips build metadata
assert.equal(cleanVersion(' =v1.2.3-beta.0+build.101 '), '1.2.3-beta.0');
// clean on a range or invalid semver returns null
assert.equal(cleanVersion('^1.2.3'), null);
// gtr and ltr determine position relative to an entire range
assert.equal(isGreaterThanRange('2.0.0', '^1.0.0'), true);
assert.equal(isGreaterThanRange('1.5.0', '^1.0.0'), false);
assert.equal(isLessThanRange('0.9.9', '^1.0.0'), true);
assert.equal(isLessThanRange('1.0.0', '^1.0.0'), false);