Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116import { env } from "$env/dynamic/private";
// accepts "0" to disable a limit; non-numeric values fall backconst bytes = (value: string | undefined, fallback: number) => { const raw = value?.trim(); if (!raw) return fallback; const parsed = Number(raw); return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;};
const cleanUrl = (value: string | undefined, fallback: string) => { const raw = value?.trim() || fallback; return raw.replace(/\/+$/, "");};
export type WebConfig = { bobbinUrl: string; knotMirrorUrl: string; apiUrl: string; deliberiUrl: string; /** the domain user sites are served under, e.g. "tngl.io" */ sitesDomain: string; camoUrl: string; avatarUrl: string; ogreUrl: string; /** the secrets camo and avatar sign with, so neither leaves the server */ camoSecret: string; avatarSecret: string; moderationServiceDid: string; turnstileSiteKey: string; /** see SSR_DIFF_MAX_BYTES */ ssrDiffMaxBytes: number; migratorUrl: string;};
export type PublicWebConfig = Pick< WebConfig, | "bobbinUrl" | "knotMirrorUrl" | "apiUrl" | "deliberiUrl" | "sitesDomain" | "moderationServiceDid" | "turnstileSiteKey" | "ssrDiffMaxBytes" | "ogreUrl" | "migratorUrl"> & { /** camo has a secret, so markup can route images through it */ camoEnabled: boolean;};
type WebConfigEnv = { BOBBIN_URL?: string; KNOTMIRROR_URL?: string; TANGLED_API_URL?: string; API_URL?: string; DELIBERI_URL?: string; KNOT_RESOLVER_URL?: string; SITES_DOMAIN?: string; CAMO_URL?: string; CAMO_SHARED_SECRET?: string; AVATAR_URL?: string; AVATAR_SHARED_SECRET?: string; OGRE_URL?: string; MODERATION_SERVICE_DID?: string; TURNSTILE_SITE_KEY?: string; MIGRATOR_URL?: string; /** diff payloads above this many bytes are not buffered through the ssr * worker; the page refetches them from the browser instead. "0" disables */ SSR_DIFF_MAX_BYTES?: string;};
export const resolveConfig = (values: WebConfigEnv): WebConfig => ({ bobbinUrl: cleanUrl(values.BOBBIN_URL, "http://127.0.0.1:8090"), knotMirrorUrl: cleanUrl(values.KNOTMIRROR_URL, ""), apiUrl: cleanUrl(values.TANGLED_API_URL ?? values.API_URL, "http://127.0.0.1:8080"), deliberiUrl: cleanUrl(values.DELIBERI_URL, "https://notifs-dev.tangled.network"), sitesDomain: values.SITES_DOMAIN?.trim() || "tngl.io", camoUrl: cleanUrl(values.CAMO_URL, "https://camo.tangled.sh"), avatarUrl: cleanUrl(values.AVATAR_URL, "https://avatar.tangled.sh"), ogreUrl: cleanUrl(values.OGRE_URL, "https://ogre.tangled.network"), migratorUrl: cleanUrl(values.MIGRATOR_URL, "https://migrator.tangled.sh"), camoSecret: values.CAMO_SHARED_SECRET?.trim() ?? "", avatarSecret: values.AVATAR_SHARED_SECRET?.trim() ?? "", moderationServiceDid: values.MODERATION_SERVICE_DID?.trim() ?? "", turnstileSiteKey: values.TURNSTILE_SITE_KEY?.trim() ?? "", ssrDiffMaxBytes: bytes(values.SSR_DIFF_MAX_BYTES, 5 * 1024 * 1024)});
// process env takes precedence over platform bindings in devexport const getConfig = (platform?: App.Platform): WebConfig => resolveConfig({ ...((platform?.env as WebConfigEnv | undefined) ?? {}), ...(env as WebConfigEnv) });
// listed one by one, so anything new in WebConfig stays private until it is// named hereexport const getPublicConfig = (platform?: App.Platform): PublicWebConfig => { const config = getConfig(platform); return { bobbinUrl: config.bobbinUrl, knotMirrorUrl: config.knotMirrorUrl, apiUrl: config.apiUrl, deliberiUrl: config.deliberiUrl, sitesDomain: config.sitesDomain, moderationServiceDid: config.moderationServiceDid, turnstileSiteKey: config.turnstileSiteKey, ssrDiffMaxBytes: config.ssrDiffMaxBytes, ogreUrl: config.ogreUrl, migratorUrl: config.migratorUrl, camoEnabled: config.camoSecret !== "" };};