admin / Synapse-Cortex
publicSelf Hosted ITSM Tool with RBAC/Tenanting and MFA
Synapse-Cortex / Synapse-Cortexv2 / frontend / src / api / client.ts
1392 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import type { ApiErrorBody } from './types' export class ApiError extends Error { status: number body: ApiErrorBody constructor(status: number, body: ApiErrorBody) { super(formatDetail(body)) this.status = status this.body = body } } function formatDetail(body: ApiErrorBody): string { if (!body.detail) return 'Request failed.' if (typeof body.detail === 'string') return body.detail return body.detail.map((e) => e.msg).join(', ') } async function request<T>(method: string, path: string, payload?: unknown): Promise<T> { const res = await fetch(path, { method, credentials: 'include', headers: payload !== undefined ? { 'Content-Type': 'application/json' } : undefined, body: payload !== undefined ? JSON.stringify(payload) : undefined, }) if (res.status === 204) { return undefined as T } const isJson = res.headers.get('content-type')?.includes('application/json') const body = isJson ? await res.json() : undefined if (!res.ok) { throw new ApiError(res.status, body ?? {}) } return body as T } export const api = { get: <T>(path: string) => request<T>('GET', path), post: <T>(path: string, payload?: unknown) => request<T>('POST', path, payload ?? {}), patch: <T>(path: string, payload?: unknown) => request<T>('PATCH', path, payload ?? {}), delete: <T>(path: string) => request<T>('DELETE', path), } |