import { link, readFile, rm } from "node:fs/promises"; import { join, resolve } from "node:path"; import { pathToFileURL } from "node:url"; import { atomicWrite, EDUCATIONAL_WARNING, networkSpec, readManifest } from "./finalize-manifest.mjs"; export async function selectManifest({ root = process.cwd(), network }) { const spec = networkSpec(network); const source = join(root, "deployments", spec.canonical); await readManifest(source); const contents = await readFile(source); const active = join(root, "deployments", "active.json"); await atomicWrite(active, contents); return { source, active }; } export async function archiveManifest({ root = process.cwd(), network, now = new Date(), io = {} }) { if (network !== "baseSepolia") throw new Error("only baseSepolia may be archived"); const spec = networkSpec(network); const source = join(root, "deployments", spec.canonical); await readManifest(source); if (!(now instanceof Date) || Number.isNaN(now.valueOf())) throw new Error("archive timestamp is invalid"); const timestamp = now.toISOString().replace(/[-:.]/g, ""); if (!/^\d{8}T\d{9}Z$/.test(timestamp)) throw new Error("archive timestamp is invalid"); const target = join(root, "deployments", `base-sepolia.${timestamp}.json`); const operations = { link, rm, ...io }; try { await operations.link(source, target); } catch (error) { if (error.code === "EEXIST") throw new Error("refusing to overwrite an existing Base Sepolia archive"); throw error; } try { await operations.rm(source); } catch (error) { await operations.rm(target, { force: true }).catch(() => {}); throw error; } return { source, path: target }; } export async function runSelectCli(argv, { root = process.cwd(), log = console.log } = {}) { log(EDUCATIONAL_WARNING); if (argv.length === 2 && argv[0] === "archive" && argv[1] === "baseSepolia") { return archiveManifest({ root, network: argv[1] }); } if (argv.length !== 1) throw new Error("usage: select-manifest.mjs | archive baseSepolia"); return selectManifest({ root, network: argv[0] }); } if (process.argv[1] && pathToFileURL(resolve(process.argv[1])).href === import.meta.url) { runSelectCli(process.argv.slice(2)).catch((error) => { console.error(error.message); process.exitCode = 1; }); }