Files
dns-autoresolver/web/src/api/client.ts
T

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) }),
}