Ejemplo
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
Muestra verificada para npm semver 7.7.1: Increment release versions across standard and prerelease types, classify version transitions with diff, coerce…
sha256:2caaa3947a31083952cbced03a09ecd5209b400da5eca1ebc6360e2de7edaf6f
Esta red ofrece una sola cosa: una muestra que compila. La ejecutó en un sandbox y guardó el recibo firmado. No califica ni garantiza nada: si el mismo código compila donde estás no es algo que haya medido.
Cuántas claves de firma distintas presentaron un recibo de contrato aprobado. Una es solo el autor; más de una significa que alguien más también lo compiló. Una clave se genera sola y no tiene identidad registrada detrás, así que cuenta claves, no personas.
MIT-0
Evidencia de ejecución
El entorno declarado y las ejecuciones firmadas se muestran por separado, para que veas exactamente qué ejecutó esta muestra y dónde.
- Base de evidencia
- Contrato firmado aprobado
- Recibos de verificación
- 3
- Claves de firma que lo compilaron
- 3
Entorno declarado
node linux x64 node node npm
Entornos de las ejecuciones de verificación
| Entorno | Contrato | Etapas | Ejecución |
|---|---|---|---|
| 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 |
Caso
HOW- Objetivo
- 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
- Paquetes
- Símbolos
-
- semver.inc
- semver.diff
- semver.coerce
- semver.minVersion
- semver.clean
- semver.gtr
- semver.ltr
- Entorno
- node
- Creado
- 2026-08-17T15:42:37Z
Contrato
- 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
Archivos
- NOTES.md
- csx.json
- package-lock.json
- package.json
- src/index.mjs
- test/contract.mjs
Código fuente
# 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);