#63

Resolve npm versions from bun.lock

Opendanielncwants to merge intofrom

Summary

Adds bun.lock to the npm version-resolution chain in core/version.rs, so opensrc path <pkg> --cwd <project> resolves the installed version in Bun projects.

Today only package-lock.json, pnpm-lock.yaml, and yarn.lock are detected. A Bun project with no node_modules (e.g. a fresh CI checkout) and none of those lockfiles falls through to the package.json range-stripping fallback — so a spec like ^1.0.0 resolves to 1.0.0 instead of the actually-installed version. Since Bun 1.2 the default lockfile is the text bun.lock (it replaced the binary bun.lockb), so this is increasingly common.

Approach

bun.lock is JSONC — trailing commas are valid — so a strict serde_json parse fails on it. This uses the jsonc-parser crate's serde bridge (parse_to_serde_value with allow_trailing_commas).

The top-level packages map keys an install entry to an array whose first element is the resolved name@version descriptor:

"packages": {
  "@mastra/core": ["@mastra/core@1.37.1", "", { /* meta */ }, "sha512-…"],
}

The version is read from element [0], not the key — which makes npm-alias entries resolve correctly, where the key differs from the resolved package:

"@ai-sdk/provider-utils-v6": ["@ai-sdk/provider-utils@4.0.27", …]

Resolution priority is unchanged for existing ecosystems; bun.lock slots in after yarn.lock and before the package.json fallback:

node_modules > package-lock > pnpm-lock > yarn.lock > bun.lock > package.json

Tests

6 new unit tests in core::version::tests: basic + scoped, prefers the resolved packages version over a workspace range, npm alias, missing package, no-substring-false-match (foo must not match foo-bar), and invalid input.

cargo test --manifest-path packages/opensrc/cli/Cargo.toml                 # 110 passing (104 + 6 new)
cargo fmt  --manifest-path packages/opensrc/cli/Cargo.toml -- --check      # clean
cargo clippy --manifest-path packages/opensrc/cli/Cargo.toml -- -D warnings # clean

End-to-end against a real ~219 KB bun.lock (isolated dir, only bun.lock present so the bun path is actually exercised):

lookupspec in workspaceresolved
@mastra/core1.37.11.37.1
ai6.0.1936.0.193
zod^3.25.76 (range)3.25.76
@ai-sdk/openai^3.0.67 (range)3.0.67
@mastra/memory1.20.01.20.0

Notes

  • Adds one dependency, jsonc-parser (serde feature); no new transitive crates beyond it. Happy to switch to a hand-rolled scan of the packages block instead if you'd prefer to avoid the dependency — the other lockfile parsers in this file are hand-rolled, so I can match that style.
  • Only the bun.lock text format (Bun >= 1.2) is supported; the legacy binary bun.lockb is not parsed. Projects with bun.lockb still resolve via node_modules/package.json as before.

Activity

3
vercel[bot]5mo ago

@danielnc is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

socket-security[bot]5mo ago

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

DiffPackageSupply Chain
Security
VulnerabilityQualityMaintenanceLicense
cargo/​jsonc-parser@​0.26.3

View full report