import type { BgpCommunity, DohProfile, ModuleRow } from '$lib/api/types.js'; export const NONE_OPTION = '__none__'; export function supportsCsvIO(type: ModuleRow['type'] | null | undefined): boolean { return type === 'AS_PREFIXES' || type === 'DOMAINS' || type === 'IP_RANGES'; } export function sanitizeFilenamePart(v: string): string { const cleaned = v .trim() .toLowerCase() .replace(/[^a-z0-9._-]+/g, '-') .replace(/-+/g, '-') .replace(/^[-_.]+|[-_.]+$/g, ''); return cleaned || 'module'; } export function communityLabel(id: string | null, communities: BgpCommunity[]): string { if (!id) return '—'; const c = communities.find((x) => x.id === id); if (!c) return id.slice(0, 8) + '…'; const t = c.title?.trim(); return t || c.community; } export function communityOptionLabel(c: BgpCommunity): string { const t = c.title?.trim(); return t || c.community; } export function nullableSelectValue(value: string | null | undefined): string { if (value === null || value === undefined || value === '') return NONE_OPTION; return value; } export function fromNullableSelect(value: string): string | null { if (value === NONE_OPTION || value === '') return null; return value; } export function moduleDohProfileIds(modRow: ModuleRow | null): string[] { if (!modRow) return []; if (modRow.doh_profile_ids?.length) return modRow.doh_profile_ids; return modRow.doh_profile_id ? [modRow.doh_profile_id] : []; } export function dohProfileLabel(id: string, dohProfiles: DohProfile[]): string { const p = dohProfiles.find((d) => d.id === id); return p ? (p.name?.trim() ? `${p.name} (${p.url})` : p.url) : id.slice(0, 8) + '…'; } export function normalizeCdnSourceKind(k: string): 'plaintext' | 'json' { return k.trim().toLowerCase() === 'json' ? 'json' : 'plaintext'; } export function syncSelection(selected: Set, existingIds: string[]): Set { const validIds = new Set(existingIds); return new Set([...selected].filter((id) => validIds.has(id))); }