export const formatAge = (ms: number | null | undefined) => { if (!ms || ms < 0) return "unknown"; const minutes = Math.round(ms / 60_000); if (minutes < 1) return "just now"; if (minutes < 60) return `${minutes}m ago`; const hours = Math.round(minutes / 60); if (hours < 48) return `${hours}h ago`; const days = Math.round(hours / 24); return `${days}d ago`; }; export const formatDuration = (ms: number | null | undefined) => { if (ms == null || !Number.isFinite(ms)) return "unknown"; if (ms < 1000) return `${Math.round(ms)}ms`; return `${(ms / 1000).toFixed(1)}s`; }; export function formatGatewayAuthUsed( auth: { token?: string; password?: string; } | null, ): "token" | "password" | "token+password" | "none" { const hasToken = Boolean(auth?.token?.trim()); const hasPassword = Boolean(auth?.password?.trim()); if (hasToken && hasPassword) return "token+password"; if (hasToken) return "token"; if (hasPassword) return "password"; return "none"; } export function redactSecrets(text: string): string { if (!text) return text; let out = text; out = out.replace( /(\b(?:access[_-]?token|refresh[_-]?token|token|password|secret|api[_-]?key)\b\s*[:=]\s*)("?)([^"\\s]+)("?)/gi, "$1$2***$4", ); out = out.replace(/\bBearer\s+[A-Za-z0-9._-]+\b/g, "Bearer ***"); out = out.replace(/\bsk-[A-Za-z0-9]{10,}\b/g, "sk-***"); return out; }