58 lines
1.9 KiB
JavaScript
58 lines
1.9 KiB
JavaScript
import { execFile } from "node:child_process";
|
|
import { createHash } from "node:crypto";
|
|
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { basename, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { promisify } from "node:util";
|
|
|
|
const manifest = JSON.parse(
|
|
await readFile(new URL("../contracts/manifest.json", import.meta.url), "utf8"),
|
|
);
|
|
const run = promisify(execFile);
|
|
const projectRoot = fileURLToPath(new URL("../", import.meta.url));
|
|
const generator = join(
|
|
projectRoot,
|
|
"node_modules",
|
|
"openapi-typescript",
|
|
"bin",
|
|
"cli.js",
|
|
);
|
|
const temporaryDirectory = await mkdtemp(
|
|
join(tmpdir(), "tjwater-api-contracts-"),
|
|
);
|
|
|
|
try {
|
|
for (const [name, contract] of Object.entries(manifest.contracts)) {
|
|
const contractPath = fileURLToPath(
|
|
new URL(`../contracts/${contract.file}`, import.meta.url),
|
|
);
|
|
const payload = await readFile(contractPath);
|
|
const actual = createHash("sha256").update(payload).digest("hex");
|
|
if (actual !== contract.sha256) {
|
|
throw new Error(
|
|
`${name} contract hash mismatch: expected ${contract.sha256}, got ${actual}`,
|
|
);
|
|
}
|
|
|
|
const generatedName = `${name}Api.ts`;
|
|
const temporaryOutput = join(temporaryDirectory, generatedName);
|
|
await run(process.execPath, [generator, contractPath, "-o", temporaryOutput]);
|
|
const expectedOutput = await readFile(
|
|
new URL(`../src/generated/${generatedName}`, import.meta.url),
|
|
);
|
|
const generatedOutput = await readFile(temporaryOutput);
|
|
if (!expectedOutput.equals(generatedOutput)) {
|
|
throw new Error(
|
|
`${basename(contract.file)} generated type is stale: run \`npm run api:generate\``,
|
|
);
|
|
}
|
|
}
|
|
} finally {
|
|
await rm(temporaryDirectory, { recursive: true, force: true });
|
|
}
|
|
|
|
console.log(
|
|
`validated API contract mirrors and generated types for ${manifest.contract_version}`,
|
|
);
|