import { type ResponseMap, ofetch } from 'ofetch' import type { HttpType } from './client' import type { ResponseType } from './omySetup' import { setOmyFetch } from './omySetup' import { formatResponseApi } from './serializer' import type { Locale } from './types' export const omyHttp = ({ api, locale, storageClient, headersCustom, localeCustom, }: HttpType) => { const generateApiUrl = (locale?: Locale) => `${api.url}/${locale}/api/` const setup = setOmyFetch({ apiUrl: api.url, getDeviceUniqueId: api.getDeviceUniqueId, interceptors: api.interceptors, locale, source: api.source, storageClient, }) return { get: async ( endpoint: string, options?: Record, ): Promise => { try { const customLocale = localeCustom?.getLocale() const url = customLocale ? generateApiUrl(customLocale) : generateApiUrl(locale) const headers = headersCustom?.getHeaders() ? headersCustom.getHeaders() : await setup.getHeaders() const response = await ofetch(`${url}${endpoint}`, { method: 'GET', onResponse: ({ response }) => { return setup.triggerOnResponse( response as unknown as ResponseType, ) as unknown as Promise }, ...(options ?? {}), headers: { ...headers, ...(options?.headers ?? {}) } as HeadersInit, }) if (options?.responseType) { return Promise.resolve(response) as Promise } return Promise.resolve( formatResponseApi(response), ) as unknown as Promise } catch (error: unknown) { return Promise.resolve({ errors: error as Error, }) as unknown as Promise } }, post: async ( endpoint: string, params: Record | BodyInit, options?: Record, ): Promise => { try { const customLocale = localeCustom?.getLocale() const url = customLocale ? generateApiUrl(customLocale) : generateApiUrl(locale) const headers = headersCustom?.getHeaders() ? headersCustom.getHeaders() : await setup.getHeaders() const response = await ofetch(`${url}${endpoint}`, { method: 'POST', body: params, onResponse: ({ response }) => { return setup.triggerOnResponse( response as unknown as ResponseType, ) as unknown as Promise }, ...(options ?? {}), headers: { ...headers, ...(options?.headers ?? {}) } as HeadersInit, }) return Promise.resolve(formatResponseApi(response)) as Promise } catch (error: unknown) { return Promise.resolve({ errors: error as Error, }) as unknown as Promise } }, put: async ( endpoint: string, params: Record | BodyInit, options?: Record, ): Promise => { try { const customLocale = localeCustom?.getLocale() const url = customLocale ? generateApiUrl(customLocale) : generateApiUrl(locale) const headers = headersCustom?.getHeaders() ? headersCustom.getHeaders() : await setup.getHeaders() const response = await ofetch(`${url}${endpoint}`, { method: 'PUT', body: params, onResponse: ({ response }) => { return setup.triggerOnResponse( response as unknown as ResponseType, ) as unknown as Promise }, ...(options ?? {}), headers: { ...headers, ...(options?.headers ?? {}) } as HeadersInit, }) return Promise.resolve(formatResponseApi(response)) as Promise } catch (error: unknown) { return Promise.resolve({ errors: error as Error, }) as unknown as Promise } }, delete: async (endpoint: string): Promise => { try { const customLocale = localeCustom?.getLocale() const url = customLocale ? generateApiUrl(customLocale) : generateApiUrl(locale) const headers = headersCustom?.getHeaders() ? headersCustom.getHeaders() : await setup.getHeaders() const response = await ofetch(`${url}${endpoint}`, { method: 'DELETE', headers: headers as HeadersInit, onResponse: ({ response }) => { return setup.triggerOnResponse( response as unknown as ResponseType, ) as unknown as Promise }, }) return Promise.resolve(formatResponseApi(response)) as Promise } catch (error) { return Promise.resolve({ errors: error as Error, }) as unknown as Promise } }, raw: async < Response extends Blob | ArrayBuffer | ReadableStream, >( endpoint: string, options: Record & { responseType: keyof ResponseMap }, ) => { const customLocale = localeCustom?.getLocale() ?? locale const url = generateApiUrl(customLocale) const headers = headersCustom?.getHeaders() ? headersCustom.getHeaders() : await setup.getHeaders() const response = await ofetch.raw< Response, NonNullable<(typeof options)['responseType']> >(`${url}${endpoint}`, { method: 'GET', onResponse: ({ response }) => { return setup.triggerOnResponse( response as unknown as ResponseType, ) as unknown as Promise }, ...options, headers: { ...headers, ...(options.headers ?? {}) } as HeadersInit, }) return { headers: response.headers, _data: response._data as Response } }, } }