const DEFAULT_PORT = 5174 const DEFAULT_SQLITE_PATH = './leo-typing.db' function parsePort(value: string | undefined): number { if (!value) return DEFAULT_PORT const port = Number.parseInt(value, 10) if (Number.isNaN(port) || port < 1 || port > 65535) { throw new Error(`Invalid PORT value: ${value}`) } return port } function parseBoolean(value: string | undefined, fallback: boolean): boolean { if (!value) return fallback switch (value.toLowerCase()) { case '1': case 'true': case 'yes': case 'on': return true case '0': case 'false': case 'no': case 'off': return false default: throw new Error(`Invalid boolean value: ${value}`) } } const appOrigin = process.env.APP_ORIGIN ? new URL(process.env.APP_ORIGIN) : null export const runtimeConfig = { host: process.env.HOST || '127.0.0.1', port: parsePort(process.env.PORT), sqlitePath: process.env.SQLITE_PATH || DEFAULT_SQLITE_PATH, appOrigin, sessionCookieSecure: parseBoolean( process.env.SESSION_COOKIE_SECURE, appOrigin?.protocol === 'https:', ), } export function resolveOrigin(req: Request): string { return runtimeConfig.appOrigin?.origin || new URL(req.url).origin } export function resolveRpId(req: Request): string { return runtimeConfig.appOrigin?.hostname || new URL(req.url).hostname }