import { ACCESS_TOKEN_KEY , RESPONSE_CONTENT_TYPE , INVALID_TOKEN_ERROR } from "./constants" ; import sleep from "./sleep" ; import { getStorage as localStorage } from "../shared/storage" ; import axios , { AxiosRequestConfig , AxiosResponse , AxiosError } from "axios" ; export type Method = "GET" | "POST" | "PUT" ; const TEST_FOR_LOADING = false ; let hostUrl ; export const setHostUrl = ( host ) : void => { hostUrl = host ; } ; export const getHostUrl = ( ) : string => { return hostUrl ; } ; const _fetch = async ( url , body , method , withToken ? , onProgress ? ) : Promise < any > => { if ( TEST_FOR_LOADING ) { await sleep ( 2000 ) ; } let completeUrl = url ; if ( url && ! url . startsWith ( getHostUrl ( ) ) ) { completeUrl = `${ getHostUrl ( ) }${ url }` ; } const headers = { Accept : "*/*" , } ; if ( withToken ) { const token = await localStorage ( ) . getItem ( ACCESS_TOKEN_KEY ) ; if ( token ) { headers [ "Authorization" ] = "Bearer " + token ; } else { return Promise . reject ( INVALID_TOKEN_ERROR ) ; } } const options = { url : completeUrl , method : method , headers : headers , withCredentials : true } ; if ( method === "POST" ) { headers [ "Content-Type" ] = "application/json" ; options . data = body ; } else if ( method === "PUT" ) { headers [ "Content-Type" ] = ( body as File ) . type ; options . data = body ; options . onUploadProgress = onProgress ; } return axios ( options ) . then ( ( response ) : Promise < any > => { let contentType = response . headers [ "Content-Type" ] || response . headers [ "content-type" ] ; if ( response . status >= 200 && response . status < 300 ) { contentType = contentType && contentType . toLowerCase ( ) ; if ( contentType && contentType . startsWith ( RESPONSE_CONTENT_TYPE . HTML ) && response . request . responseURL ) { let targetTo = response . request . responseURL ; if ( targetTo . startsWith ( getHostUrl ( ) ) ) { targetTo = targetTo . substring ( getHostUrl ( ) . length ) ; } return Promise . resolve ( { redirected : false , to : targetTo } ) ; } else { return Promise . resolve ( response . data ) ; } } else { return Promise . reject ( { isAxiosError : true , config : response . config , response : response } as AxiosError ) ; } } ) . catch ( ( error ) : Promise < any > => { const response = error . response ; if ( ! response ) { return Promise . reject ( { name : "Unknown error!" } ) ; } let contentType = response . headers [ "Content-Type" ] || response . headers [ "content-type" ] ; contentType = contentType && contentType . toLowerCase ( ) ; if ( contentType && contentType . toLowerCase ( ) . startsWith ( RESPONSE_CONTENT_TYPE . HTML ) ) { return Promise . reject ( ( { name : `${ response . status } ${ response . statusText }` , message : "" , stack : response . data } as Error ) ) ; } else { return Promise . reject ( ( { name : `${ response . status } ${ response . statusText }` , message : response . data . message } as Error ) ) ; } } ) ; } ; export default _fetch ;