import axios, { AxiosError, AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, Method, } from 'axios'; let requestHandler: RequestHandler; export const getRequestHandler = (): RequestHandler => { return requestHandler; }; export const createRequestHandler = ( authorizedConfig?: ( config: AxiosRequestConfig, ) => Promise, unauthorizedConfig?: ( config: AxiosRequestConfig, ) => Promise, ): RequestHandler => { requestHandler = new RequestHandler(authorizedConfig, unauthorizedConfig); return requestHandler; }; const baseUrl = process.env.REACT_APP_API_URL || ''; export interface RequestHandlerParams { method: Method; url: string; hasAuthentication?: boolean; data?: unknown; headers?: AxiosRequestHeaders; } export class RequestHandler { public authorizedConfig: ( config: AxiosRequestConfig, ) => Promise; public unauthorizedConfig: ( config: AxiosRequestConfig, ) => Promise; constructor( authorizedConfig?: ( config: AxiosRequestConfig, ) => Promise, unauthorizedConfig?: ( config: AxiosRequestConfig, ) => Promise, ) { this.authorizedConfig = authorizedConfig; this.unauthorizedConfig = unauthorizedConfig; } public request = async ( params: RequestHandlerParams, ): Promise | AxiosError> => { try { let config: AxiosRequestConfig = { method: params.method, url: `${baseUrl}${params.url}`, data: params.data, headers: params.headers, }; if (params.hasAuthentication) { if (this.authorizedConfig) { config = await this.authorizedConfig(config); } return await axios(config); } if (this.unauthorizedConfig) { config = await this.unauthorizedConfig(config); } return await axios(config); } catch (error) { if (axios.isAxiosError(error)) { return error; } console.error('API Request Failed: ', error); throw error; } }; }