import type { Verweisziel } from '../shared/ipc'; import { VERWEISADRESSEN } from '../shared/verweise'; /** * Vom Schluessel zur Adresse - die Tafel selbst steht in `shared/verweise.ts`. * * WARUM DIESE STELLE UEBERHAUPT: Der Renderer schickt ueber * `IPC.oeffneVerweis` einen SCHLUESSEL und keine Adresse. Was geoeffnet wird, * entscheidet allein der Hauptprozess - hier. Naehme der Kanal eine Adresse * entgegen, bestimmte am Ende jeder, der etwas in die Oberflaeche traegt, * wohin `shell.openExternal` zeigt, und das ist im Zweifel eine Projektdatei * aus fremder Hand. Ueber genau dieses Muster liess sich im Altbestand * beliebiger Kode ausfuehren. * * Dass die Oberflaeche die Adresse KENNT, ist etwas anderes und unbedenklich: * Sie muss den Quellcodevermerk nach Artikel 3 der EUPL lesbar anzeigen. Lesen * darf sie, bestimmen nicht. */ /** Alle Schluessel - fuer die Pruefung, dass keiner ohne Adresse dasteht. */ export const VERWEISZIELE = Object.keys(VERWEISADRESSEN) as readonly Verweisziel[]; /** * Die Adresse zu einem Schluessel, oder `null`. * * `null` statt eines Ausnahmefehlers und statt eines Rueckfalls: Was hier * ankommt, kommt aus dem Renderer, und der Typ ist dort eine Behauptung und * keine Messung. Ein Rueckfall auf irgendeine Adresse waere die falsche * Richtung - was nicht in der Tafel steht, oeffnet nichts. * * Durchgehen statt nachschlagen, und ohne Zusicherung: Ein * `VERWEISADRESSEN[ziel as Verweisziel]` verlangte eine Zusicherung auf einen * Typ, den der Wert vielleicht gar nicht hat - genau die Behauptung, gegen die * diese Funktion geschrieben ist. Drei Eintraege durchzugehen kostet nichts, * und `Object.entries` fasst keine geerbten Eigennamen an: `__proto__` oder * `toString` ergeben damit keine Adresse. */ export function verweisadresse(ziel: unknown): string | null { for (const [schluessel, adresse] of Object.entries(VERWEISADRESSEN)) { if (schluessel === ziel) return adresse; } return null; }