#!/usr/bin/env node /** * @file Regenerates the repo-root `openapi.yaml` from the single source of * truth — `createOpenApiSpec()` in `server/openapi.js`. The JSON spec served at * `/api/openapi.json` and this committed YAML mirror are therefore always in * sync: run `npm run openapi:yaml` after any spec change. Never hand-edit * `openapi.yaml`. * @author Nguyễn Ngọc Trí Vĩ */ const fs = require("fs"); const path = require("path"); const yaml = require("js-yaml"); const { createOpenApiSpec } = require("../server/openapi"); const OUT = path.join(__dirname, "..", "openapi.yaml"); /** The exact bytes `openapi.yaml` must contain for the current spec. Exported so * the drift test can compare against the committed file without duplicating the * dump options — a second copy of them would let the two definitions diverge, * which is the very staleness this file exists to prevent. */ function render() { const spec = createOpenApiSpec(); const body = yaml.dump(spec, { lineWidth: -1, // don't wrap long strings (keeps descriptions/examples intact) noRefs: true, // inline any shared object references for a portable document sortKeys: false, // preserve authored key order }); const header = "# DO NOT EDIT BY HAND. Generated from server/openapi.js via `npm run openapi:yaml`.\n" + "# This YAML mirrors the live spec served at GET /api/openapi.json.\n"; return { text: header + body, pathCount: Object.keys(spec.paths || {}).length }; } function main() { const { text, pathCount } = render(); fs.writeFileSync(OUT, text, "utf8"); console.log(`Wrote ${OUT} (${pathCount} paths, ${fs.statSync(OUT).size} bytes).`); } if (require.main === module) main(); module.exports = { render, OUT };