ext-tasks/scripts/snapshot-schema.ts

82 lines
2.6 KiB
TypeScript

import {
existsSync,
mkdirSync,
readFileSync,
writeFileSync,
} from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const projectRoot = join(__dirname, "..");
const draftDir = join(projectRoot, "schema", "draft");
const version = process.argv[2];
function replaceRequired(
content: string,
search: string,
replacement: string,
source: string,
): string {
if (!content.includes(search)) {
throw new Error(`Expected release metadata not found in ${source}`);
}
return content.replace(search, replacement);
}
if (!version || !/^\d{4}-\d{2}-\d{2}$/.test(version)) {
throw new Error("Usage: npm run snapshot:schema -- YYYY-MM-DD");
}
const releaseDir = join(projectRoot, "schema", version);
if (existsSync(releaseDir)) {
throw new Error(`Release schema already exists: ${releaseDir}`);
}
mkdirSync(releaseDir, { recursive: false });
const schema = JSON.parse(
readFileSync(join(draftDir, "schema.json"), "utf-8"),
) as Record<string, unknown>;
schema.$id = `https://modelcontextprotocol.io/ext-tasks/${version}/schema.json`;
writeFileSync(
join(releaseDir, "schema.json"),
JSON.stringify(schema, null, 2) + "\n",
"utf-8",
);
const schemaTypes = replaceRequired(
readFileSync(join(draftDir, "schema.ts"), "utf-8"),
" * - Run `npm run generate:schemas` to regenerate schemas from these types",
" * - This released snapshot is immutable; make changes in schema/draft/ instead",
"schema/draft/schema.ts",
);
writeFileSync(join(releaseDir, "schema.ts"), schemaTypes, "utf-8");
const specSchema = JSON.parse(
readFileSync(join(draftDir, "spec.schema.json"), "utf-8"),
) as Record<string, unknown>;
if (typeof specSchema.$comment !== "string") {
throw new Error("Draft spec.schema.json is missing its provenance $comment");
}
specSchema.$comment = replaceRequired(
specSchema.$comment,
"DO NOT EDIT MANUALLY. Update with: npm run fetch:spec-schema",
`Immutable ${version} snapshot. Do not edit; update schema/draft/ instead`,
"schema/draft/spec.schema.json",
);
writeFileSync(
join(releaseDir, "spec.schema.json"),
JSON.stringify(specSchema, null, 2) + "\n",
"utf-8",
);
const specTypes = replaceRequired(
readFileSync(join(draftDir, "spec.types.ts"), "utf-8"),
" * DO NOT EDIT THIS FILE MANUALLY. Update with: npm run fetch:spec-schema",
` * Immutable ${version} snapshot. Do not edit; update schema/draft/ instead`,
"schema/draft/spec.types.ts",
);
writeFileSync(join(releaseDir, "spec.types.ts"), specTypes, "utf-8");
console.log(`Created immutable schema snapshot: ${releaseDir}`);