UNPKG

oras-pull

Version:
86 lines (85 loc) 3.24 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_process_1 = __importDefault(require("node:process")); const node_stream_1 = __importDefault(require("node:stream")); const cross_fetch_1 = __importDefault(require("cross-fetch")); const tar_1 = __importDefault(require("tar")); async function oauth(repo) { const token = node_process_1.default.env.GITHUB_TOKEN; if (token === undefined || token.startsWith("gh") === false) { return "QQ=="; } console.log("Token: \t" + repo); const tokenResponse = await (0, cross_fetch_1.default)(`https://ghcr.io/token?service=ghcr.io&scope=repository:${repo}:pull&client_id=npm-js-oras-pull`, { headers: { authorization: "Basic " + Buffer.from("foo:" + node_process_1.default.env.GITHUB_TOKEN).toString("base64"), } }); if (tokenResponse.status !== 200) { console.dir(await tokenResponse.json()); node_process_1.default.exit(1); } return (await tokenResponse.json()).token; } async function run() { const imageName = node_process_1.default.argv[2]; if (imageName === undefined) { console.log("Supply argument"); node_process_1.default.exit(1); } console.log("Pull: \t" + imageName); let [url, tag] = imageName.split(":"); const repo = url.replace("ghcr.io/", "").split("/").splice(0, 2).join("/"); const bearer = await oauth(repo); url = url.replace("ghcr.io", "https://ghcr.io/v2"); const manifestResponse = await (0, cross_fetch_1.default)(url + '/manifests/' + tag, { headers: { accept: "application/vnd.oci.image.manifest.v1+json", authorization: "Bearer " + bearer } }); if (manifestResponse.status !== 200) { console.dir(await manifestResponse.json()); node_process_1.default.exit(1); } const manifest = await manifestResponse.json(); const layer = manifest.layers[0]; console.log("Digest: " + layer.digest); console.log("Size: \t" + layer.size + " bytes"); const blobResponse = await (0, cross_fetch_1.default)(url + '/blobs/' + layer.digest, { headers: { authorization: "Bearer " + bearer } }); if (blobResponse.status !== 200) { console.dir(await manifestResponse.json()); node_process_1.default.exit(1); } const responseBuffer = Buffer.from(await blobResponse.arrayBuffer()); const readableStream = node_stream_1.default.Readable.from(responseBuffer); console.log(""); let count = 0; const st = readableStream.pipe(tar_1.default.extract({ onentry: entry => { count++; if (count < 10) { console.log("Extract: " + entry.path); } else if (count % 100 === 0) { console.log(count); } } })); st.on('finish', () => { console.log(count + " folders/files extracted"); }); } run().then(() => { // process.exit(); }).catch((err) => { console.log(err); node_process_1.default.exit(1); });