#!/usr/bin/env node /** * sync-openapi.mjs — holt die OpenAPI-Spec vom laufenden Tibi-Server * und legt sie als Referenz-Seite ab. Ohne laufenden Server: Platzhalter. * Aufruf: npm run sync:openapi * Env: TIBI_API_URL (default http://localhost:8080/api/v1), TIBI_NAMESPACE */ import { mkdirSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = join(dirname(fileURLToPath(import.meta.url)), '..'); const base = process.env.TIBI_API_URL ?? 'http://localhost:8080/api/v1'; const namespace = process.env.TIBI_NAMESPACE; const out = join(root, 'src', 'content', 'docs', 'reference', 'openapi.md'); const frontmatter = `---\ntitle: 'OpenAPI (generiert)'\ndescription: 'Projektspezifische OpenAPI-Spec vom laufenden tibi-server: Endpunkt, Abruf per curl und Sync.'\n---\n`; const erklaerung = `Die Spec erzeugt der Server frisch aus Config und Collections deines Projekts: \`GET /api/v1/_openapi/:project\`. Es gibt keine statische \`/openapi.json\` — jede Spec gehört zu genau einem Projekt (Namespace).\n\n\`\`\`bash title="Spec eines Projekts abrufen"\ncurl http://localhost:8080/api/v1/_openapi/meinprojekt\n\`\`\`\n\n\`npm run sync:openapi\` ruft diesen Endpunkt für \`$TIBI_NAMESPACE\` auf (Basis \`TIBI_API_URL\`, Default \`http://localhost:8080/api/v1\`) und schreibt das Ergebnis in diese Seite.\n\nLäuft der Admin hinter seinem Proxy, erreichst du dieselbe Spec auch über \`$CODING_TIBIADMIN_URL/api/_openapi/\` — der Proxy schreibt \`/api\` auf \`/api/v1\` um.\n`; function schreiben(stand, specBlock) { mkdirSync(dirname(out), { recursive: true }); writeFileSync(out, `${frontmatter}\n> Stand: ${stand} — nicht von Hand editieren.\n\n${erklaerung}${specBlock}`); } if (!namespace) { console.warn('[sync:openapi] TIBI_NAMESPACE fehlt — Platzhalter bleibt.'); process.exit(0); } try { const url = `${base}/_openapi/${namespace}`; const res = await fetch(url); if (!res.ok) throw new Error(`HTTP ${res.status}`); const spec = await res.text(); schreiben( `${new Date().toISOString()} · Quelle: \`${url}\` · Erzeugen mit \`npm run sync:openapi\``, `\n\`\`\`json\n${spec.slice(0, 20000)}\n\`\`\`\n\n_Volle Spec: \`${url}\`_\n`, ); console.log(`[sync:openapi] geschrieben: ${out}`); } catch (err) { console.warn(`[sync:openapi] Server nicht erreichbar (${base}/_openapi/${namespace}): ${err.message} — Platzhalter bleibt.`); }