Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
42e95be
fix(purl): percent-decode purl components from the API
mikolalysenko Jun 11, 2026
c3c012f
feat(vendor): auto-force staging on content mismatch + correct alread…
mikolalysenko Jun 11, 2026
7363c65
feat(vendor): take over exact-version override pins (pnpm + yarn berry)
mikolalysenko Jun 11, 2026
adc5179
feat(scan): prune lifecycle for vendored packages
mikolalysenko Jun 11, 2026
7042cbc
test: e2e coverage for encoded scoped purls, mismatch annotation, pru…
mikolalysenko Jun 11, 2026
1a2dc4a
feat(vendor): lockfile inventory module for npm-family locks
mikolalysenko Jun 11, 2026
9c93b90
feat(vendor): registry_fetch — verified pristine-artifact fetching
mikolalysenko Jun 11, 2026
18822dc
feat(vendor,scan): auto-fetch missing packages + lockfile/ledger disc…
mikolalysenko Jun 11, 2026
430145a
feat(vendor): yarn berry checksum-verified fetch + ledger artifact st…
mikolalysenko Jun 11, 2026
16e7e54
feat(vendor): cargo + golang lockfile inventory and verified fetch
mikolalysenko Jun 11, 2026
b5e9f63
feat(vendor): composer + gem + pypi lockfile inventory and verified f…
mikolalysenko Jun 11, 2026
772f98d
feat(scan): all-ecosystem lockfile supplement + docs
mikolalysenko Jun 11, 2026
0426e0b
feat(apply): beforeHash mismatch warns and applies the full blob by d…
mikolalysenko Jun 11, 2026
64c59f1
polish(apply): decode percent-encoded purls in human output
mikolalysenko Jun 11, 2026
18b4cb1
feat(vendor): hold patch blobs in memory — vendoring writes no .socke…
mikolalysenko Jun 12, 2026
c92f6b2
feat(repair): rebuild missing/corrupt vendored artifacts + no-ledger …
mikolalysenko Jun 12, 2026
c05805e
fix(pnpm): bind vendor edits to name@VERSION — multi-version vendorin…
mikolalysenko Jun 12, 2026
6091280
test(docker): pin scan --sync to --strict where apply --force must st…
mikolalysenko Jun 12, 2026
cb1b0a6
test(docker): pin the content_mismatch_overwritten warning in the for…
mikolalysenko Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(vendor): lockfile inventory module for npm-family locks
Read-only inventories of the dependency set a lockfile resolves,
independent of what is installed: name/version/purl plus the lock's
artifact URL and content verifier (typed LockIntegrity: SRI, yarn sha1
fragment, berry cache-zip checksum, sha256 hex, go.sum h1 — the latter
two for the ecosystems that follow). Powers scan's lockfile supplement
and vendor's missing-package fetch.

Covers all five npm flavors via detect_npm_lock_flavor (package-lock/
shrinkwrap, pnpm v9, yarn classic, yarn berry, bun). Fail-soft per
entry, fail-closed per value (names/versions path-guarded; git/file/
link/workspace specs and our own vendored entries excluded; duplicate
instances dedup preferring a verifier). lookup() bridges percent-
encoded manifest purls. Reuses the wiring backends' parsers via
pub(super) visibility bumps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
  • Loading branch information
mikolalysenko and claude committed Jun 11, 2026
commit 1a2dc4a29ecfe2f7f208e01135c47bb32b8658f6
12 changes: 6 additions & 6 deletions crates/socket-patch-core/src/patch/vendor/bun_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ fn revert_one_record(
// ───────────────────────── conservative line grammar ──────────────────────

/// One parsed single-line packages entry.
struct BunEntry {
pub(super) struct BunEntry {
line_idx: usize,
/// Leading whitespace, re-emitted verbatim.
indent: String,
Expand All @@ -432,7 +432,7 @@ struct BunEntry {
/// The key token exactly as spelled (incl. quotes), re-emitted verbatim.
key_raw: String,
/// Verbatim top-level tuple elements (trimmed).
elems: Vec<String>,
pub(super) elems: Vec<String>,
trailing_comma: bool,
}

Expand Down Expand Up @@ -472,14 +472,14 @@ fn classify(entry: &BunEntry, target_spec: &str, name: &str) -> Option<TupleShap
}

/// `name@spec` split at the LAST `@` (scoped names keep their leading `@`).
fn split_name_spec(s: &str) -> Option<(&str, &str)> {
pub(super) fn split_name_spec(s: &str) -> Option<(&str, &str)> {
let at = s.rfind('@').filter(|&i| i > 0)?;
Some((&s[..at], &s[at + 1..]))
}

/// `"lockfileVersion": <n>` head check — only the fixture-pinned text
/// lockfile version is spliced (fail-closed on anything newer/older).
fn check_lock_version(text: &str) -> Result<(), String> {
pub(super) fn check_lock_version(text: &str) -> Result<(), String> {
let version = text.lines().take(5).find_map(|line| {
line.trim()
.strip_prefix("\"lockfileVersion\":")
Expand Down Expand Up @@ -514,7 +514,7 @@ fn packages_bounds(lines: &[String]) -> Option<(usize, usize)> {

/// Strictly parse every entry line of the packages section. Any line that
/// is neither blank nor a single-line `"key": [tuple]` entry fails CLOSED.
fn parse_packages_section(lines: &[String]) -> Result<Vec<BunEntry>, String> {
pub(super) fn parse_packages_section(lines: &[String]) -> Result<Vec<BunEntry>, String> {
let Some((start, end)) = packages_bounds(lines) else {
// No (or unterminated) packages section: an empty lock simply has
// no entries; an unterminated one is malformed.
Expand Down Expand Up @@ -651,7 +651,7 @@ fn split_top_level(interior: &str) -> Result<Vec<String>, String> {
}

/// Decode a verbatim JSON string token; `None` if it is not one.
fn decode_json_string(token: &str) -> Option<String> {
pub(super) fn decode_json_string(token: &str) -> Option<String> {
if !token.starts_with('"') {
return None;
}
Expand Down
Loading