export const TRAFFIC_RETENTION_OPTIONS = [5, 10, 30] as const; export type TrafficGrouping = 'site' | 'device'; export type TrafficSort = 'popular' | 'recent'; export type TrafficRetentionSeconds = typeof TRAFFIC_RETENTION_OPTIONS[number]; export interface TrafficSettings { grouping: TrafficGrouping; sort: TrafficSort; retentionSeconds: TrafficRetentionSeconds; } export const DEFAULT_TRAFFIC_SETTINGS: TrafficSettings = { grouping: 'site', sort: 'popular', retentionSeconds: 10, }; export function normalizeTrafficSettings( value: unknown, { strict = false }: { strict?: boolean } = {}, ): TrafficSettings { const candidate = value && typeof value === 'object' && !Array.isArray(value) ? value as Record : {}; const grouping = candidate.grouping; const sort = candidate.sort; const retentionSeconds = candidate.retentionSeconds; if (strict && ( !['site', 'device'].includes(String(grouping)) || !['popular', 'recent'].includes(String(sort)) || !TRAFFIC_RETENTION_OPTIONS.includes(Number(retentionSeconds) as TrafficRetentionSeconds) )) throw new TypeError('Invalid traffic settings'); return { grouping: grouping === 'device' ? 'device' : 'site', sort: sort === 'recent' ? 'recent' : 'popular', retentionSeconds: TRAFFIC_RETENTION_OPTIONS.includes(Number(retentionSeconds) as TrafficRetentionSeconds) ? Number(retentionSeconds) as TrafficRetentionSeconds : DEFAULT_TRAFFIC_SETTINGS.retentionSeconds, }; }