export type PopoReceiverType = "email" | "groupId"; /** * Normalize a POPO target string. * Supports formats: * - "user:email@example.com" -> "email@example.com" * - "group:123456" -> "123456" * - "email@example.com" -> "email@example.com" * - "123456" -> "123456" */ export function normalizePopoTarget(raw: string): string | null { const trimmed = raw.trim(); if (!trimmed) return null; const lowered = trimmed.toLowerCase(); if (lowered.startsWith("user:")) { return trimmed.slice("user:".length).trim() || null; } if (lowered.startsWith("group:")) { return trimmed.slice("group:".length).trim() || null; } return trimmed; } /** * Detect if a target is an email (P2P) or group ID. */ export function detectReceiverType(target: string): PopoReceiverType { // If it contains @ it's an email if (target.includes("@")) { return "email"; } // Otherwise assume it's a group ID return "groupId"; } /** * Format a POPO target for display. */ export function formatPopoTarget(id: string, type?: PopoReceiverType): string { const trimmed = id.trim(); const actualType = type ?? detectReceiverType(trimmed); if (actualType === "email") { return `user:${trimmed}`; } return `group:${trimmed}`; } /** * Check if a string looks like a POPO ID. */ export function looksLikePopoId(raw: string): boolean { const trimmed = raw.trim(); if (!trimmed) return false; // Has prefix if (/^(user|group):/i.test(trimmed)) return true; // Looks like an email if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)) return true; // Could be a group ID (numeric string) if (/^\d+$/.test(trimmed)) return true; return false; }