export function sanitizeFilenameSegment(value: string | null | undefined, fallback = ''): string { if (typeof value !== 'string') { return fallback; } const normalized = value .trim() .normalize('NFKD') .replace(/[\u0300-\u036f]/g, ''); const slug = normalized.replace(/[^A-Za-z0-9]+/g, '-').replace(/^-+|-+$/g, '').toLowerCase(); return slug.length ? slug : fallback; } export function normalizeEventDateSegment(dateValue: string | null | undefined): string | null { if (!dateValue) { return null; } const trimmed = dateValue.trim(); if (!trimmed) { return null; } const isoCandidate = trimmed.slice(0, 10); if (/^\d{4}-\d{2}-\d{2}$/.test(isoCandidate)) { return isoCandidate; } const parsed = new Date(trimmed); if (Number.isNaN(parsed.getTime())) { return null; } return parsed.toISOString().slice(0, 10); } export function buildDownloadFilename( parts: Array, extension: string, fallback = 'download', ): string { const sanitizedParts = parts .map((part) => sanitizeFilenameSegment(part, '')) .filter((segment) => segment.length > 0); const base = sanitizedParts.length ? sanitizedParts.join('-') : fallback; const cleanExtension = sanitizeFilenameSegment(extension, '').replace(/[^a-z0-9]/gi, '') || 'bin'; return `${base}.${cleanExtension.toLowerCase()}`; }