/** * Datart * * Copyright 2021 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { BASE_API_URL } from 'globalConstants'; import { APIResponse } from 'types'; import { getToken, removeToken, setToken } from './auth'; export const instance = axios.create({ baseURL: BASE_API_URL, validateStatus(status) { return status < 400; }, }); instance.interceptors.request.use(config => { const token = getToken(); if (token) { config.headers.Authorization = token; } return config; }); instance.interceptors.response.use(response => { // refresh access token const token = response.headers.authorization; if (token) { setToken(token); } return response; }); /** * @deprecated should be use @see {@link request2} in all places * @export * @template T * @param {(string | AxiosRequestConfig)} url * @param {AxiosRequestConfig} [config] * @return {*} {Promise<APIResponse<T>>} */ export function request<T>( url: string | AxiosRequestConfig, config?: AxiosRequestConfig, ): Promise<APIResponse<T>> { const axiosPromise = typeof url === 'string' ? instance(url, config) : instance(url); return axiosPromise.then(response => response.data as APIResponse<T>); } /** * New Http Request Util * Feature: * 1. Support customize onFulfilled and onRejected handler * 2. Support default backend service response error handler * 3. Support redux rejected action handler @see rejectedActionMessageHandler * @template T * @param {(string | AxiosRequestConfig)} url * @param {AxiosRequestConfig} [config] * @param {{ * onFulfilled?: (value: AxiosResponse<any>) => APIResponse<T>; * onRejected?: (error) => any; * }} [extra] * @return {*} {Promise<APIResponse<T>>} */ export function request2<T>( url: string | AxiosRequestConfig, config?: AxiosRequestConfig, extra?: { onFulfilled?: (value: AxiosResponse<any>) => APIResponse<T>; onRejected?: (error) => any; }, ): Promise<APIResponse<T>> { const defaultFulfilled = response => response.data as APIResponse<T>; const defaultRejected = error => { throw standardErrorMessageTransformer(error); }; const axiosPromise = typeof url === 'string' ? instance(url, config) : instance(url); return axiosPromise .then(extra?.onFulfilled || defaultFulfilled, error => { throw unAuthorizationErrorHandler(error); }) .catch(extra?.onRejected || defaultRejected); } export function requestWithHeader( url: string | AxiosRequestConfig, config?: AxiosRequestConfig, ) { return request2(url, config, { onFulfilled: response => { return [response.data, response.headers] as any; }, }) as any; } export const getServerDomain = () => { return `${window.location.protocol}//${window.location.host}`; }; function unAuthorizationErrorHandler(error) { if (error?.response?.status === 401) { removeToken(); } return error; } function standardErrorMessageTransformer(error) { if (error?.response?.data?.message) { return new Error(error?.response?.data?.message); } return error; }