37 lines
2.9 KiB
TypeScript
37 lines
2.9 KiB
TypeScript
import { z } from "zod"
|
|
import { logEntrySchema, logPageSchema, logSettingsSchema, logSettingsPatchSchema, logSummarySchema } from "@mmapp/contracts"
|
|
import { requestBlob, requestJson } from "./http-client"
|
|
|
|
const timedSignal = (signal?: AbortSignal, ms = 30000) => AbortSignal.any([...(signal ? [signal] : []), AbortSignal.timeout(ms)])
|
|
function confirmed<T>(schema: z.ZodType<T>, raw: unknown): T {
|
|
const parsed = schema.safeParse(raw)
|
|
if (!parsed.success) throw new Error("Ответ сервера журнала не подтверждён: некорректные данные")
|
|
return parsed.data
|
|
}
|
|
|
|
export async function getLogs(base: string, params: URLSearchParams, signal?: AbortSignal) {
|
|
const result = confirmed(logPageSchema, await requestJson(base, "/api/logs?" + params, { signal: timedSignal(signal) }))
|
|
const server = params.get("serverId")
|
|
if (server && result.entries.some(row => String(row.serverId) !== server)) throw new Error("Журнал относится к другому устройству")
|
|
return result
|
|
}
|
|
export async function getLogSummary(base: string, params: URLSearchParams, signal?: AbortSignal) {
|
|
return confirmed(logSummarySchema, await requestJson(base, "/api/logs/summary?" + params, { signal: timedSignal(signal) }))
|
|
}
|
|
export async function getLogContext(base: string, id: string, signal?: AbortSignal) {
|
|
return confirmed(z.object({ entry: logEntrySchema, before: z.array(logEntrySchema), after: z.array(logEntrySchema) }), await requestJson(base, `/api/logs/${encodeURIComponent(id)}/context`, { signal: timedSignal(signal) }))
|
|
}
|
|
export async function getLogSettings(base: string, signal?: AbortSignal) { return confirmed(logSettingsSchema, await requestJson(base, "/api/logs/settings", { signal: timedSignal(signal) })) }
|
|
export async function putLogSettings(base: string, patch: z.infer<typeof logSettingsPatchSchema>, signal?: AbortSignal) {
|
|
const input = logSettingsPatchSchema.parse(patch)
|
|
const result = confirmed(z.object({ ok: z.literal(true), settings: logSettingsSchema }), await requestJson(base, "/api/logs/settings", { method: "PUT", body: JSON.stringify(input), signal: timedSignal(signal) }))
|
|
if (Object.entries(input).some(([key, value]) => result.settings[key as keyof typeof result.settings] !== value)) throw new Error("Сервер подтвердил другие настройки; обновите данные")
|
|
return result.settings
|
|
}
|
|
export async function exportLogs(base: string, params: URLSearchParams, format: "csv" | "json", signal?: AbortSignal) {
|
|
const query = new URLSearchParams(params); query.set("format", format)
|
|
const res = await requestBlob(base, "/api/logs/export?" + query, { signal: timedSignal(signal, 60000) })
|
|
const blob = await res.blob(), url = URL.createObjectURL(blob), anchor = document.createElement("a")
|
|
anchor.href = url; anchor.download = `router-logs.${format}`; anchor.click(); setTimeout(() => URL.revokeObjectURL(url), 1000)
|
|
}
|