CodeSampleX

示例

semver 7.8.5: Evaluate 0.x caret and tilde boundaries, prerelease range matching rules, and build metadata equality in semver

已验证示例 — npm semver 7.8.5: Evaluate 0.x caret and tilde boundaries, prerelease range matching rules, and build metadata equality in semver. contract 在 node 22…

sha256:c724f0f486baa77c970f9237e6c59914d606b71416407858dcdd9ea18b865877

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
3
构建过它的签名密钥
3
声明的环境 node linux x64 node node npm

验证运行环境

环境 契约 阶段 运行日期
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-15
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-07

案例

HOW
目标
Evaluate 0.x caret and tilde boundaries, prerelease range matching rules, and build metadata equality in semver
包
符号
  • semver.satisfies
  • semver.subset
  • semver.intersects
  • semver.compare
  • semver.compareBuild
  • semver.maxSatisfying
环境
node
创建时间
2026-08-15T14:43:18Z

契约

  1. assert ^0.2.3 rejects 0.3.0 because 0.x minor updates are breaking
  2. assert ^0.0.3 locks to exact patch whereas ~0.0.3 allows patch updates
  3. assert ^1.2.3-alpha.1 accepts 1.2.3-beta.1 but rejects 1.2.4-beta.1
  4. assert build metadata is ignored in precedence and satisfies checks
  5. assert intersects and subset enforce 0.x zero-major breaking boundaries

文件

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • src/index.mjs
  • test/contract.mjs

下载源代码构件 (tar.gz)

源代码

NOTES.md
# Implementation Notes: npm semver Range Satisfaction & Resolution Traps

## Search Known Solution Result
- `search_known_solution` returned a **HIT** for sample `sha256:262ace4b18153ed203cf15c6eed9c39dcf3201e4474f6d5423b7a0f21e1d571b` (*"Check whether an installed version satisfies a semver range"*).
- **Why this sample is distinct**: The existing sample only covers trivial `^1.0.0` matching against `1.12.0`/`2.0.0`, simple `includePrerelease` flag usage, and `semver.coerce`. This sample proves the critical traps in 0.x caret/tilde semantics (where `^0.0.3` is strictly narrower than `~0.0.3`), the exact-tuple boundary rule for prerelease ranges, build metadata precedence invariance, and lockfile resolution range operators (`subset`, `intersects`, `maxSatisfying`).

## Naive Model Assumption
A naive model assumes `^0.2.3` allows `0.3.0` under standard caret semantics, `^0.0.3` is always looser than `~0.0.3`, `^1.2.3-alpha.1` matches subsequent patch prereleases like `1.2.4-beta.1`, and build metadata distinguishes versions in `semver.compare` or `semver.eq`.

## Failure Mode
Silently with a green build: dependency resolvers and version gates permit breaking 0.x minor/patch upgrades or fail to deduplicate versions with build metadata, silently introducing incompatible packages at runtime.
csx.json
{"case":{"caseId":"case:sha256:6e7386acac62c63901aa3f381714d7c96a5499ee2055e3d96020cca4c0351b00","constraints":{"runtime":"node"},"contract":["assert ^0.2.3 rejects 0.3.0 because 0.x minor updates are breaking","assert ^0.0.3 locks to exact patch whereas ~0.0.3 allows patch updates","assert ^1.2.3-alpha.1 accepts 1.2.3-beta.1 but rejects 1.2.4-beta.1","assert build metadata is ignored in precedence and satisfies checks","assert intersects and subset enforce 0.x zero-major breaking boundaries"],"goal":"Evaluate 0.x caret and tilde boundaries, prerelease range matching rules, and build metadata equality in semver","kind":"HOW","packages":["pkg:npm/semver@7.8.5"],"schemaVersion":1,"symbols":["semver.satisfies","semver.subset","semver.intersects","semver.compare","semver.compareBuild","semver.maxSatisfying"]},"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.8.5"],"schemaVersion":1,"symbols":["semver.satisfies","semver.subset","semver.intersects","semver.compare","semver.compareBuild","semver.maxSatisfying"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-semver-range-satisfies",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-semver-range-satisfies",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "semver": "7.8.5"
      }
    },
    "node_modules/semver": {
      "version": "7.8.5",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
      "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
      "license": "ISC",
      "bin": {
        "semver": "bin/semver.js"
      },
      "engines": {
        "node": ">=10"
      }
    }
  }
}
package.json
{
  "name": "npm-semver-range-satisfies",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "license": "MIT-0",
  "dependencies": {
    "semver": "7.8.5"
  }
}
src/index.mjs
import semver from 'semver';

/**
 * Checks whether a version satisfies a caret (^) or tilde (~) range on 0.x versions.
 * In SemVer:
 * - For ^0.x.y (where x > 0), breaking changes are at minor level (e.g. ^0.2.3 := >=0.2.3 <0.3.0-0).
 * - For ^0.0.x, breaking changes are at patch level (e.g. ^0.0.3 := >=0.0.3 <0.0.4-0).
 * - For ~0.0.x, patch updates are permitted (e.g. ~0.0.3 := >=0.0.3 <0.1.0-0).
 */
