@mawesome/npm-vm 0.0.0-alpha.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +50 -1
- package/dist/cli.js +4157 -0
- package/dist/cli.js.map +1 -0
- package/dist/index-B071ZJDk.d.cts +164 -0
- package/dist/index-B071ZJDk.d.ts +164 -0
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/internal.cjs +2709 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +139 -0
- package/dist/internal.d.ts +139 -0
- package/dist/internal.js +2706 -0
- package/dist/internal.js.map +1 -0
- package/dist/provenance--sOYCeF2.js +322 -0
- package/dist/provenance--sOYCeF2.js.map +1 -0
- package/dist/provenance-DDegWCyS.js +2 -0
- package/dist/runtime/atomic-C3shKdH9.cjs +88 -0
- package/dist/runtime/bootstrap.cjs +271 -0
- package/dist/runtime/commonjs-AANzyd21.cjs +7393 -0
- package/dist/runtime/dispatch-B9OSfqsn.cjs +25156 -0
- package/dist/runtime/dist-CXwBT6rE.cjs +30766 -0
- package/dist/runtime/home-BaoZZSBy.cjs +91 -0
- package/dist/runtime/install-C_M5WK98.cjs +13598 -0
- package/dist/runtime/journal-_bs-eJRJ.cjs +282 -0
- package/dist/runtime/launchers/cmd.tmpl +2 -0
- package/dist/runtime/launchers/ps1.tmpl +5 -0
- package/dist/runtime/launchers/sh.tmpl +3 -0
- package/dist/runtime/lease-HBD4CmBx.cjs +224 -0
- package/dist/runtime/lock-DBeYN-Zg.cjs +141 -0
- package/dist/runtime/messages-vUDkl1-0.cjs +174 -0
- package/dist/runtime/p-map-b8pXdaFZ.cjs +105 -0
- package/dist/runtime/proc-hB8N9WjN.cjs +127 -0
- package/dist/runtime/provenance-B4bajGXQ.cjs +2 -0
- package/dist/runtime/rolldown-runtime-BGT596CS.cjs +64 -0
- package/dist/runtime/runtime.cjs +143 -0
- package/dist/runtime/src-SpeGbMJx.cjs +314 -0
- package/dist/src-Bc9nN1Kl.cjs +2125 -0
- package/dist/src-Bc9nN1Kl.cjs.map +1 -0
- package/dist/src-NhNG2mnQ.js +1798 -0
- package/dist/src-NhNG2mnQ.js.map +1 -0
- package/package.json +87 -17
- package/index.js +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-NhNG2mnQ.js","names":["cryptoVerify","readManifest"],"sources":["../src/errors.ts","../src/messages.ts","../src/own-npm.ts","../src/state/proc.ts","../src/state/lease.ts","../src/spec.ts","../src/select.ts","../src/install/verify.ts","../src/install/cache.ts","../src/state/atomic.ts","../src/state/prune.ts","../src/setup/home.ts","../src/install/config.ts","../src/install/fetch.ts","../src/install/keys.ts","../src/install/index.ts","../src/project.ts","../src/index.ts"],"sourcesContent":["/** Exit codes of `npm-vm` itself and of the shim before npm starts (spec section 10). */\nexport const EXIT = {\n\tok: 0,\n\tproblems: 1,\n\tpartial: 2,\n\tresolution: 3,\n\ttransport: 4,\n\tverification: 5,\n\tabi: 6,\n\tusage: 64,\n} as const;\n\nexport type ExitCode = (typeof EXIT)[keyof typeof EXIT];\n\n/** A failure with a message id from spec section 12 and the exit code it maps to. */\nexport class NpmVmError extends Error {\n\toverride name = 'NpmVmError';\n\treadonly id: string;\n\treadonly exitCode: ExitCode;\n\n\tconstructor(id: string, exitCode: ExitCode, message: string) {\n\t\tsuper(message);\n\t\tthis.id = id;\n\t\tthis.exitCode = exitCode;\n\t}\n}\n\nexport function isNpmVmError(error: unknown): error is NpmVmError {\n\treturn error instanceof NpmVmError;\n}\n","import type { NpmSpec } from './spec.ts';\n\n/** Message builders for spec section 12; every message names the cause and one fix. */\n\n/** Every URL in `text` with its user info replaced, so a registry token never reaches a terminal (spec SEC-10). */\nexport function redactUrls(text: string): string {\n\treturn text.replace(/\\b([a-z][a-z0-9+.-]*:\\/\\/)([^\\s/]*)@/gi, '$1***@');\n}\n\nexport function describeSpecs(specs: readonly NpmSpec[]): string {\n\treturn specs\n\t\t.map((spec) =>\n\t\t\tspec.hash ? `${spec.exact}+${spec.hash.algorithm}.${spec.hash.hex.slice(0, 8)}…` : spec.range,\n\t\t)\n\t\t.join(' or ');\n}\n\nexport function engineMessage(version: string, enginesNode: string, nodeVersion: string): string {\n\treturn [\n\t\t`npm ${version} needs Node ${enginesNode}, but the active Node is ${nodeVersion}.`,\n\t\t`Switch Node with \\`nvm install <version>\\` or \\`fnm use <version>\\`, or relax the npm range in package.json.`,\n\t].join('\\n');\n}\n\nexport function noMatchMessage(specs: readonly NpmSpec[], file: string, reason: string): string {\n\treturn [\n\t\t`No npm version satisfies ${describeSpecs(specs)} (${file}): ${reason}.`,\n\t\t`Run \\`npm-vm which\\` to see the resolution.`,\n\t].join('\\n');\n}\n\nexport function transportMessage(ownVersion: string | null, detail: string): string {\n\tconst found =\n\t\townVersion === null ? 'no npm beside the active Node' : `Node's own npm ${ownVersion}`;\n\treturn [\n\t\t`Cannot download npm: ${found} (${detail}); npm 8 or newer is needed as the transport.`,\n\t\t`Reinstall Node or run \\`npm-vm install <version>\\` from a Node whose npm works.`,\n\t].join('\\n');\n}\n\nexport function keyMessage(keyid: string): string {\n\treturn [\n\t\t`The registry signed npm with key ${keyid}, which npm-vm does not know.`,\n\t\t`Run \\`npm-vm self-update\\` to pick up new registry keys.`,\n\t].join('\\n');\n}\n\nexport function unsignedMessage(registry: string, version: string): string {\n\treturn [\n\t\t`${redactUrls(registry)} serves npm ${version} without a registry signature.`,\n\t\t`Pin a tarball hash in devEngines.packageManager (\\`${version}+sha512.<hex>\\`) to allow unsigned registries.`,\n\t].join('\\n');\n}\n\nexport function integrityMessage(expected: string, actual: string, detail: string): string {\n\treturn [\n\t\t`npm tarball verification failed: ${detail}.`,\n\t\t`Expected ${expected}, got ${actual}. Clear the entry with \\`npm-vm cache prune\\` and retry.`,\n\t].join('\\n');\n}\n\nexport function oldNodeMessage(nodeVersion: string, floor: string, requirement: string): string {\n\treturn `npm-vm: Node ${nodeVersion} is below ${floor}; running Node's own npm and ignoring the project requirement ${requirement}. Upgrade Node to honour it.`;\n}\n\nexport function abiMessage(detail: string): string {\n\treturn [\n\t\t`npm-vm launcher mismatch: ${detail}.`,\n\t\t`Run \\`npx --prefix ~ -y @mawesome/npm-vm setup\\` to reinstall the launchers.`,\n\t].join('\\n');\n}\n\nexport interface LockHolder {\n\tpid: number;\n\thost: string;\n\tcreatedAt: string;\n}\n\n/** M-LOCKED: names the file, the holder, and the one recovery that is safe for where the holder runs. */\nexport function lockedMessage(\n\tpath: string,\n\tholder: LockHolder | null,\n\tlive: boolean,\n\tforeign: boolean,\n): string {\n\tif (holder === null) {\n\t\treturn `${path} is locked by an unreadable owner. If no npm-vm command is running, delete that file and retry.`;\n\t}\n\tconst who = `PID ${holder.pid} on ${holder.host} since ${holder.createdAt || 'an unknown time'}`;\n\tif (foreign) {\n\t\treturn [\n\t\t\t`${path} is locked by ${who}, which cannot be verified from this machine.`,\n\t\t\t`Confirm on ${holder.host} that no npm-vm command runs, then delete ${path} and retry.`,\n\t\t].join('\\n');\n\t}\n\tif (live) {\n\t\treturn `${path} is locked by ${who}, which is still running. Wait for it to finish and retry.`;\n\t}\n\treturn `${path} is locked by ${who}, which is no longer running. Delete ${path} and retry.`;\n}\n\nexport function provenanceMessage(name: string, version: string, detail: string): string {\n\treturn [\n\t\t`${name}@${version} failed provenance verification: ${detail}.`,\n\t\t'The installed version is unchanged. Retry later, or install the release by hand after checking it at https://www.npmjs.com/package/@mawesome/npm-vm.',\n\t].join('\\n');\n}\n\nexport function dirPermsMessage(dir: string, problem: string, fix: string): string {\n\treturn [\n\t\t`${dir} ${problem}.`,\n\t\t`Run \\`${fix}\\` and retry, or point NPM_VM_HOME at a private directory.`,\n\t].join('\\n');\n}\n\nexport function changedMessage(file: string, what: string): string {\n\treturn `${file} changed since npm-vm wrote it; left untouched. Remove the ${what} by hand if you still want it gone.`;\n}\n\nexport function restartMessage(): string {\n\treturn 'Restart open terminals and IDEs so they pick up the new PATH.';\n}\n","import { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { posix, win32 } from 'node:path';\n\n/** The npm in the active Node's prefix: bundled, or whatever `npm i -g npm@x` put there. */\nexport interface OwnNpm {\n\troot: string;\n\tversion: string;\n\tcliPath: string;\n\tnpxCliPath: string;\n}\n\n/**\n * Locates Node's own npm from the running binary (spec section 1).\n * The lib dir, not the `bin/npm` link: under `--link` that link is the shim.\n */\nexport function ownNpmRoot(execPath: string, platform: NodeJS.Platform = process.platform): string {\n\tif (platform === 'win32') {\n\t\treturn win32.join(win32.dirname(execPath), 'node_modules', 'npm');\n\t}\n\tlet real = execPath;\n\ttry {\n\t\treal = realpathSync(execPath);\n\t} catch {\n\t\t// A missing or unreadable binary resolves as given; the caller reports the missing npm.\n\t}\n\treturn posix.join(posix.dirname(real), '..', 'lib', 'node_modules', 'npm');\n}\n\nexport function findOwnNpm(\n\texecPath: string = process.execPath,\n\tplatform: NodeJS.Platform = process.platform,\n): OwnNpm | null {\n\tconst root = ownNpmRoot(execPath, platform);\n\tconst { join } = platform === 'win32' ? win32 : posix;\n\tconst manifest = join(root, 'package.json');\n\tif (!existsSync(manifest)) {\n\t\treturn null;\n\t}\n\tlet version: unknown;\n\ttry {\n\t\tversion = (JSON.parse(readFileSync(manifest, 'utf8')) as { version?: unknown }).version;\n\t} catch {\n\t\treturn null;\n\t}\n\tif (typeof version !== 'string') {\n\t\treturn null;\n\t}\n\treturn {\n\t\troot,\n\t\tversion,\n\t\tcliPath: join(root, 'bin', 'npm-cli.js'),\n\t\tnpxCliPath: join(root, 'bin', 'npx-cli.js'),\n\t};\n}\n","import { execFileSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { basename, isAbsolute, join } from 'node:path';\n\n/** A process plus the start identity that tells it apart from a later process reusing its PID (spec PROC-1). */\nexport interface ProcessIdentity {\n\tpid: number;\n\t/** Platform-specific start identity, compared as an exact string; null when unreadable. */\n\tstart: string | null;\n}\n\nexport function powershellPath(env: NodeJS.ProcessEnv = process.env): string {\n\treturn join(\n\t\tenv['SystemRoot'] ?? 'C:\\\\Windows',\n\t\t'System32',\n\t\t'WindowsPowerShell',\n\t\t'v1.0',\n\t\t'powershell.exe',\n\t);\n}\n\nconst SHELL_DIRS = ['/bin', '/usr/bin', '/usr/local/bin', '/opt/homebrew/bin', '/snap/bin'];\n\n/**\n * An absolute path for a shell to probe (spec SEC-8): the login shell when `$SHELL` is absolute, else system dirs.\n * Never PATH, which inside an npm script starts with `node_modules/.bin`.\n */\nexport function shellBinary(\n\tshell: 'zsh' | 'bash' | 'fish' | 'powershell',\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): string | null {\n\tconst name = shell === 'powershell' ? 'pwsh' : shell;\n\tif (platform === 'win32') {\n\t\tconst pwsh = join(env['ProgramFiles'] ?? 'C:\\\\Program Files', 'PowerShell', '7', 'pwsh.exe');\n\t\treturn shell === 'powershell' && existsSync(pwsh) ? pwsh : null;\n\t}\n\tconst login = env['SHELL'];\n\tconst candidates = [\n\t\t...(login !== undefined && isAbsolute(login) && basename(login) === name ? [login] : []),\n\t\t...SHELL_DIRS.map((dir) => join(dir, name)),\n\t];\n\treturn candidates.find((candidate) => existsSync(candidate)) ?? null;\n}\n\n/** The start identity of `pid`, or null when the lookup fails or is ambiguous. */\nexport function startIdentity(\n\tpid: number,\n\tplatform: NodeJS.Platform = process.platform,\n\tenv: NodeJS.ProcessEnv = process.env,\n): string | null {\n\ttry {\n\t\tif (platform === 'linux') {\n\t\t\tconst stat = readFileSync(`/proc/${pid}/stat`, 'utf8');\n\t\t\t// The command name sits in parentheses and may hold spaces; fields are counted after the last one.\n\t\t\tconst after = stat\n\t\t\t\t.slice(stat.lastIndexOf(')') + 1)\n\t\t\t\t.trim()\n\t\t\t\t.split(/\\s+/);\n\t\t\tconst start = after[19];\n\t\t\treturn start !== undefined && /^\\d+$/.test(start) ? start : null;\n\t\t}\n\t\tif (platform === 'darwin') {\n\t\t\tconst out = execFileSync('/bin/ps', ['-o', 'lstart=', '-p', String(pid)], {\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tenv: { LC_ALL: 'C', PATH: '/usr/bin:/bin' },\n\t\t\t}).trim();\n\t\t\treturn out === '' || out.includes('\\n') ? null : out;\n\t\t}\n\t\tif (platform === 'win32') {\n\t\t\tconst out = execFileSync(\n\t\t\t\tpowershellPath(env),\n\t\t\t\t[\n\t\t\t\t\t'-NoProfile',\n\t\t\t\t\t'-NonInteractive',\n\t\t\t\t\t'-Command',\n\t\t\t\t\t`(Get-Process -Id ${pid}).StartTime.ToFileTimeUtc()`,\n\t\t\t\t],\n\t\t\t\t{ encoding: 'utf8', windowsHide: true },\n\t\t\t).trim();\n\t\t\treturn /^\\d+$/.test(out) ? out : null;\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\treturn null;\n}\n\nexport function ownIdentity(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): ProcessIdentity {\n\treturn { pid: process.pid, start: startIdentity(process.pid, platform, env) };\n}\n\n/**\n * Whether the recorded process still runs: dead only when the PID is gone or its start identity differs.\n * Any failure to look up means live, so nothing ever expires a process that merely cannot be inspected.\n */\nexport function isLive(\n\tidentity: ProcessIdentity,\n\tplatform: NodeJS.Platform = process.platform,\n): boolean {\n\ttry {\n\t\tprocess.kill(identity.pid, 0);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === 'ESRCH') {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\tif (identity.start === null) {\n\t\treturn true;\n\t}\n\tconst current = startIdentity(identity.pid, platform);\n\treturn current === null || current === identity.start;\n}\n","import { randomBytes } from 'node:crypto';\nimport { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { hostname } from 'node:os';\nimport { join } from 'node:path';\nimport { isLive, ownIdentity, type ProcessIdentity } from './proc.ts';\n\n/** What a lease, gate or lock file records about its owner (spec LEASE-1, PROC-1). */\nexport interface OwnerRecord extends ProcessIdentity {\n\thost: string;\n\tmachineId: string;\n\tcreatedAt: string;\n}\n\nexport interface Lease {\n\tpath: string;\n\trelease(): void;\n}\n\nexport function leasesDir(entry: string): string {\n\treturn `${entry}.leases`;\n}\n\nexport function gatePath(entry: string): string {\n\treturn `${entry}.prune`;\n}\n\nexport function newToken(): string {\n\treturn randomBytes(8).toString('hex');\n}\n\nexport function ownerRecord(\n\tmachineId: string,\n\tidentity: ProcessIdentity = ownIdentity(),\n): OwnerRecord {\n\treturn { ...identity, host: hostname(), machineId, createdAt: new Date().toISOString() };\n}\n\nexport function readOwner(file: string): OwnerRecord | null {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(file, 'utf8')) as Partial<OwnerRecord>;\n\t\tif (typeof parsed.pid !== 'number') {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tpid: parsed.pid,\n\t\t\tstart: typeof parsed.start === 'string' ? parsed.start : null,\n\t\t\thost: typeof parsed.host === 'string' ? parsed.host : '?',\n\t\t\tmachineId: typeof parsed.machineId === 'string' ? parsed.machineId : '?',\n\t\t\tcreatedAt: typeof parsed.createdAt === 'string' ? parsed.createdAt : '',\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** A file in the per-machine cache belongs to a dead owner only when PROC-1 says so; unreadable means live. */\nexport function ownerLive(file: string): boolean {\n\tconst owner = readOwner(file);\n\treturn owner === null ? true : isLive(owner);\n}\n\n/** Creates a shared lease on `entry`; the file name is unique, so a prune can never delete a live one by mistake. */\nexport function createLease(entry: string, owner: OwnerRecord): Lease {\n\tconst dir = leasesDir(entry);\n\tfor (let attempt = 0; ; attempt += 1) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\tconst path = join(dir, newToken());\n\t\ttry {\n\t\t\twriteFileSync(path, JSON.stringify(owner), { mode: 0o600, flag: 'wx' });\n\t\t} catch (error) {\n\t\t\t// An unreadable lease counts as live and would keep the entry forever.\n\t\t\trmSync(path, { force: true });\n\t\t\t// A prune can move the leases dir away between the mkdir and the write; the next attempt recreates it.\n\t\t\tif ((error as NodeJS.ErrnoException).code === 'ENOENT' && attempt < 3) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\treturn {\n\t\t\tpath,\n\t\t\trelease() {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t},\n\t\t};\n\t}\n}\n\n/**\n * Whether a lease created before a gate check is still in place (spec LEASE-1).\n * A prune that passed its own lease check first moves the whole leases dir away, taking the file with it.\n */\nexport function leaseSurvived(lease: Lease): boolean {\n\treturn existsSync(lease.path);\n}\n\nexport function listLeases(entry: string): string[] {\n\ttry {\n\t\treturn readdirSync(leasesDir(entry)).map((name) => join(leasesDir(entry), name));\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst GATE_WAIT_MS = 5000;\n\n/**\n * The runtime's shared lease (spec LEASE-1): lease first, then look for a live prune gate.\n * A live gate means the entry is going away: wait briefly, retry once, else return null so the caller fetches a private entry.\n */\nexport async function acquireShared(\n\tentry: string,\n\towner: OwnerRecord,\n\toptions: { waitMs?: number } = {},\n): Promise<Lease | null> {\n\tfor (let attempt = 0; attempt < 3; attempt += 1) {\n\t\tconst lease = createLease(entry, owner);\n\t\tconst gate = gatePath(entry);\n\t\tlet gated = false;\n\t\ttry {\n\t\t\tgated = ownerLive(gate);\n\t\t} catch {\n\t\t\tgated = false;\n\t\t}\n\t\tif (!gated || !gateExists(gate)) {\n\t\t\tif (leaseSurvived(lease)) {\n\t\t\t\treturn lease;\n\t\t\t}\n\t\t\t// A prune between the lease and the gate check moved the lease away with the entry; lease again.\n\t\t\tcontinue;\n\t\t}\n\t\tlease.release();\n\t\tconst deadline = Date.now() + (options.waitMs ?? GATE_WAIT_MS);\n\t\twhile (Date.now() < deadline && gateExists(gate)) {\n\t\t\tawait sleep(50);\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction gateExists(gate: string): boolean {\n\ttry {\n\t\treturn readOwner(gate) !== null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Creates the prune gate with O_EXCL; false when another gate exists (there is only ever one prune, so a leftover). */\nexport function createGate(entry: string, owner: OwnerRecord): boolean {\n\ttry {\n\t\twriteFileSync(gatePath(entry), JSON.stringify(owner), { flag: 'wx', mode: 0o600 });\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n\t\t\treturn false;\n\t\t}\n\t\t// A gate without a readable owner would make every later prune skip the entry.\n\t\trmSync(gatePath(entry), { force: true });\n\t\tthrow error;\n\t}\n\treturn true;\n}\n\nexport function removeGate(entry: string): void {\n\trmSync(gatePath(entry), { force: true });\n}\n","import semver from 'semver';\n\nexport type HashAlgorithm = 'sha512' | 'sha256' | 'sha224';\n\nexport interface SpecHash {\n\talgorithm: HashAlgorithm;\n\thex: string;\n}\n\n/** One npm version requirement: a range, or an exact version optionally pinned to a tarball hash. */\nexport interface NpmSpec {\n\t/** The range as written, without any hash suffix. */\n\trange: string;\n\t/** Set when the range is a single exact version. */\n\texact: string | null;\n\thash: SpecHash | null;\n}\n\nexport type OnFail = 'ignore' | 'warn' | 'error' | 'download';\n\nexport type SpecField = 'devEngines' | 'packageManager';\n\nexport interface ParsedSpecs {\n\t/** Alternatives: Node's own npm or a candidate satisfies the project when it matches any of them. */\n\tspecs: NpmSpec[];\n\t/** The policy of the last `devEngines.packageManager` entry (spec RES-7); `error` for `packageManager`. */\n\tonFail: OnFail;\n\tfield: SpecField;\n}\n\nexport class SpecError extends Error {\n\toverride name = 'SpecError';\n\treadonly field: string;\n\t/** The project's policy for this failure, when the entry declaring it could still be read. */\n\tonFail: OnFail = 'error';\n\n\tconstructor(field: string, message: string) {\n\t\tsuper(message);\n\t\tthis.field = field;\n\t}\n}\n\nconst MAX_RANGE_LENGTH = 256;\nconst HASH_HEX_LENGTH: Record<HashAlgorithm, number> = { sha512: 128, sha256: 64, sha224: 56 };\nconst ON_FAIL = new Set<string>(['ignore', 'warn', 'error', 'download']);\n\n/**\n * Validates one version string before it reaches a transport argv or a message (spec RES-4).\n * Build metadata other than a well-formed hash suffix is rejected: semver would silently drop it.\n */\nexport function parseVersionSpec(raw: string, field: string): NpmSpec {\n\tif (raw.length > MAX_RANGE_LENGTH) {\n\t\tthrow new SpecError(field, `${field}: version is longer than ${MAX_RANGE_LENGTH} characters`);\n\t}\n\tconst plus = raw.indexOf('+');\n\tconst range = (plus === -1 ? raw : raw.slice(0, plus)).trim();\n\tlet hash: SpecHash | null = null;\n\tif (plus !== -1) {\n\t\thash = parseHash(raw.slice(plus + 1), field);\n\t}\n\tif (semver.validRange(range) === null) {\n\t\tthrow new SpecError(field, `${field}: ${JSON.stringify(raw)} is not a semver range`);\n\t}\n\tconst exact = semver.valid(range);\n\tif (hash !== null && exact === null) {\n\t\tthrow new SpecError(\n\t\t\tfield,\n\t\t\t`${field}: a hash needs an exact version, got ${JSON.stringify(raw)}`,\n\t\t);\n\t}\n\treturn { range, exact, hash };\n}\n\nfunction parseHash(suffix: string, field: string): SpecHash {\n\tconst match = /^(sha512|sha256|sha224)\\.([0-9a-fA-F]+)$/.exec(suffix);\n\tif (match === null) {\n\t\tthrow new SpecError(field, `${field}: unsupported hash suffix ${JSON.stringify(`+${suffix}`)}`);\n\t}\n\tconst algorithm = match[1] as HashAlgorithm;\n\tconst hex = (match[2] as string).toLowerCase();\n\tif (hex.length !== HASH_HEX_LENGTH[algorithm]) {\n\t\tthrow new SpecError(\n\t\t\tfield,\n\t\t\t`${field}: ${algorithm} hash must be ${HASH_HEX_LENGTH[algorithm]} hex characters`,\n\t\t);\n\t}\n\treturn { algorithm, hex };\n}\n\ninterface ManagerEntry {\n\tname?: unknown;\n\tversion?: unknown;\n\tonFail?: unknown;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Reads the npm requirements of a parsed `package.json` (spec RES-4).\n * Returns null when the project declares nothing for npm, including when it declares only pnpm or yarn.\n */\nexport function parseSpecs(pkg: unknown): ParsedSpecs | null {\n\tif (!isObject(pkg)) {\n\t\treturn null;\n\t}\n\tconst devEngines = pkg['devEngines'];\n\tif (isObject(devEngines) && devEngines['packageManager'] !== undefined) {\n\t\tconst fromDevEngines = parseDevEngines(devEngines['packageManager']);\n\t\tif (fromDevEngines !== null) {\n\t\t\treturn fromDevEngines;\n\t\t}\n\t}\n\tconst packageManager = pkg['packageManager'];\n\tif (typeof packageManager === 'string' && packageManager.startsWith('npm@')) {\n\t\tconst field = 'packageManager';\n\t\treturn {\n\t\t\tspecs: [parseVersionSpec(packageManager.slice('npm@'.length), field)],\n\t\t\tonFail: 'error',\n\t\t\tfield,\n\t\t};\n\t}\n\treturn null;\n}\n\nfunction parseDevEngines(value: unknown): ParsedSpecs | null {\n\tconst field = 'devEngines.packageManager';\n\tconst entries = Array.isArray(value) ? value : [value];\n\tif (entries.length === 0) {\n\t\treturn null;\n\t}\n\tconst specs: NpmSpec[] = [];\n\t// The policy comes first, so an entry with a broken version still fails the way it asked to.\n\tconst last = entries[entries.length - 1];\n\tconst onFail = isObject(last) ? parseOnFail(last, field) : 'error';\n\ttry {\n\t\tfor (const entry of entries) {\n\t\t\tif (!isObject(entry)) {\n\t\t\t\tthrow new SpecError(field, `${field}: every entry must be an object`);\n\t\t\t}\n\t\t\tif (entry['name'] !== 'npm') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst version = entry['version'];\n\t\t\tif (version === undefined) {\n\t\t\t\tspecs.push({ range: '*', exact: null, hash: null });\n\t\t\t} else if (typeof version === 'string') {\n\t\t\t\tspecs.push(parseVersionSpec(version, field));\n\t\t\t} else {\n\t\t\t\tthrow new SpecError(field, `${field}: version must be a string`);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof SpecError) {\n\t\t\terror.onFail = onFail;\n\t\t}\n\t\tthrow error;\n\t}\n\tif (specs.length === 0) {\n\t\treturn null;\n\t}\n\treturn { specs, onFail, field: 'devEngines' };\n}\n\nfunction parseOnFail(entry: ManagerEntry, field: string): OnFail {\n\tconst onFail = entry.onFail;\n\tif (onFail === undefined) {\n\t\treturn 'error';\n\t}\n\tif (typeof onFail !== 'string' || !ON_FAIL.has(onFail)) {\n\t\tthrow new SpecError(field, `${field}: onFail must be ignore, warn, error or download`);\n\t}\n\treturn onFail as OnFail;\n}\n\n/** Whether a concrete version satisfies the spec's range, hash aside (spec RES-5 and RES-6). */\nexport function matchesRange(version: string, spec: NpmSpec): boolean {\n\treturn semver.satisfies(version, spec.range);\n}\n","import semver from 'semver';\nimport { matchesRange, type NpmSpec, type SpecHash } from './spec.ts';\n\nexport interface RegistrySignature {\n\tkeyid: string;\n\tsig: string;\n}\n\n/** A published npm version as the registry or the cache describes it. */\nexport interface Candidate {\n\tversion: string;\n\t/** `engines.node` of the package; missing means any Node. */\n\tenginesNode: string | null;\n\t/** `dist.integrity` (sha512 SRI). */\n\tintegrity: string;\n\t/** Where the candidate lives when it is already cached. */\n\tentryPath: string | null;\n\t/** `dist.signatures` from the registry; null for a cached candidate. */\n\tsignatures: RegistrySignature[] | null;\n\t/** For a cached entry: the key that verified it, or null when only a project's pin did. */\n\tkeyid?: string | null;\n\t/** For a cached entry: the tarball digests recorded at verification, so a pin can be judged without the bytes. */\n\tdigests?: { sha256: string; sha224: string } | null;\n}\n\nexport interface Selection {\n\tcandidate: Candidate;\n\t/** Pins from the specs that selected the candidate; the download must match one of them. Empty: unpinned. */\n\thashes: SpecHash[];\n}\n\nexport type SelectFailure =\n\t| { kind: 'engine'; version: string; enginesNode: string }\n\t| { kind: 'nomatch'; reason: string };\n\nexport type SelectResult =\n\t| { kind: 'selected'; selection: Selection }\n\t| { kind: 'failed'; failure: SelectFailure };\n\nfunction engineAccepts(candidate: Candidate, nodeVersion: string): boolean {\n\treturn (\n\t\tcandidate.enginesNode === null ||\n\t\tsemver.satisfies(nodeVersion, candidate.enginesNode, { includePrerelease: true })\n\t);\n}\n\nfunction hashAccepts(candidate: Candidate, spec: NpmSpec): boolean {\n\tif (spec.hash === null) {\n\t\t// An entry that only a pin ever vouched for is not an alternative for an unpinned project (spec SEC-1).\n\t\treturn candidate.keyid !== null;\n\t}\n\tif (spec.hash.algorithm === 'sha512') {\n\t\treturn sriHex(candidate.integrity) === spec.hash.hex;\n\t}\n\tif (candidate.digests === undefined || candidate.digests === null) {\n\t\t// Only the tarball bytes can answer a sha256 or sha224 pin; verification checks it after download.\n\t\treturn true;\n\t}\n\treturn candidate.digests[spec.hash.algorithm] === spec.hash.hex;\n}\n\n/** The hex digest of a `sha512-<base64>` SRI string, or null for any other form. */\nexport function sriHex(integrity: string): string | null {\n\tconst match = /^sha512-([A-Za-z0-9+/=]+)$/.exec(integrity.trim());\n\treturn match === null ? null : Buffer.from(match[1] as string, 'base64').toString('hex');\n}\n\n/** Whether Node's own npm satisfies a spec without a hash (spec RES-5). */\nexport function ownNpmSatisfies(ownVersion: string, specs: readonly NpmSpec[]): boolean {\n\treturn specs.some((spec) => spec.hash === null && matchesRange(ownVersion, spec));\n}\n\n/**\n * Picks the highest candidate matching any spec and the active Node (spec RES-6), cached first.\n * Returns the reason when nothing fits, distinguishing an `engines.node` exclusion from no match at all.\n */\nexport function selectCandidate(\n\tspecs: readonly NpmSpec[],\n\tcandidates: readonly Candidate[],\n\tnodeVersion: string,\n): SelectResult {\n\tlet best: Selection | null = null;\n\tlet excluded: Candidate | null = null;\n\tfor (const candidate of candidates) {\n\t\tconst matching = specs.filter(\n\t\t\t(entry) => matchesRange(candidate.version, entry) && hashAccepts(candidate, entry),\n\t\t);\n\t\tif (matching.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!engineAccepts(candidate, nodeVersion)) {\n\t\t\tif (excluded === null || semver.gt(candidate.version, excluded.version)) {\n\t\t\t\texcluded = candidate;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (best === null || semver.gt(candidate.version, best.candidate.version)) {\n\t\t\t// An unpinned alternative needs no pin; otherwise every matching pin is carried and any one may verify.\n\t\t\tconst unpinned = matching.some((entry) => entry.hash === null);\n\t\t\tbest = {\n\t\t\t\tcandidate,\n\t\t\t\thashes: unpinned\n\t\t\t\t\t? []\n\t\t\t\t\t: matching.flatMap((entry) => (entry.hash === null ? [] : [entry.hash])),\n\t\t\t};\n\t\t}\n\t}\n\tif (best !== null) {\n\t\treturn { kind: 'selected', selection: best };\n\t}\n\tif (excluded !== null) {\n\t\treturn {\n\t\t\tkind: 'failed',\n\t\t\tfailure: {\n\t\t\t\tkind: 'engine',\n\t\t\t\tversion: excluded.version,\n\t\t\t\tenginesNode: excluded.enginesNode ?? '*',\n\t\t\t},\n\t\t};\n\t}\n\treturn { kind: 'failed', failure: { kind: 'nomatch', reason: 'no published version matches' } };\n}\n","import { createHash, createPublicKey, verify as cryptoVerify } from 'node:crypto';\nimport {\n\tcreateReadStream,\n\tcreateWriteStream,\n\tmkdirSync,\n\treadFileSync,\n\twriteFileSync,\n} from 'node:fs';\nimport { dirname, join, posix } from 'node:path';\nimport { Transform } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { createGunzip } from 'node:zlib';\nimport { Parser, type ReadEntry } from 'tar';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { integrityMessage, keyMessage, unsignedMessage } from '../messages.ts';\nimport type { RegistrySignature } from '../select.ts';\nimport type { SpecHash } from '../spec.ts';\nimport type { RegistryKey } from './keys.ts';\n\nexport interface Digests {\n\t/** `sha512-<base64>`, the SRI form the registry uses. */\n\tsha512: string;\n\tsha512hex: string;\n\tsha256hex: string;\n\tsha224hex: string;\n}\n\n/** Every digest a spec or the registry may ask for, in one pass over the file. */\nexport async function fileDigests(file: string): Promise<Digests> {\n\tconst sha512 = createHash('sha512');\n\tconst sha256 = createHash('sha256');\n\tconst sha224 = createHash('sha224');\n\tawait pipeline(\n\t\tcreateReadStream(file),\n\t\tnew Transform({\n\t\t\ttransform(chunk: Buffer, _encoding, callback) {\n\t\t\t\tsha512.update(chunk);\n\t\t\t\tsha256.update(chunk);\n\t\t\t\tsha224.update(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t}),\n\t);\n\tconst sha512Digest = sha512.digest();\n\treturn {\n\t\tsha512: `sha512-${sha512Digest.toString('base64')}`,\n\t\tsha512hex: sha512Digest.toString('hex'),\n\t\tsha256hex: sha256.digest('hex'),\n\t\tsha224hex: sha224.digest('hex'),\n\t};\n}\n\nfunction integrityFailure(expected: string, actual: string, detail: string): NpmVmError {\n\treturn new NpmVmError(\n\t\t'M-INTEGRITY',\n\t\tEXIT.verification,\n\t\tintegrityMessage(expected, actual, detail),\n\t);\n}\n\n/** The tarball must match the registry's integrity and, when the project pins hashes, one of them (spec SEC-2). */\nexport function checkIntegrity(\n\tdigests: Digests,\n\tintegrity: string,\n\thashes: readonly SpecHash[],\n): void {\n\tif (digests.sha512 !== integrity.trim()) {\n\t\tthrow integrityFailure(\n\t\t\tintegrity,\n\t\t\tdigests.sha512,\n\t\t\t'the tarball does not match the registry integrity',\n\t\t);\n\t}\n\tif (hashes.length === 0) {\n\t\treturn;\n\t}\n\tconst actual = {\n\t\tsha512: digests.sha512hex,\n\t\tsha256: digests.sha256hex,\n\t\tsha224: digests.sha224hex,\n\t};\n\tif (!hashes.some((hash) => actual[hash.algorithm] === hash.hex)) {\n\t\tconst [first] = hashes as [SpecHash, ...SpecHash[]];\n\t\tthrow integrityFailure(\n\t\t\t`${first.algorithm}.${first.hex}`,\n\t\t\t`${first.algorithm}.${actual[first.algorithm]}`,\n\t\t\t'the tarball does not match the pinned hash',\n\t\t);\n\t}\n}\n\nexport interface SignatureInput {\n\tname: string;\n\tversion: string;\n\tintegrity: string;\n\tsignatures: readonly RegistrySignature[];\n\t/** Resolves the publication time, consulted only when a signing key has expired. */\n\tpublishedAt: () => Promise<string | null>;\n\tkeys: readonly RegistryKey[];\n\tregistry: string;\n\t/** A hash-pinned spec may accept an unsigned registry. */\n\tpinned: boolean;\n}\n\n/**\n * Checks the registry signatures over `name@version:integrity` against the pinned keyring (spec SEC-1).\n * Returns the key id that verified; throws M-KEY for an unknown key and M-UNSIGNED when no signature is usable.\n */\nexport async function verifySignatures(input: SignatureInput): Promise<string | null> {\n\tif (input.signatures.length === 0) {\n\t\tif (input.pinned) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow new NpmVmError(\n\t\t\t'M-UNSIGNED',\n\t\t\tEXIT.verification,\n\t\t\tunsignedMessage(input.registry, input.version),\n\t\t);\n\t}\n\tconst payload = Buffer.from(`${input.name}@${input.version}:${input.integrity}`, 'utf8');\n\tlet unknown: string | null = null;\n\tfor (const signature of input.signatures) {\n\t\tconst key = input.keys.find((entry) => entry.keyid === signature.keyid);\n\t\tif (key === undefined) {\n\t\t\tunknown ??= signature.keyid;\n\t\t\tcontinue;\n\t\t}\n\t\tif (key.revoked === true || !(await keyCurrent(key, input.publishedAt))) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst publicKey = createPublicKey({\n\t\t\tkey: Buffer.from(key.key, 'base64'),\n\t\t\tformat: 'der',\n\t\t\ttype: 'spki',\n\t\t});\n\t\tif (cryptoVerify('sha256', payload, publicKey, Buffer.from(signature.sig, 'base64'))) {\n\t\t\treturn key.keyid;\n\t\t}\n\t}\n\tif (unknown !== null) {\n\t\tthrow new NpmVmError('M-KEY', EXIT.verification, keyMessage(unknown));\n\t}\n\tthrow new NpmVmError(\n\t\t'M-UNSIGNED',\n\t\tEXIT.verification,\n\t\tunsignedMessage(input.registry, input.version),\n\t);\n}\n\n/** An expired key still vouches for versions published before it expired; an unknown time fails closed. */\nasync function keyCurrent(\n\tkey: RegistryKey,\n\tpublishedAt: () => Promise<string | null>,\n): Promise<boolean> {\n\tif (key.expires === null) {\n\t\treturn true;\n\t}\n\tconst published = await publishedAt();\n\treturn published !== null && Date.parse(published) < Date.parse(key.expires);\n}\n\nexport interface ExtractLimits {\n\tmaxEntries: number;\n\tmaxBytes: number;\n}\n\nexport const DEFAULT_LIMITS: ExtractLimits = { maxEntries: 10_000, maxBytes: 256 * 1024 * 1024 };\n\nfunction unsafe(detail: string): NpmVmError {\n\treturn integrityFailure('a safe npm tarball', 'an unsafe entry', detail);\n}\n\n/** The destination-relative path of a tarball entry, or a thrown M-INTEGRITY for anything outside `package/` (spec SEC-3). */\nexport function entryRelativePath(path: string): string {\n\tif (\n\t\tpath.includes('\\\\') ||\n\t\t[...path].some((char) => char.charCodeAt(0) < 0x20 || char.charCodeAt(0) === 0x7f)\n\t) {\n\t\tthrow unsafe(`entry name contains a control character or backslash: ${JSON.stringify(path)}`);\n\t}\n\tif (path.startsWith('/') || /^[A-Za-z]:/.test(path)) {\n\t\tthrow unsafe(`absolute entry name: ${path}`);\n\t}\n\tconst segments = path.split('/').filter((segment) => segment !== '' && segment !== '.');\n\tif (segments.includes('..')) {\n\t\tthrow unsafe(`entry name climbs out of the archive: ${path}`);\n\t}\n\tif (segments[0] !== 'package') {\n\t\tthrow unsafe(`entry outside package/: ${path}`);\n\t}\n\treturn segments.length === 1 ? '' : posix.join(...segments.slice(1));\n}\n\n/**\n * Extracts regular files and directories under `package/` into `dest`, rejecting everything else (spec SEC-3).\n * Modes are `0644` or `0755` by the owner exec bit; ownership and extended attributes are ignored.\n */\nexport async function safeExtract(\n\ttarball: string,\n\tdest: string,\n\tlimits: ExtractLimits = DEFAULT_LIMITS,\n): Promise<void> {\n\tlet entries = 0;\n\tlet bytes = 0;\n\tlet decompressed = 0;\n\tconst writes: Promise<void>[] = [];\n\tconst parser = new Parser({ strict: true });\n\tlet aborted: Error | null = null;\n\tconst abort = (error: Error): void => {\n\t\taborted ??= error;\n\t\tparser.abort(error);\n\t};\n\tparser.on('entry', (entry: ReadEntry) => {\n\t\ttry {\n\t\t\tentries += 1;\n\t\t\tbytes += entry.size;\n\t\t\tif (entries > limits.maxEntries) {\n\t\t\t\tthrow unsafe(`more than ${limits.maxEntries} entries`);\n\t\t\t}\n\t\t\tif (bytes > limits.maxBytes) {\n\t\t\t\tthrow unsafe(`more than ${limits.maxBytes} bytes`);\n\t\t\t}\n\t\t\tconst relative = entryRelativePath(entry.path);\n\t\t\tconst target = relative === '' ? dest : join(dest, relative);\n\t\t\tif (entry.type === 'Directory') {\n\t\t\t\tmkdirSync(target, { recursive: true, mode: 0o755 });\n\t\t\t\tentry.resume();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (entry.type !== 'File' || relative === '') {\n\t\t\t\tthrow unsafe(`${entry.type} entry: ${entry.path}`);\n\t\t\t}\n\t\t\tmkdirSync(dirname(target), { recursive: true, mode: 0o755 });\n\t\t\tconst mode = ((entry.mode ?? 0o644) & 0o100) === 0 ? 0o644 : 0o755;\n\t\t\twrites.push(pipeline(entry, createWriteStream(target, { mode })));\n\t\t} catch (error) {\n\t\t\tabort(error as Error);\n\t\t}\n\t});\n\tconst counter = new Transform({\n\t\ttransform(chunk: Buffer, _encoding, callback) {\n\t\t\tdecompressed += chunk.length;\n\t\t\tif (decompressed > limits.maxBytes) {\n\t\t\t\tcallback(unsafe(`more than ${limits.maxBytes} bytes after decompression`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcallback(null, chunk);\n\t\t},\n\t});\n\tconst done = new Promise<void>((resolve, reject) => {\n\t\tparser.on('end', () => resolve());\n\t\tparser.on('error', (error: Error) => reject(error));\n\t});\n\t// The pipeline surfaces the same error first; the second rejection must not go unhandled.\n\tdone.catch(() => undefined);\n\ttry {\n\t\tawait pipeline(createReadStream(tarball), createGunzip(), counter, parser);\n\t\tawait done;\n\t\tawait Promise.all(writes);\n\t} catch (error) {\n\t\t// Let in-flight file writes settle, so the caller can remove the destination at once.\n\t\tawait Promise.allSettled(writes);\n\t\tthrow (\n\t\t\taborted ??\n\t\t\t(error instanceof NpmVmError\n\t\t\t\t? error\n\t\t\t\t: unsafe(`cannot read the tarball: ${(error as Error).message}`))\n\t\t);\n\t}\n\tif (aborted !== null) {\n\t\tthrow aborted;\n\t}\n}\n\n/** The marker an entry carries once verified (spec SEC-4). */\nexport interface Verified {\n\tversion: string;\n\tintegrity: string;\n\t/** The registry key that verified the tarball, or null when only a project's pin did. */\n\tkeyid: string | null;\n\t/** Tarball digests, so a later pin of another algorithm can be judged against the entry. */\n\tsha256: string;\n\tsha224: string;\n\tverifiedAt: string;\n}\n\nexport const VERIFIED_FILE = '.verified';\n\nexport function writeVerified(dir: string, verified: Verified): void {\n\twriteFileSync(join(dir, VERIFIED_FILE), JSON.stringify(verified), { mode: 0o600 });\n}\n\nexport function readVerified(dir: string): Verified | null {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(join(dir, VERIFIED_FILE), 'utf8')) as Partial<Verified>;\n\t\tif (typeof parsed.version !== 'string' || typeof parsed.integrity !== 'string') {\n\t\t\treturn null;\n\t\t}\n\t\tif (typeof parsed.sha256 !== 'string' || typeof parsed.sha224 !== 'string') {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tversion: parsed.version,\n\t\t\tintegrity: parsed.integrity,\n\t\t\tkeyid: typeof parsed.keyid === 'string' ? parsed.keyid : null,\n\t\t\tsha256: parsed.sha256,\n\t\t\tsha224: parsed.sha224,\n\t\t\tverifiedAt: typeof parsed.verifiedAt === 'string' ? parsed.verifiedAt : '',\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { existsSync, readdirSync, readFileSync, renameSync, rmSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { sriHex, type Candidate } from '../select.ts';\nimport {\n\tcreateLease,\n\tgatePath,\n\tleaseSurvived,\n\tnewToken,\n\townerLive,\n\ttype Lease,\n\ttype OwnerRecord,\n} from '../state/lease.ts';\nimport type { RegistryKey } from './keys.ts';\nimport { readVerified } from './verify.ts';\n\nexport const ENTRIES_DIR = 'npm';\n\n/** `<version>-<16 hex of the integrity>`: two registries serving different bytes get two entries (spec SEC-4). */\nexport function entryName(version: string, integrity: string): string {\n\tconst hex = sriHex(integrity);\n\tif (hex === null) {\n\t\tthrow new Error(`not a sha512 integrity: ${integrity}`);\n\t}\n\treturn `${version}-${hex.slice(0, 16)}`;\n}\n\n/** Where verified entries are staged before the rename into `npm/`: same filesystem, so the rename stays atomic. */\nexport function stagingDir(cacheRoot: string): string {\n\treturn join(cacheRoot, 'staging');\n}\n\nexport function canonicalEntry(cacheRoot: string, version: string, integrity: string): string {\n\treturn join(cacheRoot, ENTRIES_DIR, entryName(version, integrity));\n}\n\nexport function privateEntry(canonical: string, token: string): string {\n\treturn `${canonical}.${token}`;\n}\n\n/** Whether a directory name under `npm/` is an entry rather than a lease dir, a gate or a deletion in progress. */\nexport function isEntryName(name: string): boolean {\n\treturn /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?-[0-9a-f]{16}(?:\\.[0-9a-f]{16})?$/.test(name);\n}\n\nfunction readManifest(\n\tdir: string,\n): { name: unknown; version: unknown; enginesNode: string | null } | null {\n\ttry {\n\t\tconst pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst engines = pkg['engines'];\n\t\tconst node =\n\t\t\ttypeof engines === 'object' && engines !== null\n\t\t\t\t? (engines as Record<string, unknown>)['node']\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tname: pkg['name'],\n\t\t\tversion: pkg['version'],\n\t\t\tenginesNode: typeof node === 'string' ? node : null,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Whether an entry may run (spec SEC-5): verified for this integrity, owned by the current user,\n * and holding the npm it claims. Never deletes anything.\n */\nexport function validateEntry(entryPath: string, integrity: string): boolean {\n\ttry {\n\t\tconst stat = statSync(entryPath);\n\t\tif (!stat.isDirectory() || (process.getuid !== undefined && stat.uid !== process.getuid())) {\n\t\t\treturn false;\n\t\t}\n\t} catch {\n\t\treturn false;\n\t}\n\tconst verified = readVerified(entryPath);\n\tif (verified === null || verified.integrity !== integrity) {\n\t\treturn false;\n\t}\n\tconst manifest = readManifest(entryPath);\n\treturn manifest !== null && manifest.name === 'npm' && manifest.version === verified.version;\n}\n\n/** Every verified entry in the cache as a candidate, whatever its validity; use-time validation decides. */\nexport function listEntries(cacheRoot: string, keys: readonly RegistryKey[] = []): Candidate[] {\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(join(cacheRoot, ENTRIES_DIR));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst candidates: Candidate[] = [];\n\tfor (const name of names) {\n\t\tif (!isEntryName(name)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst entryPath = join(cacheRoot, ENTRIES_DIR, name);\n\t\tconst verified = readVerified(entryPath);\n\t\tconst manifest = readManifest(entryPath);\n\t\tif (verified === null || manifest === null || manifest.version !== verified.version) {\n\t\t\tcontinue;\n\t\t}\n\t\t// A key revoked since the entry was verified withdraws the entry with it.\n\t\tif (\n\t\t\tverified.keyid !== null &&\n\t\t\tkeys.some((key) => key.keyid === verified.keyid && key.revoked === true)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tcandidates.push({\n\t\t\tversion: verified.version,\n\t\t\tenginesNode: manifest.enginesNode,\n\t\t\tintegrity: verified.integrity,\n\t\t\tentryPath,\n\t\t\tsignatures: null,\n\t\t\tkeyid: verified.keyid,\n\t\t\tdigests: { sha256: verified.sha256, sha224: verified.sha224 },\n\t\t});\n\t}\n\treturn candidates;\n}\n\nexport interface PublishedEntry {\n\tentryPath: string;\n\tlease: Lease;\n}\n\nfunction isCollision(error: unknown): boolean {\n\tconst code = (error as NodeJS.ErrnoException).code;\n\treturn code === 'EEXIST' || code === 'ENOTEMPTY' || code === 'EPERM' || code === 'EISDIR';\n}\n\n/**\n * Moves a verified temp dir into the cache under a lease (spec SEC-4). The lease exists before the\n * rename, so a prune never sees the entry without it; a lost race reuses or sidesteps the winner's entry.\n */\nexport function publishEntry(\n\ttempDir: string,\n\tcanonical: string,\n\tintegrity: string,\n\towner: OwnerRecord,\n): PublishedEntry {\n\tconst lease = createLease(canonical, owner);\n\t// Lease first, then look for a live prune gate: a prune checks leases after creating its gate, so one side always sees the other.\n\tif (existsSync(gatePath(canonical)) && ownerLive(gatePath(canonical))) {\n\t\tlease.release();\n\t\treturn publishPrivately(tempDir, canonical, owner);\n\t}\n\tif (!leaseSurvived(lease)) {\n\t\t// A prune between the lease and the gate check moved the lease away with the old entry; the path is free now.\n\t\treturn publishEntry(tempDir, canonical, integrity, owner);\n\t}\n\ttry {\n\t\trenameSync(tempDir, canonical);\n\t\treturn { entryPath: canonical, lease };\n\t} catch (error) {\n\t\tif (!isCollision(error)) {\n\t\t\tlease.release();\n\t\t\tthrow error;\n\t\t}\n\t}\n\t// The lease taken above already covers the winner's entry, so a prune cannot take it away meanwhile.\n\tif (validateEntry(canonical, integrity)) {\n\t\trmSync(tempDir, { recursive: true, force: true });\n\t\treturn { entryPath: canonical, lease };\n\t}\n\tlease.release();\n\treturn publishPrivately(tempDir, canonical, owner);\n}\n\nfunction publishPrivately(tempDir: string, canonical: string, owner: OwnerRecord): PublishedEntry {\n\t// The same handshake as the canonical path: a prune that found the fresh leases dir first may have moved it away.\n\tfor (;;) {\n\t\tconst entryPath = privateEntry(canonical, newToken());\n\t\tconst privateLease = createLease(entryPath, owner);\n\t\tif (existsSync(gatePath(entryPath)) && ownerLive(gatePath(entryPath))) {\n\t\t\tprivateLease.release();\n\t\t\tcontinue;\n\t\t}\n\t\tif (!leaseSurvived(privateLease)) {\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\trenameSync(tempDir, entryPath);\n\t\t} catch (error) {\n\t\t\tprivateLease.release();\n\t\t\tthrow error;\n\t\t}\n\t\treturn { entryPath, lease: privateLease };\n\t}\n}\n","import { closeSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { newToken } from './lease.ts';\n\nconst RETRY_CODES = new Set(['EBUSY', 'EPERM', 'EACCES']);\nconst RETRY_LIMIT_MS = 5000;\n\nfunction sleepSync(ms: number): void {\n\tAtomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n}\n\n/**\n * Runs a file operation, retrying Windows sharing violations with backoff for up to 5 s (spec MUT-3).\n * Elsewhere the same codes are real permission errors and surface at once.\n */\nexport function withSharingRetry<T>(\n\toperation: () => T,\n\tplatform: NodeJS.Platform = process.platform,\n\tlimitMs: number = RETRY_LIMIT_MS,\n): T {\n\tconst started = Date.now();\n\tlet delay = 20;\n\tfor (;;) {\n\t\ttry {\n\t\t\treturn operation();\n\t\t} catch (error) {\n\t\t\tconst code = (error as NodeJS.ErrnoException).code ?? '';\n\t\t\tif (\n\t\t\t\tplatform !== 'win32' ||\n\t\t\t\t!RETRY_CODES.has(code) ||\n\t\t\t\tDate.now() - started + delay > limitMs\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tsleepSync(delay);\n\t\t\tdelay = Math.min(delay * 2, 500);\n\t\t}\n\t}\n}\n\n/** Writes `content` to `path` through a temp file in the same dir, fsynced and renamed into place. */\nexport function atomicWrite(path: string, content: string | Buffer, mode = 0o644): void {\n\tconst dir = dirname(path);\n\tmkdirSync(dir, { recursive: true });\n\tconst temp = join(dir, `.${newToken()}.tmp`);\n\ttry {\n\t\tconst fd = openSync(temp, 'wx', mode);\n\t\ttry {\n\t\t\tconst buffer = typeof content === 'string' ? Buffer.from(content, 'utf8') : content;\n\t\t\t// writeSync may stop short without throwing; a truncated file must never reach the rename.\n\t\t\tfor (let offset = 0; offset < buffer.length;) {\n\t\t\t\tconst written = writeSync(fd, buffer, offset, buffer.length - offset);\n\t\t\t\tif (written <= 0) {\n\t\t\t\t\tthrow new Error(`short write to ${temp}: ${offset} of ${buffer.length} bytes`);\n\t\t\t\t}\n\t\t\t\toffset += written;\n\t\t\t}\n\t\t\tfsyncSync(fd);\n\t\t} finally {\n\t\t\tcloseSync(fd);\n\t\t}\n\t\twithSharingRetry(() => renameSync(temp, path));\n\t} catch (error) {\n\t\trmSync(temp, { force: true });\n\t\tthrow error;\n\t}\n}\n\n/** Renames with the Windows retry; a cross-device rename is not retried, it is a layout error. */\nexport function atomicRename(from: string, to: string): void {\n\twithSharingRetry(() => renameSync(from, to));\n}\n\nexport function removeWithRetry(path: string): void {\n\twithSharingRetry(() => rmSync(path, { recursive: true, force: true }));\n}\n","import { existsSync, readdirSync, rmSync, statSync, utimesSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { ENTRIES_DIR, isEntryName, stagingDir, validateEntry } from '../install/cache.ts';\nimport { readVerified } from '../install/verify.ts';\nimport { atomicRename, removeWithRetry } from './atomic.ts';\nimport {\n\tcreateGate,\n\tgatePath,\n\tleasesDir,\n\tlistLeases,\n\tnewToken,\n\townerLive,\n\tremoveGate,\n\ttype OwnerRecord,\n} from './lease.ts';\n\nexport const USED_SUFFIX = '.used';\n\n/** Records a resolution of `entry` for the prune age, in a sidecar so the entry itself stays untouched. */\nexport function touchUsed(entry: string): void {\n\tconst marker = `${entry}${USED_SUFFIX}`;\n\ttry {\n\t\tconst now = new Date();\n\t\tutimesSync(marker, now, now);\n\t} catch {\n\t\twriteFileSync(marker, '', { flag: 'a' });\n\t}\n}\n\nexport function lastUsed(entry: string): number | null {\n\ttry {\n\t\treturn statSync(`${entry}${USED_SUFFIX}`).mtimeMs;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport interface PruneOptions {\n\t/** Entries not resolved for this long are removed; `Infinity` keeps every valid entry. */\n\tmaxAgeMs: number;\n\tnow?: number;\n}\n\nexport interface PruneReport {\n\tremoved: string[];\n\tkept: string[];\n\tskipped: string[];\n}\n\nexport type PruneReason = 'stale' | 'invalid' | 'orphan-private' | 'leftover';\n\n/** Why one entry would go, or null to keep it. */\nexport function pruneReason(\n\tcacheRoot: string,\n\tname: string,\n\toptions: PruneOptions,\n): PruneReason | null {\n\tconst entry = join(cacheRoot, ENTRIES_DIR, name);\n\tif (name.includes('.deleting.')) {\n\t\treturn 'leftover';\n\t}\n\tif (!isEntryName(name)) {\n\t\treturn null;\n\t}\n\tconst verified = readVerified(entry);\n\tif (verified === null || !validateEntry(entry, verified.integrity)) {\n\t\treturn 'invalid';\n\t}\n\tconst isPrivate = /\\.[0-9a-f]{16}$/.test(name);\n\tif (isPrivate && !listLeases(entry).some((lease) => ownerLive(lease))) {\n\t\treturn 'orphan-private';\n\t}\n\tconst used = lastUsed(entry);\n\tconst age = (options.now ?? Date.now()) - (used ?? statSync(entry).mtimeMs);\n\treturn age > options.maxAgeMs ? 'stale' : null;\n}\n\n/**\n * Removes one entry the exclusive way (spec LEASE-1): gate, drop dead leases, bail on a live one, rename aside, drop the gate, delete.\n * After the gate is gone nothing here touches the entry's paths again.\n */\nexport function pruneEntry(entry: string, owner: OwnerRecord): boolean {\n\tif (existsSync(gatePath(entry)) && !ownerLive(gatePath(entry))) {\n\t\tremoveGate(entry);\n\t}\n\tif (!createGate(entry, owner)) {\n\t\treturn false;\n\t}\n\tfor (const lease of listLeases(entry)) {\n\t\tif (!ownerLive(lease)) {\n\t\t\trmSync(lease, { force: true });\n\t\t}\n\t}\n\tif (listLeases(entry).length > 0) {\n\t\tremoveGate(entry);\n\t\treturn false;\n\t}\n\tconst token = newToken();\n\tconst deletingEntry = `${entry}.deleting.${token}`;\n\tconst deletingLeases = `${entry}.leases.deleting.${token}`;\n\tif (existsSync(entry)) {\n\t\tatomicRename(entry, deletingEntry);\n\t}\n\tif (existsSync(leasesDir(entry))) {\n\t\tatomicRename(leasesDir(entry), deletingLeases);\n\t}\n\tremoveGate(entry);\n\tremoveWithRetry(deletingEntry);\n\tremoveWithRetry(deletingLeases);\n\trmSync(`${entry}${USED_SUFFIX}`, { force: true });\n\treturn true;\n}\n\nconst STAGING_MAX_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** Work dirs a crashed extraction left under `staging/`; a live one is never a day old. */\nfunction pruneStaging(cacheRoot: string, now: number): void {\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(stagingDir(cacheRoot));\n\t} catch {\n\t\treturn;\n\t}\n\tfor (const name of names) {\n\t\tconst dir = join(stagingDir(cacheRoot), name);\n\t\ttry {\n\t\t\tif (now - statSync(dir).mtimeMs > STAGING_MAX_AGE_MS) {\n\t\t\t\tremoveWithRetry(dir);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Gone already, or unreadable: nothing to reclaim.\n\t\t}\n\t}\n}\n\n/** Prunes the whole cache; the caller holds the exclusive lock (MUT-1) so only one prune ever runs. */\nexport function pruneCache(\n\tcacheRoot: string,\n\towner: OwnerRecord,\n\toptions: PruneOptions,\n): PruneReport {\n\tconst report: PruneReport = { removed: [], kept: [], skipped: [] };\n\tpruneStaging(cacheRoot, options.now ?? Date.now());\n\tlet names: string[];\n\ttry {\n\t\tnames = readdirSync(join(cacheRoot, ENTRIES_DIR));\n\t} catch {\n\t\treturn report;\n\t}\n\tfor (const name of names) {\n\t\tconst entry = join(cacheRoot, ENTRIES_DIR, name);\n\t\t// A lease dir whose entry is gone and whose owners are all dead is a crashed prune's leftover too.\n\t\tif (\n\t\t\tname.endsWith('.leases') &&\n\t\t\texistsSync(entry) &&\n\t\t\t!existsSync(entry.slice(0, -'.leases'.length))\n\t\t) {\n\t\t\t// Through the gate like any entry: a publisher creating its lease right now still wins.\n\t\t\t(pruneEntry(entry.slice(0, -'.leases'.length), owner) ? report.removed : report.skipped).push(\n\t\t\t\tname,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\t// A gate whose entry is gone and whose owner is dead is a crashed prune's leftover.\n\t\tif (\n\t\t\tname.endsWith('.prune') &&\n\t\t\t!existsSync(entry.slice(0, -'.prune'.length)) &&\n\t\t\t!ownerLive(entry)\n\t\t) {\n\t\t\trmSync(entry, { force: true });\n\t\t\treport.removed.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tconst reason = pruneReason(cacheRoot, name, options);\n\t\tif (reason === null) {\n\t\t\tif (isEntryName(name)) {\n\t\t\t\treport.kept.push(name);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (reason === 'leftover') {\n\t\t\tremoveWithRetry(entry);\n\t\t\treport.removed.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (pruneEntry(entry, owner)) {\n\t\t\treport.removed.push(name);\n\t\t} else {\n\t\t\treport.skipped.push(name);\n\t\t}\n\t}\n\treturn report;\n}\n","import { execFileSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { homedir, hostname } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface MachineId {\n\t/** sha256 of the platform id, first 16 hex chars (spec DIST-2). */\n\tid: string;\n\t/** True when only the hostname was available, which cloned machines can share. */\n\tfallback: boolean;\n}\n\n/** Every directory the tool uses (spec DIST-1 and SET-1). */\nexport interface Dirs {\n\thome: string;\n\tcache: string;\n\tstate: string;\n\ttmp: string;\n\tjournal: string;\n\tmachine: MachineId;\n}\n\nfunction localAppData(env: NodeJS.ProcessEnv): string {\n\treturn env['LOCALAPPDATA'] ?? join(homedir(), 'AppData', 'Local');\n}\n\nexport function defaultHome(\n\tenv: NodeJS.ProcessEnv,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tif (platform === 'win32') {\n\t\treturn join(localAppData(env), 'npm-vm');\n\t}\n\treturn join(env['XDG_DATA_HOME'] || join(homedir(), '.local', 'share'), 'npm-vm');\n}\n\nexport function cacheBase(\n\tenv: NodeJS.ProcessEnv,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tif (platform === 'win32') {\n\t\t// Beside the home, not inside it: uninstall removes the home and must leave the cache alone.\n\t\treturn join(localAppData(env), 'npm-vm-cache');\n\t}\n\treturn join(env['XDG_CACHE_HOME'] || join(homedir(), '.cache'), 'npm-vm');\n}\n\nfunction platformId(platform: NodeJS.Platform, env: NodeJS.ProcessEnv): string | null {\n\ttry {\n\t\tif (platform === 'linux') {\n\t\t\tfor (const file of ['/etc/machine-id', '/var/lib/dbus/machine-id']) {\n\t\t\t\ttry {\n\t\t\t\t\tconst id = readFileSync(file, 'utf8').trim();\n\t\t\t\t\tif (id !== '') {\n\t\t\t\t\t\treturn id;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Try the next location.\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tif (platform === 'darwin') {\n\t\t\tconst out = execFileSync('/usr/sbin/ioreg', ['-rd1', '-c', 'IOPlatformExpertDevice'], {\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tenv: { PATH: '/usr/bin:/bin:/usr/sbin:/sbin' },\n\t\t\t});\n\t\t\treturn /\"IOPlatformUUID\"\\s*=\\s*\"([^\"]+)\"/.exec(out)?.[1] ?? null;\n\t\t}\n\t\tif (platform === 'win32') {\n\t\t\tconst reg = join(env['SystemRoot'] ?? 'C:\\\\Windows', 'System32', 'reg.exe');\n\t\t\tconst out = execFileSync(\n\t\t\t\treg,\n\t\t\t\t['query', 'HKLM\\\\SOFTWARE\\\\Microsoft\\\\Cryptography', '/v', 'MachineGuid'],\n\t\t\t\t{\n\t\t\t\t\tencoding: 'utf8',\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn /MachineGuid\\s+REG_SZ\\s+(\\S+)/.exec(out)?.[1] ?? null;\n\t\t}\n\t} catch {\n\t\t// Fall back to the hostname below.\n\t}\n\treturn null;\n}\n\n/** The hashed machine id, or a hashed hostname when the platform id is unreadable. */\nexport function readMachineId(\n\tenv: NodeJS.ProcessEnv = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): MachineId {\n\tconst raw = platformId(platform, env);\n\tconst source = raw ?? hostname();\n\treturn {\n\t\tid: createHash('sha256').update(source).digest('hex').slice(0, 16),\n\t\tfallback: raw === null,\n\t};\n}\n\nexport function resolveDirs(\n\tenv: NodeJS.ProcessEnv = process.env,\n\thome: string = env['NPM_VM_HOME'] || defaultHome(env),\n\tplatform: NodeJS.Platform = process.platform,\n\tmachine: MachineId = readMachineId(env, platform),\n): Dirs {\n\t// The shims embed this path, so a relative NPM_VM_HOME must become absolute here, once.\n\tconst absoluteHome = resolve(home);\n\tconst state = join(absoluteHome, 'state');\n\treturn {\n\t\thome: absoluteHome,\n\t\tcache: join(cacheBase(env, platform), machine.id),\n\t\tstate,\n\t\ttmp: join(state, 'tmp'),\n\t\tjournal: join(state, 'journal'),\n\t\tmachine,\n\t};\n}\n","import Config from '@npmcli/config';\nimport npmDefinitions from '@npmcli/config/lib/definitions/index.js';\nimport type { OwnNpm } from '../own-npm.ts';\n\n/** The npm settings a download may use, read from user and global config only (spec DL-2). */\nexport interface NpmConfigView {\n\tregistry: string;\n\tuserconfig: string;\n\tglobalconfig: string;\n\tcache: string;\n\tcredentials: {\n\t\ttoken?: string;\n\t\tusername?: string;\n\t\tpassword?: string;\n\t\tauth?: string;\n\t\tcertfile?: string;\n\t\tkeyfile?: string;\n\t};\n\thttpsProxy: string | null;\n\tproxy: string | null;\n\tnoproxy: string | null;\n\tca: string[] | null;\n\tcafile: string | null;\n\tstrictSsl: boolean;\n}\n\nconst DROPPED = new Set(['NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS']);\n/** Proxy settings reach the transport only from the user and global npm config (spec DL-2), never the env. */\nconst PROXY_VARS = /^(https?_proxy|all_proxy|no_proxy|proxy)$/i;\n\n/** The env without anything that would steer npm or Node: `npm_config_*`, proxies, `NODE_OPTIONS`, `NODE_EXTRA_CA_CERTS`. */\nexport function sanitizeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n\tconst clean: NodeJS.ProcessEnv = {};\n\tfor (const [key, value] of Object.entries(env)) {\n\t\tif (/^npm_config_/i.test(key) || DROPPED.has(key.toUpperCase()) || PROXY_VARS.test(key)) {\n\t\t\tcontinue;\n\t\t}\n\t\tclean[key] = value;\n\t}\n\treturn clean;\n}\n\nfunction optionalString(value: unknown): string | null {\n\tconst text = Array.isArray(value)\n\t\t? value\n\t\t\t\t.map(String)\n\t\t\t\t.filter((item) => item !== '')\n\t\t\t\t.join(',')\n\t\t: value;\n\treturn typeof text === 'string' && text !== '' ? text : null;\n}\n\n/**\n * Loads npm's config the way npm does, minus the project: `cwd` is an empty dir under the home,\n * the env is sanitized and nothing is printed. Credentials come only from `getCredentialsByURI`.\n */\nexport async function loadNpmConfig(\n\town: OwnNpm,\n\tenv: NodeJS.ProcessEnv,\n\tcwd: string,\n\tnodePath: string = process.execPath,\n): Promise<NpmConfigView> {\n\tconst { definitions, shorthands, flatten, nerfDarts } = npmDefinitions;\n\tconst config = new Config({\n\t\tdefinitions,\n\t\tshorthands,\n\t\tflatten,\n\t\tnerfDarts,\n\t\tnpmPath: own.root,\n\t\t/* The global prefix and its npmrc belong to the Node the shims run, not to this process.\n\t\t * Global mode makes the loader skip project config, so no ancestor of the home can inject an .npmrc. */\n\t\targv: [nodePath, own.cliPath, '--location=global'],\n\t\texecPath: nodePath,\n\t\tenv: { ...sanitizeEnv(env) },\n\t\tcwd,\n\t\texcludeNpmCwd: true,\n\t});\n\tawait config.load();\n\tconst registry = String(config.get('registry'));\n\tconst ca = config.get('ca');\n\treturn {\n\t\tregistry,\n\t\tuserconfig: String(config.get('userconfig')),\n\t\tglobalconfig: String(config.get('globalconfig')),\n\t\tcache: String(config.get('cache')),\n\t\tcredentials: config.getCredentialsByURI(registry),\n\t\thttpsProxy: optionalString(config.get('https-proxy')),\n\t\tproxy: optionalString(config.get('proxy')),\n\t\tnoproxy: optionalString(config.get('noproxy')),\n\t\tca: Array.isArray(ca) ? ca.map(String) : typeof ca === 'string' ? [ca] : null,\n\t\tcafile: optionalString(config.get('cafile')),\n\t\tstrictSsl: config.get('strict-ssl') !== false,\n\t};\n}\n","import { execFile } from 'node:child_process';\nimport { mkdirSync, mkdtempSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { integrityMessage, redactUrls, transportMessage } from '../messages.ts';\nimport type { OwnNpm } from '../own-npm.ts';\nimport type { RegistrySignature } from '../select.ts';\nimport { sanitizeEnv, type NpmConfigView } from './config.ts';\n\n/** One published version as `npm view` reports it. */\nexport interface RegistryVersion {\n\tversion: string;\n\tenginesNode: string | null;\n\tintegrity: string;\n\ttarball: string;\n\tsignatures: RegistrySignature[];\n\t/** `dist.attestations.url`, present for packages published with provenance. */\n\tattestationsUrl: string | null;\n}\n\nexport interface PackedTarball {\n\tfile: string;\n\tintegrity: string;\n}\n\nconst MIN_TRANSPORT = '8.0.0';\nconst MAX_OUTPUT = 256 * 1024 * 1024;\n\n/** Whether Node's own npm can serve as the transport (spec DL-1). */\nexport function transportUsable(own: OwnNpm | null): own is OwnNpm {\n\treturn own !== null && semver.gte(own.version, MIN_TRANSPORT);\n}\n\n/** A fresh private working dir under `state/tmp/`, never the shared system temp dir (spec DL-2). */\nexport function newWorkDir(tmpRoot: string): string {\n\tmkdirSync(tmpRoot, { recursive: true, mode: 0o700 });\n\treturn mkdtempSync(join(tmpRoot, 'work-'));\n}\n\n/**\n * Runs Node's own npm as the download transport, isolated from the project (spec DL-1, DL-2).\n * Every call runs in its own empty working dir, with that dir as the prefix and the user and global config named explicitly.\n */\nexport class Transport {\n\treadonly #own: OwnNpm;\n\treadonly #config: NpmConfigView;\n\treadonly #env: NodeJS.ProcessEnv;\n\treadonly #tmpRoot: string;\n\treadonly #nodePath: string;\n\n\tconstructor(\n\t\town: OwnNpm,\n\t\tconfig: NpmConfigView,\n\t\tenv: NodeJS.ProcessEnv,\n\t\ttmpRoot: string,\n\t\tnodePath: string = process.execPath,\n\t) {\n\t\tthis.#own = own;\n\t\tthis.#config = config;\n\t\tthis.#env = sanitizeEnv(env);\n\t\tthis.#tmpRoot = tmpRoot;\n\t\tthis.#nodePath = nodePath;\n\t}\n\n\t/** Versions of npm matching `range`, newest last as npm lists them; an unmatched range is an empty list. */\n\tview(range: string): Promise<RegistryVersion[]> {\n\t\treturn this.viewPackage('npm', range);\n\t}\n\n\t/** The same for any package, used by self-update for its own package. */\n\tasync viewPackage(name: string, range: string): Promise<RegistryVersion[]> {\n\t\tconst output = await this.#run(\n\t\t\t['view', `${name}@${range}`, 'version', 'engines', 'dist'],\n\t\t\ttrue,\n\t\t);\n\t\tif (output === null) {\n\t\t\treturn [];\n\t\t}\n\t\treturn asList(output).flatMap((item) => {\n\t\t\tconst version = readString(item, 'version');\n\t\t\tconst dist = readObject(item, 'dist');\n\t\t\tconst integrity = dist === null ? null : readString(dist, 'integrity');\n\t\t\tconst tarball = dist === null ? null : readString(dist, 'tarball');\n\t\t\tif (version === null || integrity === null || tarball === null) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tconst engines = readObject(item, 'engines');\n\t\t\tconst signatures = (dist === null ? null : dist['signatures']) ?? [];\n\t\t\tconst attestations = dist === null ? null : readObject(dist, 'attestations');\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tversion,\n\t\t\t\t\tenginesNode: engines === null ? null : readString(engines, 'node'),\n\t\t\t\t\tintegrity,\n\t\t\t\t\ttarball,\n\t\t\t\t\tsignatures: Array.isArray(signatures) ? signatures.filter(isSignature) : [],\n\t\t\t\t\tattestationsUrl: attestations === null ? null : readString(attestations, 'url'),\n\t\t\t\t},\n\t\t\t];\n\t\t});\n\t}\n\n\t/** Publication time per version, used only to judge signatures by expired keys. */\n\tasync times(): Promise<Record<string, string>> {\n\t\tconst output = await this.#run(['view', 'npm', 'time'], true);\n\t\tconst map = output === null ? null : (asList(output)[0] ?? null);\n\t\tconst times: Record<string, string> = {};\n\t\tif (map !== null && typeof map === 'object') {\n\t\t\tfor (const [version, time] of Object.entries(map)) {\n\t\t\t\tif (typeof time === 'string') {\n\t\t\t\t\ttimes[version] = time;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn times;\n\t}\n\n\t/** Downloads one npm version's tarball into `dest` through `npm pack`. */\n\tpack(version: string, dest: string): Promise<PackedTarball> {\n\t\treturn this.packPackage('npm', version, dest);\n\t}\n\n\tasync packPackage(name: string, version: string, dest: string): Promise<PackedTarball> {\n\t\tconst output = await this.#run(\n\t\t\t['pack', `${name}@${version}`, `--pack-destination=${dest}`],\n\t\t\tfalse,\n\t\t);\n\t\t// npm 8 prints a list; npm 9 and later print an object keyed by package name.\n\t\tconst items = asList(output).flatMap((item) =>\n\t\t\treadString(item, 'filename') === null ? asList(Object.values(item)) : [item],\n\t\t);\n\t\tconst item = items.find((candidate) => readString(candidate, 'filename') !== null) ?? null;\n\t\tconst filename = item === null ? null : readString(item, 'filename');\n\t\tconst integrity = item === null ? null : readString(item, 'integrity');\n\t\tif (filename === null || integrity === null) {\n\t\t\tthrow this.#failure(`npm pack returned no tarball for ${name}@${version}`);\n\t\t}\n\t\treturn { file: join(dest, filename), integrity };\n\t}\n\n\t#failure(detail: string): NpmVmError {\n\t\treturn new NpmVmError(\n\t\t\t'M-TRANSPORT',\n\t\t\tEXIT.transport,\n\t\t\ttransportMessage(this.#own.version, detail),\n\t\t);\n\t}\n\n\t/** Runs npm with the isolation flags; returns parsed JSON, or null for a 404 when `missingIsEmpty`. */\n\tasync #run(args: string[], missingIsEmpty: boolean): Promise<unknown> {\n\t\tconst cwd = newWorkDir(this.#tmpRoot);\n\t\tconst argv = [\n\t\t\tthis.#own.cliPath,\n\t\t\t...args,\n\t\t\t'--json',\n\t\t\t'--ignore-scripts',\n\t\t\t'--loglevel=error',\n\t\t\t// A packument's tarball URL never redirects the download to another host (spec SEC-7).\n\t\t\t'--replace-registry-host=always',\n\t\t\t...proxyFlags(this.#config),\n\t\t\t'--fetch-retry-mintimeout=1000',\n\t\t\t'--fetch-retry-maxtimeout=10000',\n\t\t\t`--prefix=${cwd}`,\n\t\t\t`--cache=${this.#config.cache}`,\n\t\t\t`--userconfig=${this.#config.userconfig}`,\n\t\t\t`--globalconfig=${this.#config.globalconfig}`,\n\t\t];\n\t\ttry {\n\t\t\tconst { stdout: output } = await new Promise<{ stdout: string }>((resolve, reject) => {\n\t\t\t\texecFile(\n\t\t\t\t\tthis.#nodePath,\n\t\t\t\t\targv,\n\t\t\t\t\t{ cwd, env: this.#env, maxBuffer: MAX_OUTPUT, timeout: 300_000, windowsHide: true },\n\t\t\t\t\t(error, stdout, stderr) => {\n\t\t\t\t\t\tif (error === null) {\n\t\t\t\t\t\t\tresolve({ stdout });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(Object.assign(error, { stdout, stderr }));\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn parseJson(output);\n\t\t} catch (error) {\n\t\t\tconst stderr = String((error as { stderr?: string }).stderr ?? '');\n\t\t\tif (missingIsEmpty && /\\bE404\\b/.test(stderr)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst line = (\n\t\t\t\tstderr.split('\\n').find((text) => /^npm (ERR!|error)/.test(text)) ??\n\t\t\t\t(error as Error).message\n\t\t\t)\n\t\t\t\t.replace(/^npm (ERR!|error) /, '')\n\t\t\t\t.trim();\n\t\t\tconst redacted = redactUrls(line);\n\t\t\tif (/\\bEINTEGRITY\\b/.test(stderr)) {\n\t\t\t\tthrow new NpmVmError(\n\t\t\t\t\t'M-INTEGRITY',\n\t\t\t\t\tEXIT.verification,\n\t\t\t\t\tintegrityMessage('the registry integrity', 'other bytes', redacted),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow this.#failure(redacted);\n\t\t} finally {\n\t\t\trmSync(cwd, { recursive: true, force: true });\n\t\t}\n\t}\n}\n\n/** Proxy settings as flags, since the env the transport sees carries none (spec DL-2). */\nfunction proxyFlags(config: NpmConfigView): string[] {\n\tconst flags: string[] = [];\n\tif (config.httpsProxy !== null) {\n\t\tflags.push(`--https-proxy=${config.httpsProxy}`);\n\t}\n\tif (config.proxy !== null) {\n\t\tflags.push(`--proxy=${config.proxy}`);\n\t}\n\tif (config.noproxy !== null) {\n\t\tflags.push(`--noproxy=${config.noproxy}`);\n\t}\n\treturn flags;\n}\n\nfunction parseJson(text: string): unknown {\n\tconst trimmed = text.trim();\n\tif (trimmed === '') {\n\t\treturn null;\n\t}\n\treturn JSON.parse(trimmed) as unknown;\n}\n\nfunction asList(value: unknown): Record<string, unknown>[] {\n\tconst items = Array.isArray(value) ? value : [value];\n\treturn items.filter(\n\t\t(item): item is Record<string, unknown> => typeof item === 'object' && item !== null,\n\t);\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | null {\n\tconst value = record[key];\n\treturn typeof value === 'string' ? value : null;\n}\n\nfunction readObject(record: Record<string, unknown>, key: string): Record<string, unknown> | null {\n\tconst value = record[key];\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: null;\n}\n\nfunction isSignature(value: unknown): value is RegistrySignature {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\ttypeof (value as RegistrySignature).keyid === 'string' &&\n\t\ttypeof (value as RegistrySignature).sig === 'string'\n\t);\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/** A registry signing key as `https://registry.npmjs.org/-/npm/v1/keys` lists it (spec SEC-1). */\nexport interface RegistryKey {\n\tkeyid: string;\n\t/** SPKI DER, base64. */\n\tkey: string;\n\texpires: string | null;\n\t/** A revoked key never verifies anything, whatever the dates say. */\n\trevoked?: boolean;\n}\n\n/*\n * Append-only: a rotated key keeps its entry with `expires`; a compromised one gets `revoked: true`.\n * Snapshot of the registry listing taken on 2026-10-15.\n */\nexport const REGISTRY_KEYS: readonly RegistryKey[] = [\n\t{\n\t\tkeyid: 'SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA',\n\t\tkey: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==',\n\t\texpires: '2025-01-29T00:00:00.000Z',\n\t},\n\t{\n\t\tkeyid: 'SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U',\n\t\tkey: 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEY6Ya7W++7aUPzvMTrezH6Ycx3c+HOKYCcNGybJZSCJq/fd7Qa8uuAKtdIkUQtQiEKERhAmE5lMMJhP8OkDOa2g==',\n\t\texpires: null,\n\t},\n];\n\nexport const EXTRA_KEYS_FILE = 'keys.json';\n\n/**\n * Keys added beside the built-in ones from `<home>/state/keys.json`, for registries that sign with their own keys.\n * Anything able to write there could replace the runtime itself, so this adds no trust the home does not already hold.\n */\nexport function loadKeyring(stateDir: string): RegistryKey[] {\n\tlet extra: unknown;\n\ttry {\n\t\textra = JSON.parse(readFileSync(join(stateDir, EXTRA_KEYS_FILE), 'utf8'));\n\t} catch {\n\t\treturn [...REGISTRY_KEYS];\n\t}\n\tconst keys = Array.isArray(extra) ? extra : [];\n\treturn [\n\t\t...REGISTRY_KEYS,\n\t\t...keys.filter(\n\t\t\t(key): key is RegistryKey =>\n\t\t\t\ttypeof key === 'object' &&\n\t\t\t\tkey !== null &&\n\t\t\t\ttypeof (key as RegistryKey).keyid === 'string' &&\n\t\t\t\ttypeof (key as RegistryKey).key === 'string' &&\n\t\t\t\t((key as RegistryKey).expires === null || typeof (key as RegistryKey).expires === 'string'),\n\t\t),\n\t];\n}\n","import { createHash } from 'node:crypto';\nimport { mkdirSync, readFileSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\nimport { EXIT, NpmVmError } from '../errors.ts';\nimport { engineMessage, integrityMessage, transportMessage } from '../messages.ts';\nimport { findOwnNpm, type OwnNpm } from '../own-npm.ts';\nimport type { ResolveProviders } from '../index.ts';\nimport type { Candidate, Selection } from '../select.ts';\nimport type { NpmSpec } from '../spec.ts';\nimport { acquireShared, ownerRecord, type Lease } from '../state/lease.ts';\nimport { touchUsed } from '../state/prune.ts';\nimport { resolveDirs, type Dirs } from '../setup/home.ts';\nimport {\n\tcanonicalEntry,\n\tlistEntries,\n\tpublishEntry,\n\tstagingDir,\n\tvalidateEntry,\n\ttype PublishedEntry,\n} from './cache.ts';\nimport { loadNpmConfig, type NpmConfigView } from './config.ts';\nimport { newWorkDir, Transport, transportUsable, type RegistryVersion } from './fetch.ts';\nimport { loadKeyring, type RegistryKey } from './keys.ts';\nimport {\n\tcheckIntegrity,\n\tfileDigests,\n\tsafeExtract,\n\tverifySignatures,\n\twriteVerified,\n\ttype Digests,\n} from './verify.ts';\n\nexport interface InstallContext {\n\tdirs: Dirs;\n\town: OwnNpm | null;\n\tenv: NodeJS.ProcessEnv;\n\tnodeVersion: string;\n\t/** The Node that runs the transport and, through the shims, npm itself. */\n\tnodePath: string;\n\tkeys: readonly RegistryKey[];\n}\n\nexport interface ContextNode {\n\t/** The Node binary the shims resolve through PATH; the Action passes the one setup-node installed. */\n\texecPath: string;\n\tversion: string;\n}\n\nexport function createContext(\n\tenv: NodeJS.ProcessEnv = process.env,\n\thome?: string,\n\tnode: ContextNode = { execPath: process.execPath, version: process.version },\n): InstallContext {\n\tconst dirs = resolveDirs(env, home);\n\treturn {\n\t\tdirs,\n\t\town: findOwnNpm(node.execPath),\n\t\tenv,\n\t\tnodeVersion: node.version,\n\t\tnodePath: node.execPath,\n\t\tkeys: loadKeyring(dirs.state),\n\t};\n}\n\nfunction toCandidate(version: RegistryVersion): Candidate {\n\treturn {\n\t\tversion: version.version,\n\t\tenginesNode: version.enginesNode,\n\t\tintegrity: version.integrity,\n\t\tentryPath: null,\n\t\tsignatures: version.signatures,\n\t};\n}\n\n/** Lazily loads the npm config and builds the transport once per process. */\nclass TransportFactory {\n\treadonly #context: InstallContext;\n\t#ready: Promise<{ transport: Transport; config: NpmConfigView }> | null = null;\n\n\tconstructor(context: InstallContext) {\n\t\tthis.#context = context;\n\t}\n\n\tget(): Promise<{ transport: Transport; config: NpmConfigView }> {\n\t\tthis.#ready ??= this.#create();\n\t\treturn this.#ready;\n\t}\n\n\tasync #create(): Promise<{ transport: Transport; config: NpmConfigView }> {\n\t\tconst { own, env, dirs } = this.#context;\n\t\tconst found = own?.version ?? null;\n\t\tif (!transportUsable(own)) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-TRANSPORT',\n\t\t\t\tEXIT.transport,\n\t\t\t\ttransportMessage(found, 'too old or missing'),\n\t\t\t);\n\t\t}\n\t\tconst cwd = newWorkDir(dirs.tmp);\n\t\ttry {\n\t\t\tconst config = await loadNpmConfig(own, env, cwd, this.#context.nodePath);\n\t\t\treturn {\n\t\t\t\ttransport: new Transport(own, config, env, dirs.tmp, this.#context.nodePath),\n\t\t\t\tconfig,\n\t\t\t};\n\t\t} finally {\n\t\t\trmSync(cwd, { recursive: true, force: true });\n\t\t}\n\t}\n}\n\n/** A downloaded tarball plus what the registry said about it, ready for verification. */\nexport interface PackedSource {\n\tfile: string;\n\tpublished: RegistryVersion;\n\tpublishedAt: () => Promise<string | null>;\n\tregistry: string;\n}\n\nexport interface EnsureOptions {\n\t/** Called with the verified tarball before it is extracted, so a caller can keep a copy (the Action's cache). */\n\tonPacked?: (source: PackedSource, digests: Digests) => Promise<void>;\n\t/** Never contact the registry; defaults to `NPM_VM_OFFLINE` in the context env. */\n\toffline?: boolean;\n}\n\nexport interface Installer extends ResolveProviders {\n\t/** Makes the selected npm runnable: validates a cached entry or downloads, verifies and publishes one (spec SEC-4, SEC-5). */\n\tensure(\n\t\tselection: Selection,\n\t\toptions?: EnsureOptions,\n\t): Promise<{ entryPath: string; lease: Lease }>;\n\t/** Verifies and publishes a tarball obtained elsewhere, such as a restored CI cache (spec SEC-1 to SEC-5). */\n\tinstallTarball(selection: Selection, source: PackedSource): Promise<PublishedEntry>;\n\t/** A short stable id of the configured registry, for cache keys that must not mix registries. */\n\tregistryIdentity(): Promise<string>;\n}\n\nexport function createInstaller(context: InstallContext): Installer {\n\tconst factory = new TransportFactory(context);\n\n\tasync function registryVersions(specs: readonly NpmSpec[]): Promise<RegistryVersion[]> {\n\t\tconst { transport } = await factory.get();\n\t\tconst byVersion = new Map<string, RegistryVersion>();\n\t\tfor (const spec of specs) {\n\t\t\tfor (const version of await transport.view(spec.exact ?? spec.range)) {\n\t\t\t\tbyVersion.set(version.version, version);\n\t\t\t}\n\t\t}\n\t\treturn [...byVersion.values()];\n\t}\n\n\tasync function installTarball(\n\t\tselection: Selection,\n\t\tsource: PackedSource,\n\t\tonPacked?: EnsureOptions['onPacked'],\n\t): Promise<PublishedEntry> {\n\t\tconst { candidate } = selection;\n\t\tconst owner = ownerRecord(context.dirs.machine.id);\n\t\tif (\n\t\t\tsource.published.version !== candidate.version ||\n\t\t\tsource.published.integrity !== candidate.integrity\n\t\t) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-INTEGRITY',\n\t\t\t\tEXIT.verification,\n\t\t\t\tintegrityMessage(\n\t\t\t\t\tcandidate.integrity,\n\t\t\t\t\tsource.published.integrity,\n\t\t\t\t\t`the registry no longer serves npm ${candidate.version} with this integrity`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tconst digests = await fileDigests(source.file);\n\t\tcheckIntegrity(digests, candidate.integrity, selection.hashes);\n\t\tconst keyid = await verifySignatures({\n\t\t\tname: 'npm',\n\t\t\tversion: candidate.version,\n\t\t\tintegrity: candidate.integrity,\n\t\t\tsignatures: source.published.signatures,\n\t\t\tpublishedAt: source.publishedAt,\n\t\t\tkeys: context.keys,\n\t\t\tregistry: source.registry,\n\t\t\tpinned: selection.hashes.length > 0,\n\t\t});\n\t\tif (onPacked !== undefined) {\n\t\t\tawait onPacked(source, digests);\n\t\t}\n\t\t// Extracted on the cache's own filesystem: the final rename into the cache must not cross one (EXDEV).\n\t\tconst work = newWorkDir(stagingDir(context.dirs.cache));\n\t\ttry {\n\t\t\tconst extracted = join(work, 'package');\n\t\t\tmkdirSync(extracted, { mode: 0o700 });\n\t\t\tawait safeExtract(source.file, extracted);\n\t\t\tcheckExtracted(extracted, candidate, context.nodeVersion);\n\t\t\twriteVerified(extracted, {\n\t\t\t\tversion: candidate.version,\n\t\t\t\tintegrity: candidate.integrity,\n\t\t\t\tkeyid,\n\t\t\t\tsha256: digests.sha256hex,\n\t\t\t\tsha224: digests.sha224hex,\n\t\t\t\tverifiedAt: new Date().toISOString(),\n\t\t\t});\n\t\t\tconst canonical = canonicalEntry(context.dirs.cache, candidate.version, candidate.integrity);\n\t\t\tmkdirSync(join(canonical, '..'), { recursive: true, mode: 0o700 });\n\t\t\tconst published = publishEntry(extracted, canonical, candidate.integrity, owner);\n\t\t\ttouchUsed(published.entryPath);\n\t\t\treturn published;\n\t\t} finally {\n\t\t\trmSync(work, { recursive: true, force: true });\n\t\t}\n\t}\n\n\treturn {\n\t\tnodeVersion: context.nodeVersion,\n\t\townNpm: () => context.own,\n\t\tcached: async () => listEntries(context.dirs.cache, context.keys),\n\t\tregistry: async (specs) => (await registryVersions(specs)).map(toCandidate),\n\t\tentryPathFor: (candidate) =>\n\t\t\tcanonicalEntry(context.dirs.cache, candidate.version, candidate.integrity),\n\t\tasync registryIdentity() {\n\t\t\tconst { config } = await factory.get();\n\t\t\treturn createHash('sha256').update(config.registry).digest('hex').slice(0, 12);\n\t\t},\n\t\tinstallTarball: (selection, source) => installTarball(selection, source),\n\t\tasync ensure(selection, options = {}) {\n\t\t\tconst { candidate } = selection;\n\t\t\tconst owner = ownerRecord(context.dirs.machine.id);\n\t\t\tif (candidate.entryPath !== null && validateEntry(candidate.entryPath, candidate.integrity)) {\n\t\t\t\tconst lease = await acquireShared(candidate.entryPath, owner);\n\t\t\t\t// A live prune gate means the entry is on its way out; fetch a private copy instead of waiting.\n\t\t\t\tif (lease !== null && validateEntry(candidate.entryPath, candidate.integrity)) {\n\t\t\t\t\ttouchUsed(candidate.entryPath);\n\t\t\t\t\treturn { entryPath: candidate.entryPath, lease };\n\t\t\t\t}\n\t\t\t\tlease?.release();\n\t\t\t}\n\t\t\t// Offline means offline even when the cached entry turned out unusable (spec RES-7).\n\t\t\tif (options.offline ?? (context.env['NPM_VM_OFFLINE'] ?? '') !== '') {\n\t\t\t\tthrow new NpmVmError(\n\t\t\t\t\t'M-NOMATCH',\n\t\t\t\t\tEXIT.resolution,\n\t\t\t\t\t`npm ${candidate.version} is not usable from the cache and NPM_VM_OFFLINE forbids the registry.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst { transport, config } = await factory.get();\n\t\t\tconst published = (await transport.view(candidate.version)).find(\n\t\t\t\t(item) => item.version === candidate.version,\n\t\t\t);\n\t\t\tif (published === undefined) {\n\t\t\t\tthrow new NpmVmError(\n\t\t\t\t\t'M-INTEGRITY',\n\t\t\t\t\tEXIT.verification,\n\t\t\t\t\tintegrityMessage(\n\t\t\t\t\t\tcandidate.integrity,\n\t\t\t\t\t\t'nothing',\n\t\t\t\t\t\t`the registry no longer serves npm ${candidate.version}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst work = newWorkDir(context.dirs.tmp);\n\t\t\ttry {\n\t\t\t\tconst packed = await transport.pack(candidate.version, work);\n\t\t\t\tconst source: PackedSource = {\n\t\t\t\t\tfile: packed.file,\n\t\t\t\t\tpublished,\n\t\t\t\t\tpublishedAt: async () => (await transport.times())[candidate.version] ?? null,\n\t\t\t\t\tregistry: config.registry,\n\t\t\t\t};\n\t\t\t\treturn await installTarball(selection, source, options.onPacked);\n\t\t\t} finally {\n\t\t\t\trmSync(work, { recursive: true, force: true });\n\t\t\t}\n\t\t},\n\t};\n}\n\n/** The extracted manifest is authoritative for name, version and engines (spec SEC-5). */\nfunction checkExtracted(dir: string, candidate: Candidate, nodeVersion: string): void {\n\tlet pkg: Record<string, unknown>;\n\ttry {\n\t\tpkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as Record<string, unknown>;\n\t} catch (error) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-INTEGRITY',\n\t\t\tEXIT.verification,\n\t\t\tintegrityMessage('npm package.json', 'unreadable', (error as Error).message),\n\t\t);\n\t}\n\tif (pkg['name'] !== 'npm' || pkg['version'] !== candidate.version) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-INTEGRITY',\n\t\t\tEXIT.verification,\n\t\t\tintegrityMessage(\n\t\t\t\t`npm@${candidate.version}`,\n\t\t\t\t`${String(pkg['name'])}@${String(pkg['version'])}`,\n\t\t\t\t'the tarball holds a different package',\n\t\t\t),\n\t\t);\n\t}\n\tconst engines = pkg['engines'];\n\tconst node =\n\t\ttypeof engines === 'object' && engines !== null\n\t\t\t? (engines as Record<string, unknown>)['node']\n\t\t\t: undefined;\n\tif (\n\t\ttypeof node === 'string' &&\n\t\t!semver.satisfies(nodeVersion, node, { includePrerelease: true })\n\t) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-ENGINE',\n\t\t\tEXIT.resolution,\n\t\t\tengineMessage(candidate.version, node, nodeVersion),\n\t\t);\n\t}\n}\n","import { readFileSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, join, matchesGlob, relative, resolve, sep } from 'node:path';\n\nexport interface ProjectLocation {\n\t/** npm's `localPrefix` for this argv and cwd (spec RES-2). */\n\troot: string;\n\t/** Global mode, computed as npm does (spec RES-3). */\n\tglobal: boolean;\n\t/** The `--prefix` the command line carries, resolved, when it carries one. */\n\tcliPrefix: string | null;\n}\n\ninterface CliFlags {\n\tprefix: string | null;\n\tglobal: boolean | null;\n\tlocation: string | null;\n\tworkspaces: boolean | null;\n}\n\nconst BOOLEANS = new Set(['global', 'workspaces']);\nconst SHORTHANDS: Record<string, string> = {\n\tC: 'prefix',\n\tg: 'global',\n\tL: 'location',\n\tws: 'workspaces',\n};\n\n/**\n * The subset of nopt that decides the prefix: `--flag value`, `--flag=value`, `--no-flag`, `--flag true|false` for booleans, npm's shorthands and `--`.\n * Later flags win, as in nopt.\n */\nexport function parsePrefixFlags(argv: readonly string[], cwd: string): CliFlags {\n\tconst flags: CliFlags = { prefix: null, global: null, location: null, workspaces: null };\n\tfor (let i = 0; i < argv.length; i += 1) {\n\t\tconst arg = argv[i] as string;\n\t\tif (arg === '--') {\n\t\t\tbreak;\n\t\t}\n\t\tlet name: string;\n\t\tlet value: string | null = null;\n\t\tif (arg.startsWith('--')) {\n\t\t\tconst eq = arg.indexOf('=');\n\t\t\tname = eq === -1 ? arg.slice(2) : arg.slice(2, eq);\n\t\t\tvalue = eq === -1 ? null : arg.slice(eq + 1);\n\t\t\tname = SHORTHANDS[name] ?? name;\n\t\t} else if (arg.startsWith('-') && arg.length > 1 && SHORTHANDS[arg.slice(1)] !== undefined) {\n\t\t\tname = SHORTHANDS[arg.slice(1)] as string;\n\t\t} else {\n\t\t\tcontinue;\n\t\t}\n\t\tlet negated = false;\n\t\tif (name.startsWith('no-') && BOOLEANS.has(name.slice(3))) {\n\t\t\tnegated = true;\n\t\t\tname = name.slice(3);\n\t\t}\n\t\tif (BOOLEANS.has(name)) {\n\t\t\tlet bool = !negated;\n\t\t\tif (value !== null) {\n\t\t\t\tbool = value !== 'false';\n\t\t\t} else if (!negated && (argv[i + 1] === 'true' || argv[i + 1] === 'false')) {\n\t\t\t\tbool = argv[i + 1] === 'true';\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t\tif (name === 'global') {\n\t\t\t\tflags.global = bool;\n\t\t\t} else {\n\t\t\t\tflags.workspaces = bool;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (name !== 'prefix' && name !== 'location') {\n\t\t\tcontinue;\n\t\t}\n\t\tif (value === null) {\n\t\t\tif (i + 1 >= argv.length) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalue = argv[i + 1] as string;\n\t\t\ti += 1;\n\t\t}\n\t\tif (name === 'prefix') {\n\t\t\tflags.prefix = resolve(cwd, value);\n\t\t} else {\n\t\t\tflags.location = value;\n\t\t}\n\t}\n\treturn flags;\n}\n\n/** Global mode from the command line and the npm env, CLI winning (spec RES-3). */\nexport function isGlobalMode(flags: CliFlags, env: NodeJS.ProcessEnv): boolean {\n\t// npm: `global || location === 'global'`, each setting resolved on its own, CLI over env.\n\tconst fromEnv = env['npm_config_global'];\n\t// npm ignores an empty value; nopt reads any other value as true except its spellings of false.\n\tconst global =\n\t\tflags.global ??\n\t\t(fromEnv === undefined || fromEnv === '' ? null : !['false', '0', 'null'].includes(fromEnv));\n\tconst location = flags.location ?? env['npm_config_location'] ?? null;\n\treturn global === true || location === 'global';\n}\n\nfunction hasPackageJson(dir: string): boolean {\n\ttry {\n\t\treturn statSync(join(dir, 'package.json')).isFile();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction hasNodeModules(dir: string): boolean {\n\ttry {\n\t\treturn statSync(join(dir, 'node_modules')).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction* walkUp(start: string): Generator<string> {\n\tlet dir = resolve(start);\n\tfor (;;) {\n\t\tyield dir;\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) {\n\t\t\treturn;\n\t\t}\n\t\tdir = parent;\n\t}\n}\n\n/** The `workspaces` patterns of a manifest: the array form or `{ packages: [] }`, else none. */\nexport function workspacePatterns(pkg: unknown): string[] {\n\tif (typeof pkg !== 'object' || pkg === null) {\n\t\treturn [];\n\t}\n\tlet raw = (pkg as { workspaces?: unknown }).workspaces;\n\tif (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {\n\t\traw = (raw as { packages?: unknown }).packages;\n\t}\n\tif (!Array.isArray(raw)) {\n\t\treturn [];\n\t}\n\treturn raw.filter((entry): entry is string => typeof entry === 'string');\n}\n\n/**\n * Whether `candidate` is one of the workspaces `root` declares, matched like `@npmcli/map-workspaces`.\n * A pattern selects directories holding a `package.json`, `!pattern` removes matches, and `node_modules` never matches.\n */\nexport function isWorkspaceOf(\n\troot: string,\n\tcandidate: string,\n\tpatterns: readonly string[],\n): boolean {\n\tconst rel = relative(root, candidate);\n\tif (rel === '' || rel.startsWith('..') || isAbsolute(rel) || !hasPackageJson(candidate)) {\n\t\treturn false;\n\t}\n\tif (rel.split(sep).includes('node_modules')) {\n\t\treturn false;\n\t}\n\tconst posix = rel.split(sep).join('/');\n\tconst { positive, negative } = splitPatterns(patterns);\n\treturn (\n\t\tpositive.some((pattern) => matchesGlob(posix, pattern)) &&\n\t\t!negative.some((pattern) => matchesGlob(posix, pattern))\n\t);\n}\n\n/*\n * map-workspaces drops a negated pattern when a later positive pattern falls under it,\n * so `['packages/**', '!packages/b/**', 'packages/b/a']` keeps `packages/b/a`.\n */\nfunction splitPatterns(patterns: readonly string[]): { positive: string[]; negative: string[] } {\n\tconst positive: string[] = [];\n\tconst negative: string[] = [];\n\tfor (const raw of patterns) {\n\t\tconst bangs = /^!+/.exec(raw)?.[0].length ?? 0;\n\t\tconst pattern = normalizePattern(raw.slice(bangs));\n\t\tif (bangs % 2 === 1) {\n\t\t\tnegative.push(pattern);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (let i = negative.length - 1; i >= 0; i -= 1) {\n\t\t\tif (matchesGlob(pattern, negative[i] as string)) {\n\t\t\t\tnegative.splice(i, 1);\n\t\t\t}\n\t\t}\n\t\tpositive.push(pattern);\n\t}\n\treturn { positive, negative };\n}\n\nfunction normalizePattern(pattern: string): string {\n\treturn pattern\n\t\t.replace(/\\\\/g, '/')\n\t\t.replace(/^\\.?\\/+/, '')\n\t\t.replace(/\\/+$/, '');\n}\n\nfunction readManifest(dir: string): unknown {\n\ttry {\n\t\treturn JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as unknown;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Mirrors `@npmcli/config` `loadLocalPrefix` (spec RES-2): a CLI prefix is final.\n * Otherwise the nearest ancestor with `package.json` or `node_modules` wins, promoted to a parent whose `workspaces` include it unless `--no-workspaces` or global mode.\n */\nexport function findProject(\n\targv: readonly string[],\n\tcwd: string,\n\tenv: NodeJS.ProcessEnv = process.env,\n): ProjectLocation {\n\tconst flags = parsePrefixFlags(argv, cwd);\n\tconst global = isGlobalMode(flags, env);\n\tif (flags.prefix !== null) {\n\t\treturn { root: flags.prefix, global, cliPrefix: flags.prefix };\n\t}\n\tlet localPrefix: string | null = null;\n\tfor (const dir of walkUp(cwd)) {\n\t\tconst manifest = hasPackageJson(dir);\n\t\tif (localPrefix === null) {\n\t\t\tif (manifest || hasNodeModules(dir)) {\n\t\t\t\tlocalPrefix = dir;\n\t\t\t\tif (flags.workspaces === false || global) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (!manifest) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst pkg = readManifest(dir);\n\t\tif (pkg !== null && isWorkspaceOf(dir, localPrefix, workspacePatterns(pkg))) {\n\t\t\tlocalPrefix = dir;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn { root: localPrefix ?? resolve(cwd), global, cliPrefix: null };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { EXIT, NpmVmError } from './errors.ts';\nimport { engineMessage, noMatchMessage } from './messages.ts';\nimport type { OwnNpm } from './own-npm.ts';\nimport { createContext, createInstaller } from './install/index.ts';\nimport { findProject } from './project.ts';\nimport { selectCandidate, ownNpmSatisfies, type Candidate, type Selection } from './select.ts';\nimport {\n\tparseSpecs,\n\tparseVersionSpec,\n\tSpecError,\n\ttype NpmSpec,\n\ttype OnFail,\n\ttype ParsedSpecs,\n} from './spec.ts';\n\n// The public API is `resolveNpm` and what it returns (spec section 3.1); everything else lives in `./internal`.\nexport type { NpmSpec, OnFail, ParsedSpecs } from './spec.ts';\nexport type { Candidate, Selection } from './select.ts';\nexport { EXIT, isNpmVmError, NpmVmError } from './errors.ts';\n\nexport interface ResolveSource {\n\tfile: string;\n\tfield: 'devEngines' | 'packageManager' | 'env';\n}\n\nexport interface ResolveResult {\n\tkind: 'own' | 'cached' | 'download';\n\tversion: string;\n\t/** Absolute path to `bin/npm-cli.js`; for a download, the path the entry will have once fetched. */\n\tcliPath: string;\n\tsource: ResolveSource | null;\n\tprojectRoot: string | null;\n\t/** Set for `cached` and `download`: what to fetch or verify. */\n\tselection: Selection | null;\n\t/** The project's npm requirements, when it declares any. */\n\tspecs: NpmSpec[] | null;\n\t/** A warning to print on stderr before running Node's own npm (`onFail: warn`). */\n\twarning: string | null;\n}\n\nexport interface ResolveOptions {\n\tenv?: NodeJS.ProcessEnv;\n\toffline?: boolean;\n\t/** The npm-vm home holding the cache namespace; defaults to `NPM_VM_HOME` or the platform location. */\n\thome?: string;\n}\n\n/** The lookups resolution depends on; the install layer provides the real ones. */\nexport interface ResolveProviders {\n\townNpm(): OwnNpm | null;\n\tcached(specs: readonly NpmSpec[]): Promise<Candidate[]>;\n\tregistry(specs: readonly NpmSpec[]): Promise<Candidate[]>;\n\tnodeVersion: string;\n\t/** Path a download will occupy, so callers can report it before fetching. */\n\tentryPathFor(candidate: Candidate): string;\n}\n\n/** Resolves the npm to run for `argv` in `cwd` (spec section 5); writes only under the cache, spawns npm only as the transport. */\nexport function resolveNpm(\n\targv: readonly string[],\n\tcwd: string,\n\toptions: ResolveOptions = {},\n): Promise<ResolveResult> {\n\tconst env = options.env ?? process.env;\n\treturn resolveNpmWith(argv, cwd, options, createInstaller(createContext(env, options.home)));\n}\n\nexport async function resolveNpmWith(\n\targv: readonly string[],\n\tcwd: string,\n\toptions: ResolveOptions,\n\tproviders: ResolveProviders,\n): Promise<ResolveResult> {\n\tconst env = options.env ?? process.env;\n\tconst own = providers.ownNpm();\n\tconst ownResult = (\n\t\tprojectRoot: string | null,\n\t\tsource: ResolveSource | null,\n\t\twarning: string | null,\n\t): ResolveResult => {\n\t\tif (own === null) {\n\t\t\tthrow new NpmVmError(\n\t\t\t\t'M-TRANSPORT',\n\t\t\t\tEXIT.transport,\n\t\t\t\t'No npm found beside the active Node; reinstall Node.',\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tkind: 'own',\n\t\t\tversion: own.version,\n\t\t\tcliPath: own.cliPath,\n\t\t\tsource,\n\t\t\tprojectRoot,\n\t\t\tselection: null,\n\t\t\tspecs: null,\n\t\t\twarning,\n\t\t};\n\t};\n\n\tif (nonEmpty(env['NPM_VM_DISABLE'])) {\n\t\treturn ownResult(null, null, null);\n\t}\n\tconst project = findProject(argv, cwd, env);\n\tif (project.global) {\n\t\treturn ownResult(project.root, null, null);\n\t}\n\n\tlet parsed: ParsedSpecs;\n\tlet source: ResolveSource;\n\tif (nonEmpty(env['NPM_VM_VERSION'])) {\n\t\tparsed = {\n\t\t\tspecs: [parseVersionSpec(env['NPM_VM_VERSION'] as string, 'NPM_VM_VERSION')],\n\t\t\tonFail: 'error',\n\t\t\tfield: 'devEngines',\n\t\t};\n\t\tsource = { file: 'NPM_VM_VERSION', field: 'env' };\n\t} else {\n\t\tconst file = join(project.root, 'package.json');\n\t\tlet read: ParsedSpecs | null;\n\t\ttry {\n\t\t\tread = readSpecs(file);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof SpecError)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst message = `${file}: ${error.message}`;\n\t\t\tconst failure = new NpmVmError('M-NOMATCH', EXIT.resolution, message);\n\t\t\treturn applyPolicy(error.onFail, failure, () => ownResult(project.root, null, message));\n\t\t}\n\t\tif (read === null) {\n\t\t\treturn ownResult(project.root, null, null);\n\t\t}\n\t\tparsed = read;\n\t\tsource = { file, field: read.field };\n\t}\n\n\tif (own !== null && ownNpmSatisfies(own.version, parsed.specs)) {\n\t\treturn ownResult(project.root, source, null);\n\t}\n\n\tconst cached = await providers.cached(parsed.specs);\n\tlet result = selectCandidate(parsed.specs, cached, providers.nodeVersion);\n\tif (result.kind === 'failed' && !options.offline && !nonEmpty(env['NPM_VM_OFFLINE'])) {\n\t\tlet fromRegistry: Candidate[];\n\t\ttry {\n\t\t\tfromRegistry = await providers.registry(parsed.specs);\n\t\t} catch (error) {\n\t\t\t// A download that cannot happen follows the project's policy like a missing version does.\n\t\t\tif (!(error instanceof NpmVmError) || error.id !== 'M-TRANSPORT') {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn applyPolicy(parsed.onFail, error, () =>\n\t\t\t\townResult(project.root, source, error.message),\n\t\t\t);\n\t\t}\n\t\tresult = selectCandidate(parsed.specs, fromRegistry, providers.nodeVersion);\n\t}\n\tif (result.kind === 'selected') {\n\t\tconst { candidate } = result.selection;\n\t\tconst entry = candidate.entryPath ?? providers.entryPathFor(candidate);\n\t\treturn {\n\t\t\tkind: candidate.entryPath === null ? 'download' : 'cached',\n\t\t\tversion: candidate.version,\n\t\t\tcliPath: join(entry, 'bin', 'npm-cli.js'),\n\t\t\tsource,\n\t\t\tprojectRoot: project.root,\n\t\t\tselection: result.selection,\n\t\t\tspecs: parsed.specs,\n\t\t\twarning: null,\n\t\t};\n\t}\n\n\tconst message =\n\t\tresult.failure.kind === 'engine'\n\t\t\t? engineMessage(result.failure.version, result.failure.enginesNode, providers.nodeVersion)\n\t\t\t: noMatchMessage(parsed.specs, source.file, result.failure.reason);\n\tconst id = result.failure.kind === 'engine' ? 'M-ENGINE' : 'M-NOMATCH';\n\tconst failure = new NpmVmError(id, EXIT.resolution, message);\n\treturn applyPolicy(parsed.onFail, failure, () => ownResult(project.root, source, message));\n}\n\n/** `onFail` makes a failed resolution fatal, a warning before Node's own npm, or silent (spec RES-7). */\nfunction applyPolicy(\n\tonFail: OnFail,\n\tfailure: NpmVmError,\n\tfallback: () => ResolveResult,\n): ResolveResult {\n\tif (onFail === 'ignore') {\n\t\treturn { ...fallback(), warning: null };\n\t}\n\tif (onFail === 'warn') {\n\t\treturn fallback();\n\t}\n\tthrow failure;\n}\n\n/** Reads and validates the project's specs; a broken file or range follows its own `onFail` when readable, else errors. */\nfunction readSpecs(file: string): ParsedSpecs | null {\n\tlet text: string;\n\ttry {\n\t\ttext = readFileSync(file, 'utf8');\n\t} catch {\n\t\treturn null;\n\t}\n\tlet pkg: unknown;\n\ttry {\n\t\tpkg = JSON.parse(text);\n\t} catch (error) {\n\t\tthrow new NpmVmError(\n\t\t\t'M-NOMATCH',\n\t\t\tEXIT.resolution,\n\t\t\t`${file} is not valid JSON: ${(error as Error).message}`,\n\t\t);\n\t}\n\treturn parseSpecs(pkg);\n}\n\nfunction nonEmpty(value: string | undefined): boolean {\n\treturn value !== undefined && value !== '';\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,88 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
"name": "@mawesome/npm-vm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Run the npm version a project declares in devEngines, whatever Node is active",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"devengines",
|
|
7
|
+
"fnm",
|
|
8
|
+
"npm",
|
|
9
|
+
"nvm",
|
|
10
|
+
"package-manager",
|
|
11
|
+
"version-manager"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/mawesomedev/mawesome/tree/main/packages/npm-vm#readme",
|
|
14
|
+
"bugs": "https://github.com/mawesomedev/mawesome/issues",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Manzoor Ahmad Wani",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/mawesomedev/mawesome.git",
|
|
20
|
+
"directory": "packages/npm-vm"
|
|
21
|
+
},
|
|
22
|
+
"bin": {
|
|
23
|
+
"npm-vm": "./dist/cli.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"main": "./dist/index.cjs",
|
|
31
|
+
"module": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"import": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"default": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"require": {
|
|
40
|
+
"types": "./dist/index.d.cts",
|
|
41
|
+
"default": "./dist/index.cjs"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"./internal": {
|
|
45
|
+
"import": {
|
|
46
|
+
"types": "./dist/internal.d.ts",
|
|
47
|
+
"default": "./dist/internal.js"
|
|
48
|
+
},
|
|
49
|
+
"require": {
|
|
50
|
+
"types": "./dist/internal.d.cts",
|
|
51
|
+
"default": "./dist/internal.cjs"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public",
|
|
58
|
+
"provenance": true
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@npmcli/config": "^10.14.0",
|
|
62
|
+
"semver": "^7.8.5",
|
|
63
|
+
"sigstore": "^4.1.1",
|
|
64
|
+
"tar": "^7.5.22",
|
|
65
|
+
"undici": "^7.30.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
69
|
+
"@mawesome/testing": "0.0.0",
|
|
70
|
+
"@mawesome/tsconfig": "0.0.0",
|
|
71
|
+
"@types/node": "^26.4.1",
|
|
72
|
+
"@types/semver": "^7.8.0",
|
|
73
|
+
"@typescript/native-preview": "7.0.0-dev.20260527.2",
|
|
74
|
+
"publint": "^0.3.24",
|
|
75
|
+
"tsdown": "^0.23.0",
|
|
76
|
+
"vitest": "^5.0.0"
|
|
77
|
+
},
|
|
78
|
+
"engines": {
|
|
79
|
+
"node": ">=22.9.0"
|
|
80
|
+
},
|
|
81
|
+
"scripts": {
|
|
82
|
+
"build": "tsdown",
|
|
83
|
+
"dev": "tsdown --watch",
|
|
84
|
+
"typecheck": "tsgo",
|
|
85
|
+
"test": "vitest run",
|
|
86
|
+
"check:exports": "attw --pack . --profile node16 && publint --strict"
|
|
87
|
+
}
|
|
88
|
+
}
|
package/index.js
DELETED