143 lines
5.2 KiB
TypeScript
143 lines
5.2 KiB
TypeScript
import type {
|
|
AlertRule,
|
|
AlertRuleUpdate,
|
|
Asset,
|
|
CheckResult,
|
|
Incident,
|
|
Monitor,
|
|
MonitorUpdate,
|
|
NotificationChannel,
|
|
NotificationChannelCreate,
|
|
NotificationChannelUpdate,
|
|
PingMonitorCreate,
|
|
SnmpCredentialProfile,
|
|
SnmpCredentialProfileCreate,
|
|
SnmpCredentialProfileUpdate,
|
|
TcpMonitorCreate,
|
|
User,
|
|
WebsiteMonitorCreate,
|
|
} from "../types/api";
|
|
|
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8000";
|
|
|
|
export interface LoginResponse {
|
|
access_token: string;
|
|
token_type: string;
|
|
}
|
|
|
|
async function request<T>(path: string, token?: string, init: RequestInit = {}): Promise<T> {
|
|
const headers = new Headers(init.headers);
|
|
if (token) {
|
|
headers.set("Authorization", `Bearer ${token}`);
|
|
}
|
|
if (init.body && !headers.has("Content-Type")) {
|
|
headers.set("Content-Type", "application/json");
|
|
}
|
|
|
|
const response = await fetch(`${API_BASE_URL}${path}`, { ...init, headers });
|
|
if (!response.ok) {
|
|
const message = await response.text();
|
|
throw new Error(message || `Request failed with ${response.status}`);
|
|
}
|
|
if (response.status === 204) {
|
|
return undefined as T;
|
|
}
|
|
return (await response.json()) as T;
|
|
}
|
|
|
|
export async function login(email: string, password: string): Promise<LoginResponse> {
|
|
const body = new URLSearchParams();
|
|
body.set("username", email);
|
|
body.set("password", password);
|
|
|
|
const response = await fetch(`${API_BASE_URL}/auth/login`, {
|
|
method: "POST",
|
|
body,
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error("Invalid email or password");
|
|
}
|
|
return (await response.json()) as LoginResponse;
|
|
}
|
|
|
|
export const api = {
|
|
me: (token: string) => request<User>("/auth/me", token),
|
|
assets: (token: string) => request<Asset[]>("/assets", token),
|
|
monitors: (token: string) => request<Monitor[]>("/monitors", token),
|
|
createWebsiteMonitor: (token: string, payload: WebsiteMonitorCreate) =>
|
|
request<Monitor>("/monitors/website", token, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
createPingMonitor: (token: string, payload: PingMonitorCreate) =>
|
|
request<Monitor>("/monitors/ping", token, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
createTcpMonitor: (token: string, payload: TcpMonitorCreate) =>
|
|
request<Monitor>("/monitors/tcp", token, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
updateMonitor: (token: string, monitorId: number, payload: MonitorUpdate) =>
|
|
request<Monitor>(`/monitors/${monitorId}`, token, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
deleteMonitor: (token: string, monitorId: number) =>
|
|
request<void>(`/monitors/${monitorId}`, token, {
|
|
method: "DELETE",
|
|
}),
|
|
monitorResults: (token: string, monitorId: number, limit = 1) =>
|
|
request<CheckResult[]>(`/monitors/${monitorId}/results?limit=${limit}`, token),
|
|
alertRules: (token: string) => request<AlertRule[]>("/alerts/rules", token),
|
|
updateAlertRule: (token: string, ruleId: number, payload: AlertRuleUpdate) =>
|
|
request<AlertRule>(`/alerts/rules/${ruleId}`, token, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
incidents: (token: string) => request<Incident[]>("/incidents", token),
|
|
acknowledgeIncident: (token: string, incidentId: number) =>
|
|
request<Incident>(`/incidents/${incidentId}/acknowledge`, token, {
|
|
method: "POST",
|
|
}),
|
|
silenceIncident: (token: string, incidentId: number, minutes = 60) =>
|
|
request<Incident>(`/incidents/${incidentId}/silence?minutes=${minutes}`, token, {
|
|
method: "POST",
|
|
}),
|
|
notificationChannels: (token: string) => request<NotificationChannel[]>("/notifications/channels", token),
|
|
createNotificationChannel: (token: string, payload: NotificationChannelCreate) =>
|
|
request<NotificationChannel>("/notifications/channels", token, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
updateNotificationChannel: (token: string, channelId: number, payload: NotificationChannelUpdate) =>
|
|
request<NotificationChannel>(`/notifications/channels/${channelId}`, token, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
testNotificationChannel: (token: string, channelId: number) =>
|
|
request<{ status: string; message: string }>(`/notifications/channels/${channelId}/test`, token, {
|
|
method: "POST",
|
|
}),
|
|
deleteNotificationChannel: (token: string, channelId: number) =>
|
|
request<void>(`/notifications/channels/${channelId}`, token, {
|
|
method: "DELETE",
|
|
}),
|
|
snmpCredentialProfiles: (token: string) => request<SnmpCredentialProfile[]>("/credentials/snmp", token),
|
|
createSnmpCredentialProfile: (token: string, payload: SnmpCredentialProfileCreate) =>
|
|
request<SnmpCredentialProfile>("/credentials/snmp", token, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
updateSnmpCredentialProfile: (token: string, profileId: number, payload: SnmpCredentialProfileUpdate) =>
|
|
request<SnmpCredentialProfile>(`/credentials/snmp/${profileId}`, token, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
}),
|
|
deleteSnmpCredentialProfile: (token: string, profileId: number) =>
|
|
request<void>(`/credentials/snmp/${profileId}`, token, {
|
|
method: "DELETE",
|
|
}),
|
|
};
|