Persist traffic settings and support multi-device traffic views
Build and Deploy Gateway / build-and-push (push) Successful in 32s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-08-31 06:46:59 +03:00
parent 6777422a27
commit 3c2eefe108
18 changed files with 653 additions and 124 deletions
+41
View File
@@ -0,0 +1,41 @@
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<string, unknown>
: {};
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,
};
}