63 lines
2.1 KiB
JavaScript
63 lines
2.1 KiB
JavaScript
import { createHash } from "node:crypto";
|
|
import { readFile, readdir } from "node:fs/promises";
|
|
import { resolve } from "node:path";
|
|
|
|
const root = resolve(import.meta.dirname, "..");
|
|
const sourcePath = resolve(root, "crates/nana-domain/src/lib.rs");
|
|
const hashPath = resolve(root, "contracts/.source.sha256");
|
|
const schemaDirectory = resolve(root, "contracts/schema");
|
|
|
|
const source = await readFile(sourcePath);
|
|
const expectedHash = (await readFile(hashPath, "utf8")).trim();
|
|
const actualHash = createHash("sha256").update(source).digest("hex");
|
|
|
|
if (actualHash !== expectedHash) {
|
|
throw new Error(
|
|
"Generated contracts are stale. Install Rust and run `pnpm contracts:generate`."
|
|
);
|
|
}
|
|
|
|
const schemaFiles = (await readdir(schemaDirectory))
|
|
.filter((name) => name.endsWith(".schema.json"))
|
|
.sort();
|
|
|
|
const required = [
|
|
"app-info.schema.json",
|
|
"character-card.schema.json",
|
|
"demo-pack-summary.schema.json",
|
|
"fork-branch-request.schema.json",
|
|
"fork-branch-result.schema.json",
|
|
"item-spec.schema.json",
|
|
"persona.schema.json",
|
|
"player-view.schema.json",
|
|
"plot-module.schema.json",
|
|
"resource-bundle.schema.json",
|
|
"resource-header.schema.json",
|
|
"runtime-state.schema.json",
|
|
"story-node.schema.json",
|
|
"turn-failure.schema.json",
|
|
"turn-request.schema.json",
|
|
"turn-result.schema.json",
|
|
"world-book.schema.json"
|
|
];
|
|
|
|
for (const name of required) {
|
|
if (!schemaFiles.includes(name)) {
|
|
throw new Error(`Missing generated schema: contracts/schema/${name}`);
|
|
}
|
|
}
|
|
|
|
for (const name of schemaFiles) {
|
|
const value = JSON.parse(await readFile(resolve(schemaDirectory, name), "utf8"));
|
|
if (typeof value !== "object" || value === null || value.$schema === undefined) {
|
|
throw new Error(`Invalid generated schema: contracts/schema/${name}`);
|
|
}
|
|
}
|
|
|
|
const typeScript = await readFile(resolve(root, "contracts/ts/index.ts"), "utf8");
|
|
if (!typeScript.startsWith("// @generated by crates/nana-contracts")) {
|
|
throw new Error("contracts/ts/index.ts is not marked as generated");
|
|
}
|
|
|
|
console.log(`Verified ${schemaFiles.length} schemas and TypeScript DTO source hash.`);
|