Skip to content

Resolve npm versions from bun.lock#63

Open
danielnc wants to merge 1 commit into
vercel-labs:mainfrom
danielnc:feat/bun-lockfile-support
Open

Resolve npm versions from bun.lock#63
danielnc wants to merge 1 commit into
vercel-labs:mainfrom
danielnc:feat/bun-lockfile-support

Conversation

@danielnc

Copy link
Copy Markdown

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):

lookup spec in workspace resolved
@mastra/core 1.37.1 1.37.1
ai 6.0.193 6.0.193
zod ^3.25.76 (range) 3.25.76
@ai-sdk/openai ^3.0.67 (range) 3.0.67
@mastra/memory 1.20.0 1.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.

Add bun.lock to the lockfile resolution chain so `opensrc path <pkg>
--cwd <project>` resolves the installed version in Bun projects. Since
Bun 1.2 the default lockfile is the text `bun.lock` (it replaced the
binary `bun.lockb`).

Previously only package-lock.json, pnpm-lock.yaml and yarn.lock were
detected, so a Bun project with no node_modules (e.g. a fresh CI
checkout) fell through to the package.json range-stripping fallback,
which returns the declared range (^1.0.0 -> 1.0.0) rather than the
actually-installed version.

bun.lock is JSONC (trailing commas are valid), so it is parsed with the
jsonc-parser crate's serde bridge rather than serde_json directly. The
top-level `packages` map keys an install entry to an array whose first
element is the resolved "name@version" descriptor; the version is read
from element [0] (not the key) so npm-alias entries resolve correctly,
e.g. "@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

Adds 6 unit tests (basic + scoped, prefers resolved over workspace
range, npm alias, missing package, no-substring-false-match, invalid
input).
@vercel

vercel Bot commented May 31, 2026

Copy link
Copy Markdown

@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

Copy link
Copy Markdown

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

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcargo/​jsonc-parser@​0.26.3100100100100100

View full report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant