stammtisch-hersbruck/frontend/scripts/schema-to-json.mjs
Daniel Michelberger 2540666e1a feat: Typen aus der Schema-Migration erzeugen statt aus einer Instanz
npm run generate-pocketbase-types liest das Collections-Array jetzt direkt
aus backend/pb_migrations/ (scripts/schema-to-json.mjs) und speist es über
pocketbase-typegen --json ein. Keine laufende Instanz, kein Token, kein
Netzwerkzugriff mehr nötig.

Damit stammen Schema und Typen aus derselben versionierten Quelle und können
nicht auseinanderlaufen. Vorher zeigten sie auf eine Remote-Instanz, deren
Stand niemand garantieren konnte — nach dem Neu-Deployment lieferte sie
prompt Typen ohne die fachlichen Collections.

frontend/.env enthält dadurch nur noch PUBLIC_PB_URL. PB_TYPEGEN_URL und
PB_TYPEGEN_TOKEN entfallen (letztere wurde ohnehin nirgends gelesen),
PB_SUPERUSER_TOKEN wird nicht mehr gebraucht. Die Datei enthält damit kein
Geheimnis mehr.

Verifiziert: ohne .env, ohne Token und ohne laufende Instanz entstehen alle
sechs Collections, svelte-check meldet 0 Fehler und 0 Warnungen.

Die System-Collections (_superusers, _mfas, ...) fehlen in den Typen, weil
sie bewusst nicht in der Migration stehen. Die Anwendung verwendet sie nicht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 14:20:15 +02:00

52 lines
1.7 KiB
JavaScript

/**
* Extrahiert das Collections-Array aus der PocketBase-Migration und schreibt es
* als JSON auf stdout — in der Form, die `pocketbase-typegen --json` erwartet.
*
* Damit entstehen die TypeScript-Typen aus dem versionierten Schema im Repo,
* ohne laufende Instanz, ohne Token und ohne Netzwerkzugriff.
*
* Aufruf über npm run generate-pocketbase-types.
*/
import { readFileSync, readdirSync } from 'node:fs'
import { join } from 'node:path'
const MIGRATIONS_DIR = new URL('../../backend/pb_migrations/', import.meta.url).pathname
// Die Snapshot-Migration ist die einzige, die ein vollständiges
// `const collections = [...]` enthält. Bei mehreren Dateien gewinnt die
// jüngste — Migrationen sind nach Zeitstempel benannt.
const candidates = readdirSync(MIGRATIONS_DIR)
.filter((f) => f.endsWith('.js'))
.sort()
.reverse()
const MARKER = 'const collections = '
for (const file of candidates) {
const source = readFileSync(join(MIGRATIONS_DIR, file), 'utf8')
const start = source.indexOf(MARKER)
if (start === -1) continue
// Vom öffnenden [ bis zur zugehörigen schließenden Klammer zählen —
// ein Regex käme an den verschachtelten Arrays der Feldoptionen nicht vorbei.
const from = start + MARKER.length
let depth = 0
for (let i = from; i < source.length; i++) {
if (source[i] === '[') depth++
else if (source[i] === ']') {
depth--
if (depth === 0) {
process.stdout.write(source.slice(from, i + 1))
process.exit(0)
}
}
}
}
console.error(
`Keine Migration mit "${MARKER.trim()}" in ${MIGRATIONS_DIR} gefunden.\n` +
`Ohne sie lassen sich die Typen nicht aus dem Repo erzeugen.`
)
process.exit(1)