import merge from "deepmerge" import fetchRetry from "fetch-retry" import { env } from "@/env/server" import type { RequestOptionsWithJSONBody, RequestOptionsWithOutBody, } from "@/types/fetch" import type { Endpoint } from "./endpoints" export { endpoints } from "./endpoints" const defaultOptions: RequestInit = { cache: "no-store", headers: { "Content-Type": "application/json", }, mode: "cors", } const fetch = fetchRetry(global.fetch, { retries: 3, retryDelay: function (attempt, error, response) { return Math.pow(2, attempt) * 150 // 150, 300, 600 }, }) export async function get( endpoint: Endpoint, options: RequestOptionsWithOutBody, params?: URLSearchParams ) { const url = new URL( `${env.API_BASEURL}/${endpoint}${params ? `?${params.toString()}` : ""}` ) return fetch(url, merge.all([defaultOptions, { method: "GET" }, options])) } export async function patch( endpoint: Endpoint, options: RequestOptionsWithJSONBody ) { const { body, ...requestOptions } = options return fetch( `${env.API_BASEURL}/${endpoint}`, merge.all([ defaultOptions, { body: JSON.stringify(body), method: "PATCH" }, requestOptions, ]) ) } export async function post( endpoint: Endpoint, options: RequestOptionsWithJSONBody ) { const { body, ...requestOptions } = options return fetch( `${env.API_BASEURL}/${endpoint}`, merge.all([ defaultOptions, { body: JSON.stringify(body), method: "POST" }, requestOptions, ]) ) } export async function remove( endpoint: Endpoint, options: RequestOptionsWithOutBody ) { return fetch( `${env.API_BASEURL}/${endpoint}`, merge.all([defaultOptions, { method: "DELETE" }, options]) ) }