| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { API_V1, CREDENTIALS } from "../apiContract"; |
| import { EMPTY_INBOX, parseAlerts, parseInbox } from "./alertsModel"; |
| import type { Alert, Inbox } from "./alertsModel"; |
|
|
| export type Result<T> = |
| | { ok: true; value: T } |
| | { ok: false; status: number; message: string }; |
|
|
| |
| |
| export function errorMessage(status: number, message?: string): string { |
| if (status >= 500 || !message) { |
| return status >= 500 |
| ? "Something went wrong on our side. Try again in a moment." |
| : `The server answered ${status}.`; |
| } |
| return message; |
| } |
|
|
| async function call<T>( |
| path: string, |
| init: RequestInit, |
| read: (body: unknown) => T |
| ): Promise<Result<T>> { |
| let res: Response; |
| try { |
| res = await fetch(`${API_V1}${path}`, { credentials: CREDENTIALS, ...init }); |
| } catch { |
| return { ok: false, status: 0, message: "Cannot reach the server." }; |
| } |
| const body = (await res.json().catch(() => null)) as unknown; |
| if (!res.ok) { |
| const detail = (body as { error?: { message?: string } } | null)?.error?.message; |
| return { ok: false, status: res.status, message: errorMessage(res.status, detail) }; |
| } |
| return { ok: true, value: read(body) }; |
| } |
|
|
| const json = (data: unknown): RequestInit => ({ |
| method: "POST", |
| headers: { "Content-Type": "application/json" }, |
| body: JSON.stringify(data), |
| }); |
|
|
| export function fetchInbox(): Promise<Result<Inbox>> { |
| return call("/notifications", {}, parseInbox); |
| } |
|
|
| |
| export function markRead(ids: string[] | null, read = true): Promise<Result<true>> { |
| return call("/notifications/read", json({ ids, read }), () => true as const); |
| } |
|
|
| export function fetchAlerts(): Promise<Result<Alert[]>> { |
| return call("/alerts", {}, parseAlerts); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export function createAlert( |
| viewId: string, |
| topic: string, |
| label?: string |
| ): Promise<Result<unknown>> { |
| return call("/alerts", json({ viewId, topic, ...(label ? { label } : {}) }), (b) => b); |
| } |
|
|
| export function deleteAlert(id: string): Promise<Result<true>> { |
| return call(`/alerts/${encodeURIComponent(id)}`, { method: "DELETE" }, () => true as const); |
| } |
|
|
| |
| export function runAlert(id: string): Promise<Result<unknown>> { |
| return call(`/alerts/${encodeURIComponent(id)}/run`, { method: "POST" }, (b) => b); |
| } |
|
|
| export { EMPTY_INBOX }; |
|
|