import type { FlowAnalyticsDto, FlowClientsDto, FlowExportersDto, FlowMapHopsDto, FlowMonthlyDto, FlowPurgeDto, FlowStatsDto, TrafficFlowHostFile, TrafficFlowOverlayResult, TrafficFlowSettingsDto, TrafficFlowSettingsPatch, } from "@mmapp/contracts/traffic-flow" import { requestJson } from "@/shared/api/http-client" export type { TrafficFlowHostFile } export async function getTrafficFlowSettings(baseUrl: string): Promise { return requestJson(baseUrl, "/api/traffic/flow/settings") } export async function putTrafficFlowSettings( baseUrl: string, patch: TrafficFlowSettingsPatch, ): Promise<{ ok: boolean; settings: TrafficFlowSettingsDto }> { return requestJson(baseUrl, "/api/traffic/flow/settings", { method: "PUT", body: JSON.stringify(patch), }) } export async function generateTrafficFlowKeys(baseUrl: string): Promise<{ ok: boolean created: boolean publicKey: string settings: TrafficFlowSettingsDto }> { return requestJson(baseUrl, "/api/traffic/flow/settings/generate-keys", { method: "POST" }) } export async function getTrafficFlowHostFiles(baseUrl: string): Promise<{ files: TrafficFlowHostFile[] }> { return requestJson(baseUrl, "/api/traffic/flow/host-files") } export async function applyTrafficFlowOverlay( baseUrl: string, serverId: string | number, publicEndpoint?: string, ): Promise { return requestJson(baseUrl, "/api/traffic/flow-overlay", { method: "POST", body: JSON.stringify({ serverId, publicEndpoint }), }) } export async function getTrafficFlows(baseUrl: string, range = "5m"): Promise { return requestJson(baseUrl, `/api/traffic/flows?range=${encodeURIComponent(range)}`) } function flowQuery(params: { range?: string serverId?: string userId?: string iface?: string dedup?: boolean excludeMesh?: boolean excludeOverlay?: boolean }): string { const q = new URLSearchParams() if (params.range) q.set("range", params.range) if (params.serverId) q.set("serverId", params.serverId) if (params.userId) q.set("userId", params.userId) if (params.iface && params.iface !== "__all__") q.set("iface", params.iface) if (params.dedup === false) q.set("dedup", "0") else if (params.dedup === true) q.set("dedup", "1") if (params.excludeMesh === false) q.set("excludeMesh", "0") else if (params.excludeMesh === true) q.set("excludeMesh", "1") if (params.excludeOverlay === false) q.set("excludeOverlay", "0") else if (params.excludeOverlay === true) q.set("excludeOverlay", "1") const s = q.toString() return s ? `?${s}` : "" } export async function getFlowExporters(baseUrl: string, range = "5m"): Promise { return requestJson(baseUrl, `/api/traffic/flow/exporters?range=${encodeURIComponent(range)}`) } export async function getFlowClients(baseUrl: string, range = "5m"): Promise { return requestJson(baseUrl, `/api/traffic/flow/clients?range=${encodeURIComponent(range)}`) } export async function getFlowMapHops( baseUrl: string, params: { range?: string serverId?: string userId?: string iface?: string dedup?: boolean excludeMesh?: boolean excludeOverlay?: boolean } = {}, ): Promise { return requestJson(baseUrl, `/api/traffic/flow/map-hops${flowQuery({ range: params.range ?? "5m", serverId: params.serverId, userId: params.userId, iface: params.iface, dedup: params.dedup, excludeMesh: params.excludeMesh, excludeOverlay: params.excludeOverlay, })}`) } export async function getFlowAnalytics( baseUrl: string, params: { range?: string serverId?: string userId?: string iface?: string dedup?: boolean excludeMesh?: boolean excludeOverlay?: boolean }, ): Promise { return requestJson(baseUrl, `/api/traffic/flow/analytics${flowQuery(params)}`) } export async function getFlowMonthly( baseUrl: string, params: { month: string; serverId?: string }, ): Promise { const q = new URLSearchParams() q.set("month", params.month) if (params.serverId) q.set("serverId", params.serverId) return requestJson(baseUrl, `/api/traffic/flow/monthly?${q.toString()}`) } export async function purgeTrafficFlowData(baseUrl: string): Promise { return requestJson(baseUrl, "/api/traffic/flow/purge", { method: "POST" }) } export { flowQuery }