From dfb7b0e952d17ca67c6070aa980c2d3bd3cdc135 Mon Sep 17 00:00:00 2001 From: implementer Date: Sat, 29 Aug 2026 00:23:27 +0000 Subject: [PATCH] fix: handle quoted scoped keys in frozen-install probe (E00-S02-T03) --- tests/frozen-install.test.mjs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/frozen-install.test.mjs b/tests/frozen-install.test.mjs index c80e1be..4d52e06 100644 --- a/tests/frozen-install.test.mjs +++ b/tests/frozen-install.test.mjs @@ -46,13 +46,19 @@ const VIRTUAL_STORE = 'node_modules/.pnpm'; /** * Extracts the package entry keys from the `packages:` section of a pnpm 9.x * lockfile, e.g. `typescript@6.0.3` or `@scope/name@1.2.3(peer@2.0.0)`. + * pnpm 11 quotes scoped package keys in the lockfile YAML (e.g. + * `'@types/node@24.13.3':`), so surrounding single quotes are stripped to + * yield the plain `@` key the virtual-store mapping expects. */ function lockedPackageKeys(lockfileText) { const packagesSection = lockfileText.slice( lockfileText.indexOf('packages:'), lockfileText.indexOf('snapshots:'), ); - return [...packagesSection.matchAll(/^ (\S+):$/gm)].map((m) => m[1]); + return [...packagesSection.matchAll(/^ (\S+):$/gm)].map((m) => { + const key = m[1]; + return key.length >= 2 && key.startsWith("'") && key.endsWith("'") ? key.slice(1, -1) : key; + }); } /** @@ -241,4 +247,10 @@ test('the lockfile→virtual-store helpers flag missing packages (non-vacuous pr const drifted = ['typescript@6.0.4', '@scope+core@1.2.3', 'with-peer@2.0.0_peer@1.0.0']; assert.deepEqual(missingLockedDirs(keys, drifted), ['typescript@6.0.3']); + + // Scoped package keys are quoted by pnpm in the lockfile YAML (e.g. + // `'@types/node@24.13.3':`) — the extractor must strip the quotes so the + // key keeps the plain @ shape the store lookup expects. + const quotedScoped = "packages:\n\n '@scope/core@1.2.3':\n resolution: {integrity: x}\n\nsnapshots:\n"; + assert.deepEqual(lockedPackageKeys(quotedScoped), ['@scope/core@1.2.3']); });