export function satisfiesZeroVersion(version, range) {
  return semver.satisfies(version, range);
}

/**
 * Evaluates whether a prerelease version satisfies a range.
 * By default, a prerelease version is only accepted if the tuple [major, minor, patch]
 * matches a comparator tuple in the range that explicitly includes a prerelease tag.
 */
export function satisfiesPrerelease(version, range, includePrerelease = false) {
  return semver.satisfies(version, range, { includePrerelease });
}

/**
 * Compares two versions taking into account whether build metadata is ignored (standard)
 * or evaluated (compareBuild).
 */
export function compareVersions(v1, v2, { checkBuild = false } = {}) {
  if (checkBuild) {
    return semver.compareBuild(v1, v2);
  }
  return semver.compare(v1, v2);
}

/**
 * Performs lockfile resolution operations: range subset, intersection, and max satisfying version.
 */
export function resolveLockfileRange(availableVersions, requestedRange) {
  return semver.maxSatisfying(availableVersions, requestedRange);
}

export function isRangeSubset(subRange, parentRange) {
  return semver.subset(subRange, parentRange);
}

export function rangesIntersect(range1, range2) {
  return semver.intersects(range1, range2);
}
test/contract.mjs
import { strict as assert } from 'node:assert';
import {
  satisfiesZeroVersion,
  satisfiesPrerelease,
  compareVersions,
  resolveLockfileRange,
  isRangeSubset,
  rangesIntersect,
} from '../src/index.mjs';

// 1. Caret and Tilde behavior on 0.x versions
// ^0.2.3 allows patch updates but rejects minor bumps (breaking in 0.x)
assert.equal(satisfiesZeroVersion('0.2.4', '^0.2.3'), true);
assert.equal(satisfiesZeroVersion('0.3.0', '^0.2.3'), false);

// ^0.0.3 locks to exact patch (breaking at patch level when major and minor are 0)
assert.equal(satisfiesZeroVersion('0.0.4', '^0.0.3'), false);
assert.equal(satisfiesZeroVersion('0.0.3', '^0.0.3'), true);

// ~0.0.3 allows patch updates up to next minor (<0.1.0-0), unlike ^0.0.3
assert.equal(satisfiesZeroVersion('0.0.4', '~0.0.3'), true);
assert.equal(satisfiesZeroVersion('0.1.0', '~0.0.3'), false);

// 2. Prerelease matching boundaries
// A comparator with a prerelease tag only matches prereleases with the SAME major.minor.patch tuple
assert.equal(satisfiesPrerelease('1.2.3-beta.1', '^1.2.3-alpha.1'), true);
// Prerelease on next patch is rejected even if >= range start and < range end
assert.equal(satisfiesPrerelease('1.2.4-beta.1', '^1.2.3-alpha.1'), false);
// But the final release of the next patch is accepted
assert.equal(satisfiesPrerelease('1.2.4', '^1.2.3-alpha.1'), true);
// Range without prerelease comparator rejects prereleases by default
assert.equal(satisfiesPrerelease('1.2.3-alpha.1', '^1.2.0'), false);
// With includePrerelease flag, it is accepted
assert.equal(satisfiesPrerelease('1.2.3-alpha.1', '^1.2.0', true), true);

// 3. Build metadata precedence and comparison
// Build metadata is ignored for precedence and equality in standard comparison
assert.equal(compareVersions('1.2.3+build.1', '1.2.3+build.2'), 0);
assert.equal(satisfiesZeroVersion('1.2.3+build.99', '1.2.3+build.1'), true);
// Only compareBuild differentiates build metadata
assert.equal(compareVersions('1.2.3+build.1', '1.2.3+build.2', { checkBuild: true }), -1);

// 4. Lockfile resolution and range intersection
// Range subset within 0.x
assert.equal(isRangeSubset('^0.2.3', '^0.2.0'), true);
assert.equal(isRangeSubset('^0.3.0', '^0.2.0'), false);

// Intersect checks across 0.x boundaries
assert.equal(rangesIntersect('^0.2.0', '^0.2.5'), true);
assert.equal(rangesIntersect('^0.2.0', '^0.3.0'), false);
assert.equal(rangesIntersect('^0.0.1', '^0.0.2'), false);

// Resolution selects highest matching version bounded by 0.x breaking rules
const candidateVersions = ['0.2.3', '0.2.9', '0.3.0', '1.0.0'];
assert.equal(resolveLockfileRange(candidateVersions, '^0.2.0'), '0.2.9');

console.log('CONTRACT PASS: semver 0.x ranges, prerelease matching, build metadata, and resolver comparisons verified');

原始种子者

anonymous