#!/usr/bin/env node // 持久下载缓存可以保留旧版本;交付给 CI 镜像的快照只带当前 lock 已下载的包。 import fs from 'node:fs/promises'; import { createRequire } from 'node:module'; import path from 'node:path'; import { pipeline } from 'node:stream/promises'; const [npmRoot, lockPath, source, destination] = process.argv.slice(2); if (!npmRoot || !lockPath || !source || !destination) { throw new Error( 'usage: export-ci-npm-download-cache.mjs ', ); } const require = createRequire(path.resolve(npmRoot, 'package.json')); const cacache = require('cacache'); const lock = JSON.parse(await fs.readFile(lockPath, 'utf8')); const integrities = new Set( Object.values(lock.packages).flatMap((entry) => typeof entry.integrity === 'string' ? [entry.integrity] : [], ), ); let count = 0; for await (const entry of cacache.ls.stream(source)) { if (!integrities.has(entry.integrity)) continue; await pipeline( cacache.get.stream(source, entry.key, { integrity: entry.integrity }), cacache.put.stream(destination, entry.key, { integrity: entry.integrity, metadata: entry.metadata, }), ); count += 1; } console.log( `[ci-image] exported ${count} npm cache entries for the current lock`, );