import Axios, { type AxiosError, type AxiosRequestConfig, type AxiosResponse, } from 'axios' import { type AxiosCacheInstance, setupCache } from 'axios-cache-interceptor' import type { Interceptors, Locale, StorageClient } from './types' export type LCConfig = { apiUrl: string interceptors?: Interceptors locale?: Locale storageClient?: StorageClient source?: 'app' | 'stay' | 'website' getDeviceUniqueId?: () => Promise } const communHeaders = { 'access-token': '', client: '', uid: '', } const setAxios = ({ apiUrl, getDeviceUniqueId, interceptors, locale, source, storageClient, }: LCConfig) => { const BASE_URL = `${apiUrl}/${locale}/api/` const apiConfig = setupCache( Axios.create({ baseURL: `${BASE_URL}`, headers: { ...communHeaders }, }), ) const setStorageOnResponse = async (response: AxiosResponse) => { if (response && response.headers && response.headers['access-token']) { const headers = { accessToken: response.headers['access-token'], client: response.headers.client, uid: response.headers.uid, httpSource: source, } storageClient?.setItem('headers', JSON.stringify(headers)) } } const onResponse = (api: AxiosCacheInstance): void => { api.interceptors.response.use( function (response) { setStorageOnResponse(response) if (Array.isArray(interceptors?.response)) { interceptors?.response.forEach((fn) => fn(response)) } if ( (response.data as { data: unknown; success: boolean })?.data || (response.data as { success: boolean })?.success ) { return { ...(response.data as { data: unknown; success: boolean }), headers: response.headers, included: (response.data as { included: unknown })?.included, } as never } return { data: response.data, headers: response.headers, included: (response.data as { included: unknown })?.included, } as never }, (error: AxiosError) => { if (error.response) { setStorageOnResponse(error.response) } return Promise.reject(error) }, ) } const setHeadersFromStorage = (api: AxiosCacheInstance): void => { api.interceptors.request.use( async function (config) { const headers = await storageClient?.getItem('headers') if (headers) { config.headers['access-token'] = JSON.parse(headers).accessToken config.headers.client = JSON.parse(headers).client config.headers.uid = JSON.parse(headers).uid config.headers.httpSource = JSON.parse(headers).httpSource } if (getDeviceUniqueId) config.headers.deviceIdentifier = await getDeviceUniqueId() return config }, (error: AxiosError) => { return Promise.reject(error) }, ) } setHeadersFromStorage(apiConfig) onResponse(apiConfig) return apiConfig } const setStrapiAdminAxios = ({ apiUrl }: { apiUrl: string }) => { const BASE_URL = `${apiUrl}/api/` return Axios.create({ baseURL: `${BASE_URL}`, headers: communHeaders, }) as AxiosCacheInstance } const setBaseAxios = ({ apiUrl }: { apiUrl: string }) => { const BASE_URL = `${apiUrl}/` return setupCache( Axios.create({ baseURL: BASE_URL, headers: { 'Content-Type': 'application/json', }, }), ) } export default { lc: (config: LCConfig) => setAxios(config), mindee: (config: { apiUrl: string }) => setBaseAxios(config), ipLocation: (config: { apiUrl: string }) => setBaseAxios(config), sharegroop: (config: { apiUrl: string }) => setBaseAxios(config), strapiAdmin: (config: { apiUrl: string }) => setStrapiAdminAxios(config), hubspot: (config: { apiUrl: string }) => setBaseAxios(config), mapbox: (config: { apiUrl: string }) => setBaseAxios(config), }