import { Postbode } from "./plugin"; /* * Het logboek van het toestel: wat er een native plugin in gaat en wat eruit komt. Dit zit ook in * de release, want een fout die je niet kunt uitlezen is een fout waar je niets aan hebt — wie met * een toestel voor je staat waarop het misgaat, is uit te lezen met * * adb -s logcat -s Liefdesbrieven * * (de eigenaar moet daarvoor ontwikkelaarsopties en usb-foutopsporing aanzetten en de computer * eenmalig toestaan; zonder dat komt er niemand bij). De regels blijven op het toestel: ze gaan * naar het Android-logboek en nergens anders heen — geen server, geen bestand, geen tweede partij. * Andere apps kunnen er niet bij, dat kan sinds Android 4.1 alleen het systeem zelf. * * Waarom via de plugin en niet met console.log: Capacitor stuurt de console van de webview alleen * naar logcat in een debug-build. Die brug helemaal openzetten (loggingBehavior "production") zet * ook Capacitor's eigen regels aan, en die bevatten de ruwe invoer van élke plugin-aanroep — daar * staat het sessietoken in. Deze weg logt alleen wat hieronder is klaargemaakt, en verder niets. * * Wat er met opzet niet in komt: het sessietoken, wachtwoorden, en de onafgeronde coördinaten. Een * logregel is een kopie die blijft liggen, en van een toegangsbewijs is alleen interessant óf het * er was en hoe lang het is. Wie een precieze locatie in een logboek zet, heeft haar alsnog * opgeschreven. */ const GEHEIM = /^(token|password|wachtwoord|authorization|apikey)$/i; /* Een geheim wordt zijn lengte: genoeg om te zien of het er was, te weinig om het te gebruiken */ const verkort = (v) => (typeof v === "string" && v !== "" ? `<${v.length} tekens>` : ""); /* Waarden klaarmaken om te tonen; geheime velden worden vervangen, de rest gaat zoals hij is */ const schoon = (waarde) => { if (waarde === null || typeof waarde !== "object") return waarde; if (Array.isArray(waarde)) return waarde.map(schoon); return Object.fromEntries( Object.entries(waarde).map(([k, v]) => [k, GEHEIM.test(k) ? verkort(v) : schoon(v)]) ); }; /* Naar één regel, want logcat knipt op regels. Onleesbaar (cyclisch) mag nooit de app breken. */ export const toon = (waarde) => { if (waarde === undefined) return "undefined"; try { return JSON.stringify(schoon(waarde)); } catch { return String(waarde); } }; /* * Een regel wegschrijven mag nooit iets kapotmaken: het logboek is er om een storing te kunnen * zien, niet om er zelf een te worden. Vandaar de vangnetten en het bewust niet afwachten van de * plugin — logregels horen niet in de weg te lopen van waar de gebruiker op wacht. */ export const log = (...delen) => { const regel = delen.map((d) => (typeof d === "string" ? d : toon(d))).join(" "); if (Postbode) { try { Postbode.log({ regel }).catch(() => {}); } catch { /* een app-versie die deze methode nog niet kent: dan geen regel, en verder niets aan de hand */ } } else { console.log("[liefdesbrieven]", regel); // de browser tijdens het ontwikkelen } }; /* * Eén aanroep mét zijn antwoord. Beide kanten komen in het log: wat erin ging en wat eruit kwam — * of de afwijzing, en dan vooral de `code`, want daar zet een Capacitor-plugin de eigenlijke reden * in ("location-disabled", "location-timeout", …). De boodschap alleen is te vaag om iets aan te * hebben. */ export async function gelogd(naam, invoer, fn) { log(`→ ${naam}`, toon(invoer)); try { const uit = await fn(); log(`← ${naam}`, toon(uit)); return uit; } catch (e) { log(`✗ ${naam}`, toon({ code: e?.code ?? null, message: e?.message ?? String(e) })); throw e; } }