81 lines
3.5 KiB
TypeScript
81 lines
3.5 KiB
TypeScript
import { API_ROOT } from "@/lib/config"
|
|
import type {
|
|
AuthState,
|
|
Account, CreateAccountInput, Template, CreateTemplateInput,
|
|
Domain, CreateDomainInput, ChangesetResponse, ApplyRequest,
|
|
} from "./types"
|
|
|
|
export class UnauthorizedError extends Error {
|
|
constructor() {
|
|
super("Unauthorized")
|
|
this.name = "UnauthorizedError"
|
|
}
|
|
}
|
|
|
|
async function req<T>(path: string, init?: RequestInit): Promise<T> {
|
|
const res = await fetch(path, {
|
|
headers: { "Content-Type": "application/json" },
|
|
method: "GET",
|
|
credentials: "include",
|
|
...init,
|
|
})
|
|
if (res.status === 401) throw new UnauthorizedError()
|
|
if (!res.ok) {
|
|
let msg = `HTTP ${res.status}`
|
|
try { const b = await res.json(); if (b?.error) msg = String(b.error) } catch { /* ignore */ }
|
|
throw new Error(msg)
|
|
}
|
|
if (res.status === 204) return undefined as T
|
|
return (await res.json()) as T
|
|
}
|
|
|
|
function projectPath(projectId: string, path: string): string {
|
|
return `${API_ROOT}/projects/${projectId}${path}`
|
|
}
|
|
|
|
export const api = {
|
|
auth: {
|
|
register: (email: string, password: string) =>
|
|
req<AuthState>(`${API_ROOT}/auth/register`, {
|
|
method: "POST",
|
|
body: JSON.stringify({ email, password }),
|
|
}),
|
|
login: (email: string, password: string) =>
|
|
req<AuthState>(`${API_ROOT}/auth/login`, {
|
|
method: "POST",
|
|
body: JSON.stringify({ email, password }),
|
|
}),
|
|
logout: () => req<void>(`${API_ROOT}/auth/logout`, { method: "POST" }),
|
|
me: () => req<AuthState>(`${API_ROOT}/auth/me`),
|
|
},
|
|
|
|
listAccounts: (projectId: string) => req<Account[]>(projectPath(projectId, "/accounts")),
|
|
createAccount: (projectId: string, input: CreateAccountInput) =>
|
|
req<Account>(projectPath(projectId, "/accounts"), { method: "POST", body: JSON.stringify(input) }),
|
|
deleteAccount: (projectId: string, id: string) =>
|
|
req<void>(projectPath(projectId, `/accounts/${id}`), { method: "DELETE" }),
|
|
|
|
listTemplates: (projectId: string) => req<Template[]>(projectPath(projectId, "/templates")),
|
|
createTemplate: (projectId: string, input: CreateTemplateInput) =>
|
|
req<Template>(projectPath(projectId, "/templates"), { method: "POST", body: JSON.stringify(input) }),
|
|
updateTemplate: (projectId: string, id: string, input: CreateTemplateInput) =>
|
|
req<Template>(projectPath(projectId, `/templates/${id}`), { method: "PUT", body: JSON.stringify(input) }),
|
|
deleteTemplate: (projectId: string, id: string) =>
|
|
req<void>(projectPath(projectId, `/templates/${id}`), { method: "DELETE" }),
|
|
|
|
listDomains: (projectId: string) => req<Domain[]>(projectPath(projectId, "/domains")),
|
|
createDomain: (projectId: string, input: CreateDomainInput) =>
|
|
req<Domain>(projectPath(projectId, "/domains"), { method: "POST", body: JSON.stringify(input) }),
|
|
deleteDomain: (projectId: string, id: string) =>
|
|
req<void>(projectPath(projectId, `/domains/${id}`), { method: "DELETE" }),
|
|
importZones: (projectId: string, accountId: string) =>
|
|
req<Domain[]>(projectPath(projectId, `/accounts/${accountId}/import`), { method: "POST" }),
|
|
setDomainTemplate: (projectId: string, id: string, templateId: string | null) =>
|
|
req<Domain>(projectPath(projectId, `/domains/${id}`), { method: "PATCH", body: JSON.stringify({ templateId }) }),
|
|
|
|
checkDomain: (projectId: string, id: string) =>
|
|
req<ChangesetResponse>(projectPath(projectId, `/domains/${id}/check`)),
|
|
applyDomain: (projectId: string, id: string, body: ApplyRequest) =>
|
|
req<ChangesetResponse>(projectPath(projectId, `/domains/${id}/apply`), { method: "POST", body: JSON.stringify(body) }),
|
|
}
|