import type { Clerk } from "@clerk/clerk-js"; import type { ApiResponseBase, UserConfig } from "../types"; import { fetch, type RequestInit } from "undici"; import { apiResponseBaseSchema } from "../schema"; import { ResocketError } from "../errors/RescoketError"; import { API_BASE } from "../constants"; interface UserConfigWithClerk { config: UserConfig; clerk: Clerk; } interface FetchApi { user: UserConfigWithClerk; options: RequestInit; } //api base const API = API_BASE + "/api"; export const apiFetch = async ( route: string, { user, options }: FetchApi ): Promise => { const clerkAuthToken = await user.clerk.session?.getToken(); if (!clerkAuthToken) throw new Error(`session expired! please login again`); const res = await fetch(`${API}${route}`, { headers: { "Content-Type": "application/json", Authorization: "Bearer " + clerkAuthToken, ...options.headers, }, ...options, }); //Note: our apis are designed to give explicit errors. so it should only be notokay incase of internal server errors if (res.ok) { const json = (await res.json()) as ApiResponseBase; const baseRes = apiResponseBaseSchema.parse(json); if ("error" in baseRes) throw new ResocketError(baseRes.error!); return baseRes.data as unknown as T; } else { throw new Error(`Something went wrong, Internal server error`); } };