import {FrontendApiEndpoint, FrontendApiEndpoints} from "./fe-api"; import {GetNoteById} from "./types/endpoints/GetNoteById"; type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; export interface BackendApiEndpoint { method: M; endpoint: string; pathParams: [string], request?: T; response?: R; } function nestedUrlSearchParams(data: any, topLevel: boolean = true): string { switch (typeof data) { case "string": case "bigint": case "boolean": case "number": case "symbol": if (topLevel) return encodeURIComponent(data.toString()) + "="; return data.toString(); case "object": if (data === null) return "null"; if (Array.isArray(data)) return data.map(d => nestedUrlSearchParams(d, true)) .map(encodeURIComponent) .join("&"); const inner = Object.entries(data) .map(([k, v]) => [k, nestedUrlSearchParams(v, false)]); return new URLSearchParams(inner).toString(); default: return ""; } } type MagApiErrorCode = "Client:GenericApiError" | string; export interface MagApiError { status: number; code: MagApiErrorCode, message: string, } export class MagApiClient { private readonly baseUrl: string; constructor(baseUrl: string) { this.baseUrl = baseUrl; } async call>( endpoint: T["endpoint"], method: M, data: T["request"], pathParams: Record, token?: string | null | undefined ): Promise { type Response = T["response"]; const authorizationToken = token ?? undefined; const authorization = authorizationToken ? `Bearer ${authorizationToken}` : undefined; let url = `${this.baseUrl}/${endpoint}`; if (method === "GET") { const query = nestedUrlSearchParams(data as any); if (query) { url += `?${query}`; } } return await fetch(url, { method, body: method !== "GET" ? JSON.stringify(data) : undefined, credentials: "omit", cache: "no-cache", headers: authorization ? {authorization} : {}, }) .then(async (res) => { const body = res.status === 204 ? null : await res.json(); if (res.status === 200) { return body as Response; } else if (res.status === 204) { return null as any as Response; } else { throw body as MagApiError; } }) .catch((e) => { throw ({ status: -1, code: "Client:GenericApiError", message: e }) as MagApiError; }); } } const a = new MagApiClient("https://aaa"); a.call<"GET", GetNoteById>("", "",{}, {})