1/**2 * Sanitizer for owner-editable public metadata (title/description), following3 * the sanitizeSay precedent in @tribes/script-host: strip control and4 * bidi-override characters (they'd render in every Browse visitor's page),5 * collapse whitespace runs, trim, cap length. Returns null when nothing6 * printable remains - callers store null instead of an empty string.7 */89// eslint-disable-next-line no-control-regex10const STRIP_RE = new RegExp(11 '[' +12 '\\u0000-\\u001f' + // C0 controls13 '\\u007f' + // DEL14 '\\u202a-\\u202e' + // bidi embeddings/overrides15 '\\u2066-\\u2069' + // bidi isolates16 '\\u200b-\\u200f' + // zero-width + LRM/RLM17 '\\ufeff' + // BOM / zero-width no-break space18 ']',19 'g',20);2122export function sanitizeMeta(raw: string, maxChars: number): string | null {23 const cleaned = raw24 .replace(/\s+/g, ' ') // whitespace (incl. newlines/tabs) collapses to one space25 .replace(STRIP_RE, '') // remaining controls/bidi/zero-width vanish outright26 .replace(/ +/g, ' ') // stripping may have fused two spaces together27 .trim()28 .slice(0, maxChars)29 .trim();30 return cleaned.length > 0 ? cleaned : null;31}