import type { AxiosRequestConfig, AxiosResponse, ResponseType } from 'axios' import type { HeadersCustom } from './headers' import type { LocaleCustom } from './locale' import { formatResponseApi } from './serializer' import setup from './setup' import type { Interceptors, Locale, StorageClient } from './types' export type AvailableServiceNames = | 'lc' | 'mindee' | 'ipLocation' | 'strapiAdmin' | 'sharegroop' | 'hubspot' | 'mapbox' export type HttpType = { api: { name: AvailableServiceNames url: string source?: 'app' | 'stay' | 'website' getDeviceUniqueId?: () => Promise interceptors?: Interceptors } locale?: Locale localeCustom?: LocaleCustom storageClient?: StorageClient headersCustom?: HeadersCustom unserialized?: boolean } export const http = ({ api, locale, storageClient, unserialized = false, }: HttpType) => { const config = { apiUrl: api.url, interceptors: api.interceptors, locale, storageClient, source: api.source, getDeviceUniqueId: api.getDeviceUniqueId, } return { get: async ( endpoint: string, options?: Record, ): Promise => { try { const response = await setup[api.name](config).get(endpoint, options) if (options?.responseType) { return Promise.resolve(response) as Promise } if (unserialized) { if (api.name === 'strapiAdmin') { return Promise.resolve(response.data) as Promise } else { return Promise.resolve(response) as Promise } } else { return Promise.resolve( formatResponseApi(response), ) 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 response = await setup[api.name](config).post( endpoint, params, options, ) return unserialized ? (Promise.resolve(response) as Promise) : (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 response = await setup[api.name](config).put( endpoint, params, options, ) return unserialized ? (Promise.resolve(response) as Promise) : (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 response = await setup[api.name](config).delete(endpoint) return unserialized ? (Promise.resolve(response) as Promise) : (Promise.resolve(formatResponseApi(response)) as Promise) } catch (error: unknown) { return Promise.resolve({ errors: error as Error, }) as unknown as Promise } }, raw: async >( endpoint: string, options: Record & { responseType: 'blob' | 'arrayBuffer' | 'stream' }, ) => { const response = await setup[api.name](config).request< T, AxiosResponse, AxiosResponse >({ url: endpoint, method: 'GET', ...options, responseType: options.responseType.toLowerCase() as ResponseType, }) return { headers: new Headers(Object.entries(response.headers)), _data: response.data, } }, } }