import {API, APIParams, APIPath, APIResponse} from 'common/api/schema' import {APIError, getApiUrl} from 'common/api/utils' import {removeUndefinedProps} from 'common/util/object' import {User} from 'firebase/auth' import {forEach} from 'lodash' export function unauthedApi

(path: P, params: APIParams

) { return typedAPICall(path, params, null) } export const typedAPICall =

( path: P, params: APIParams

, user: User | null, ) => { // parse any params that should part of the path (like market/:id) const newParams: any = {} let url = getApiUrl(path) forEach(params, (v, k) => { if (url.includes(`:${k}`)) { url = url.replace(`:${k}`, v + '') } else { newParams[k] = v } }) return baseApiCall({ url, method: API[path].method, params: newParams, user, }) as Promise> } function appendQuery(url: string, props: Record) { const [base, query] = url.split(/\?(.+)/) const params = new URLSearchParams(query) forEach(removeUndefinedProps(props ?? {}), (v, k) => { if (Array.isArray(v)) { v.forEach((item) => params.append(k, item)) } else { params.set(k, v) } }) return `${base}?${params.toString()}` } export async function baseApiCall(props: { url: string method: 'POST' | 'PUT' | 'GET' params: any user: User | null }) { const {url, method, params, user} = props const actualUrl = method === 'POST' ? url : appendQuery(url, params) const headers: HeadersInit = { 'Content-Type': 'application/json', } if (user) { const token = await user.getIdToken() headers.Authorization = `Bearer ${token}` } const req = new Request(actualUrl, { headers, method: method, body: params == null || method === 'GET' ? undefined : JSON.stringify(params), }) // console.log('Request', req) return fetch(req).then(async (resp) => { const json = (await resp.json()) as {[k: string]: any} if (!resp.ok) { throw new APIError(resp.status as any, json?.message, json?.details) } return json }) }