140 lines
4.5 KiB
TypeScript
140 lines
4.5 KiB
TypeScript
import axios from 'axios';
|
|
import {Dispatch} from '@reduxjs/toolkit';
|
|
import {setAuthData} from '../../reducer/commonSlice';
|
|
import {toast} from '../../../RN-UI-LIB/src/components/toast';
|
|
import {navigateToScreen} from './navigationUtlis';
|
|
import {GLOBAL} from '../../constants/Global';
|
|
|
|
const MOCK_DIR = '__mocks__';
|
|
|
|
// set this to `true` to use mock data for local development
|
|
// to connect with real apis this should be set to `false`
|
|
const USE_MOCK = false;
|
|
|
|
export enum ApiKeys {
|
|
GENERATE_OTP,
|
|
VERIFY_OTP,
|
|
}
|
|
|
|
const API_URLS: Record<ApiKeys, string> = {} as Record<ApiKeys, string>;
|
|
API_URLS[ApiKeys.GENERATE_OTP] = '/auth/otp/generate';
|
|
API_URLS[ApiKeys.VERIFY_OTP] = '/auth/otp/verify';
|
|
|
|
const MOCK_API_URLS: Record<ApiKeys, string> = {} as Record<ApiKeys, string>;
|
|
|
|
let dispatch: Dispatch<any>;
|
|
|
|
const getErrorMessage = (err: any) => {
|
|
if (err?.response?.data?.title) {
|
|
return err?.response?.data?.title;
|
|
}
|
|
const errorContent = err?.response?.data?.message
|
|
? JSON.parse(err?.response?.data?.message)
|
|
: '';
|
|
return errorContent?.detail || errorContent?.message || errorContent || err;
|
|
};
|
|
|
|
export function getApiUrl(
|
|
apiKey: ApiKeys,
|
|
params?: Record<string, string | number>,
|
|
queryParams?: Record<string, string | number>,
|
|
) {
|
|
if (USE_MOCK) {
|
|
return `${MOCK_DIR}/${MOCK_API_URLS[apiKey]}`;
|
|
}
|
|
|
|
let apiUrl = API_URLS[apiKey];
|
|
|
|
// replace all {placeholders} with their values in params
|
|
if (params) {
|
|
Object.keys(params).forEach(paramKey => {
|
|
apiUrl = apiUrl.split(`{${paramKey}}`).join(`${params[paramKey]}`);
|
|
// apiUrl = apiUrl.replaceAll(`{${paramKey}}`, `${params[paramKey]}`);
|
|
});
|
|
}
|
|
|
|
if (queryParams) {
|
|
apiUrl +=
|
|
'?' +
|
|
Object.keys(queryParams)
|
|
.map(key => `${key}=${queryParams[key]}`)
|
|
.join('&');
|
|
}
|
|
|
|
return `${apiUrl}`;
|
|
}
|
|
// status code to be retried on
|
|
const errorsToRetry = [500, 503];
|
|
|
|
const axiosInstance = axios.create();
|
|
|
|
axiosInstance.interceptors.request.use(request => {
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
// request['retry'] = request['retry'] && request['retry'] < 4 ? request['retry'] : 3;
|
|
request.retry = request?.retry < 4 ? request.retry : 3;
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
request.headers['request-start-time'] = new Date().getTime();
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
request.headers['sessionToken'] = GLOBAL.SESSION_TOKEN || '';
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
request.headers['deviceId'] = GLOBAL.DEVICE_ID || '';
|
|
return request;
|
|
});
|
|
|
|
axiosInstance.interceptors.response.use(
|
|
response => {
|
|
if (response.config.headers) {
|
|
const start = response.config.headers['request-start-time'];
|
|
const end = new Date().getTime();
|
|
const milliseconds = end - Number(start);
|
|
response.headers['request-duration'] = String(milliseconds);
|
|
}
|
|
return response;
|
|
},
|
|
error => {
|
|
const {config, response} = error;
|
|
if (
|
|
!config ||
|
|
config.retry <= 1 ||
|
|
!errorsToRetry.includes(error.response.status)
|
|
) {
|
|
const errorString = getErrorMessage(error);
|
|
if (!config.headers.donotHandleError) {
|
|
toast({type: 'error', text1: errorString});
|
|
}
|
|
|
|
if (response.status === 401) {
|
|
dispatch &&
|
|
dispatch(
|
|
setAuthData({sessionToken: '', isLoggedIn: false}),
|
|
);
|
|
navigateToScreen('Login');
|
|
}
|
|
|
|
return Promise.reject(error);
|
|
}
|
|
config.retry -= 1;
|
|
const delayRetryRequest = new Promise<void>(resolve => {
|
|
setTimeout(() => {
|
|
resolve();
|
|
}, 0);
|
|
});
|
|
return delayRetryRequest.then(() => axiosInstance(config));
|
|
},
|
|
);
|
|
|
|
axiosInstance.defaults.headers.common['Content-Type'] = 'application/json';
|
|
axiosInstance.defaults.baseURL = `https://dev-longhorn-server.np.navi-tech.in/av/`;
|
|
|
|
// TODO:: Ideally should happen through middlewares.
|
|
// export const registerNavigateAndDispatch = (
|
|
// navigateParam: NavigateFunction,
|
|
// dispatchParam: Dispatch<any>
|
|
// ) => ((navigate = navigateParam), (dispatch = dispatchParam));
|
|
|
|
export default axiosInstance;
|