import { getAccessToken , getAuthHeaders , logout } from '../auth/auth' ; import { AuthError , ForbiddenError , NotFoundError } from './customError' ; interface FetchOptions extends RequestInit { searchParams ? : UrlParams ; } export type UrlParams = URLSearchParams | { [ key ] : string ; } ; export const fetchWithoutToken = < T = any > ( uri , init ? ) : Promise < T > => fetch ( uri , init ) . then ( ( response ) => response . json ( ) ) ; const handleErrors = ( response , reloadOnUnauthorized = false ) => { if ( response . status >= 400 && response . status <= 401 && reloadOnUnauthorized ) { logout ( ) ; } if ( response . status === 401 ) { throw new AuthError ( response . status , '' ) ; } if ( response . status === 403 ) { throw new ForbiddenError ( response . status , '' ) ; } if ( response . status === 404 ) { throw new NotFoundError ( response . status , response . statusText ) ; } if ( ! response . ok ) { throw Error ( response . statusText ) ; } return response ; } ; export const fetchWithToken = < T = any > ( url , params ? , cancel ? , reloadOnUnauthorized = false , headers ? , token = getAccessToken ( ) ) : Promise < T > => { const requestHeaders = headers ?? new Headers ( ) ; if ( token ?. length > 0 ) { requestHeaders . set ( 'Authorization' , `Bearer ${ token }` ) ; } const options = { headers : requestHeaders , } ; if ( cancel ) { options . signal = cancel ; } const searchParams = ( params instanceof URLSearchParams ? params : new URLSearchParams ( params ) ) . toString ( ) ; const fullUrl = `${ url }${ searchParams ? `?${ searchParams }` : '' }` ; return fetch ( fullUrl , options ) . then ( ( response ) => handleErrors ( response , reloadOnUnauthorized ) ) . then ( ( response ) => response . json ( ) ) as Promise < T > ; } ; export const createUrlWithToken = ( url , token ) => { const parsedUrl = new URL ( url ) ; if ( token . length > 0 ) { parsedUrl . searchParams . set ( 'access_token' , token ) ; } return parsedUrl . toString ( ) ; } ; export const fetchProxy = < T = any > ( url , init = { } ) : Promise < T > => { const { headers , searchParams = { } , ... otherOptions } = init ; const requestHeaders = new Headers ( headers ) ; const authHeaders = Object . entries ( getAuthHeaders ( ) ) ; authHeaders . forEach ( ( [ name , value ] ) => { if ( value ) requestHeaders . append ( name , value ) ; } ) ; const options = { ... otherOptions , headers : requestHeaders , } ; const fullUrl = new URL ( url ) ; const params = new URLSearchParams ( searchParams ) ; const paramsInUrl = fullUrl . searchParams ; params . forEach ( ( value , key ) => { paramsInUrl . set ( key , value ) ; } ) ; fullUrl . search = paramsInUrl . toString ( ) ; return fetch ( fullUrl . toString ( ) , options ) . then ( ( response ) => handleErrors ( response ) ) . then ( ( response ) => response . json ( ) ) as Promise < T > ; } ;