9ef864d1f2
Closes #304. ## Summary The three `/schema/*.json` URLs baked into every Hyperframes project as `\$schema` references are 404ing on the live docs site — blocking editor autocomplete and validation. - \`https://hyperframes.heygen.com/schema/hyperframes.json\` — **404** (missing entirely) - \`https://hyperframes.heygen.com/schema/registry.json\` — **404** (only in npm package) - \`https://hyperframes.heygen.com/schema/registry-item.json\` — **404** (only in npm package) Mintlify serves top-level non-MDX dirs in \`docs/\` at \`/\<dir>/*\` (confirmed by \`docs/logo/*.svg\` → \`/logo/*.svg\`). This PR drops the three schemas into \`docs/schema/\` so the URLs resolve. ## What changed | File | Role | |---|---| | \`docs/schema/hyperframes.json\` | **New.** Authored from the \`ProjectConfig\` type in \`packages/cli/src/utils/projectConfig.ts\`. | | \`docs/schema/registry.json\` | Mirror of \`packages/core/schemas/registry.json\`. | | \`docs/schema/registry-item.json\` | Mirror of \`packages/core/schemas/registry-item.json\`. | | \`scripts/sync-schemas.ts\` | Keeps the registry mirrors in lockstep with their authoritative copies in \`packages/core/schemas/\`. \`--check\` mode fails the Docs workflow on drift. | | \`.github/workflows/docs.yml\` | Runs \`tsx scripts/sync-schemas.ts --check\` on every PR touching docs or core schemas. | | \`package.json\` | \`sync-schemas\` / \`sync-schemas:check\` npm scripts. | ## Why not make \`packages/core/schemas/\` authoritative for \`hyperframes.json\` too? \`hyperframes.json\` is CLI config, not a core type. Keeping the schema in \`docs/\` avoids an artificial dependency between \`@hyperframes/core\` and \`@hyperframes/cli\`. If the two ever need to align, we can flip the direction then. ## Verification - \`bun run sync-schemas:check\` → \`2/2 in sync\`. - Ajv (draft 2020-12, in-process) validation against 9 cases: - ✓ real factory-series-c-video config - ✓ default shape from \`hyperframes init\` - ✓ \`\$schema\` is optional - ✓ missing registry → rejected - ✓ missing paths.assets → rejected - ✓ extra top-level key → rejected - ✓ empty registry string → rejected - ✓ empty block path → rejected - ✓ missing paths entirely → rejected ## Test plan - [x] \`tsx scripts/sync-schemas.ts --check\` passes locally - [x] Schemas parse as valid JSON and validate real/default project configs - [x] After merge: \`curl -sI https://hyperframes.heygen.com/schema/hyperframes.json\` returns 200 once Mintlify redeploys - [x] Same check for \`/schema/registry.json\` and \`/schema/registry-item.json\` - [x] VS Code autocomplete and error-highlighting work on \`hyperframes.json\` without extra config ## Notes - The Docs workflow now triggers on \`packages/core/schemas/**\` and \`scripts/sync-schemas.ts\` in addition to \`docs/**\`, so a core-schemas change that forgets to run \`sync-schemas\` will fail CI instead of silently publishing stale docs. - No runtime / API changes to any package; ship independent of a version bump.
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
#!/usr/bin/env tsx
|
|
/**
|
|
* Mirror JSON Schemas from `packages/core/schemas/` into `docs/schema/` so
|
|
* Mintlify serves them at `https://hyperframes.heygen.com/schema/*`. The core
|
|
* copies stay authoritative — they're exported from `@hyperframes/core` for
|
|
* npm consumers — and this script is the single contract that prevents the
|
|
* docs mirror from drifting.
|
|
*
|
|
* Usage:
|
|
* bun run sync-schemas # copy core → docs
|
|
* bun run sync-schemas --check # exit non-zero if copies are stale (CI)
|
|
*
|
|
* `docs/schema/hyperframes.json` is authored directly in docs (no source in
|
|
* core) so it's skipped by this script.
|
|
*/
|
|
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const ROOT = join(import.meta.dirname, "..");
|
|
const SOURCE_DIR = join(ROOT, "packages/core/schemas");
|
|
const TARGET_DIR = join(ROOT, "docs/schema");
|
|
const MIRRORED = ["registry.json", "registry-item.json"];
|
|
|
|
function main() {
|
|
const checkOnly = process.argv.includes("--check");
|
|
let drift = 0;
|
|
|
|
for (const name of MIRRORED) {
|
|
const source = readFileSync(join(SOURCE_DIR, name), "utf-8");
|
|
const targetPath = join(TARGET_DIR, name);
|
|
const target = (() => {
|
|
try {
|
|
return readFileSync(targetPath, "utf-8");
|
|
} catch {
|
|
return null;
|
|
}
|
|
})();
|
|
|
|
if (target === source) {
|
|
console.log(` ✓ ${name} in sync`);
|
|
continue;
|
|
}
|
|
|
|
drift++;
|
|
if (checkOnly) {
|
|
console.error(` ✗ ${name} out of sync (run \`bun run sync-schemas\` to fix)`);
|
|
continue;
|
|
}
|
|
writeFileSync(targetPath, source);
|
|
console.log(` → ${name} updated`);
|
|
}
|
|
|
|
if (checkOnly && drift > 0) {
|
|
console.error(`\n${drift} schema${drift === 1 ? "" : "s"} drifted from source.`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|