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>
52 lines
1.7 KiB
JavaScript
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)
|