import { createHash } from "node:crypto"; import { mkdir, writeFile } from "node:fs/promises"; import { dirname } from "node:path"; import { CONTRACT_SET_ALGORITHM, computeContractSetDigestWith, type ContractSetPackage, } from "../src/contracts/contract-set-canonical.ts"; import { EXPECTED_CONTRACT_SET_PACKAGES } from "../src/features/installed-contract-contributions.ts"; /** * §5.4 / §17.2.2 step 2. Derives the build-time expected contract set from the * installed contributions and emits it as generated source for the manifest * writer. `TEMPLATE_FIXTURE` provenance never reaches this list, so a fixture * cannot influence the release digest. */ const OUTPUT = ".generated/frontend-runtime/contract-set.ts"; function sha256(bytes: Uint8Array): Uint8Array { return new Uint8Array(createHash("sha256").update(bytes).digest()); } export function buildContractSet( packages: readonly ContractSetPackage[] = EXPECTED_CONTRACT_SET_PACKAGES as readonly ContractSetPackage[], ) { return Object.freeze({ setAlgorithm: CONTRACT_SET_ALGORITHM, setDigest: computeContractSetDigestWith(packages, sha256), packages: Object.freeze( [...packages] .map((entry) => Object.freeze({ ...entry })) .sort((left, right) => (left.packageId < right.packageId ? -1 : 1)), ), }); } async function main(): Promise { const contractSet = buildContractSet(); const source = [ "// Generated by scripts/generate-contract-set.ts. Do not edit.", "// Regenerated from scratch on every build; never committed.", "", "import type { ContractSet } from \"../../src/contracts/contract-set.ts\";", "", `export const BUILD_CONTRACT_SET: ContractSet = ${JSON.stringify( contractSet, null, 2, )} as const;`, "", ].join("\n"); await mkdir(dirname(OUTPUT), { recursive: true }); await writeFile(OUTPUT, source, "utf8"); process.stdout.write( `contract set: ${contractSet.packages.length} package(s) ${contractSet.setDigest}\n`, ); } if (process.argv[1]?.endsWith("generate-contract-set.ts")) { await main(); }