import axios from 'axios' ; import { STORAGE_KEY } from './lib/constants' ; import { isBrowser } from './lib/helpers' ; import { AuthResponseFailure , AuthResponse , ProfileResponse , TokenResponse , } from './lib/types' ; export default class AuthClient { protected url : string ; protected headers : { [ key ] : string ; } ; protected currentToken : string | null ; constructor ( url , { headers = { } } = { } ) { this . url = url ; this . headers = { ... headers } ; this . currentToken = null ; this . _initToken ( ) ; } private _error ( error ) { if ( axios . isAxiosError ( error ) && error . response ) { return { error : { message : error . response . data ?. message ? error . response . data . message : typeof error . response . data === 'object' ? JSON . stringify ( error . response . data ) : String ( error . response . data ) , } , status : error . response . status , statusText : error . response . statusText , } ; } return { error : { message : 'Failed' , } , status : 500 , statusText : 'FAILED' , } ; } async login < T = any > ( body ) { return new Promise ( async ( resolve , reject ) => { try { const { data , status , statusText } = await axios . post < TokenResponse < T > > ( `${ this . url }/auth/login` , body ) ; this . saveToken ( data . token ) ; const user = data . user ; resolve ( { user , status , statusText , token : data . token , } ) ; } catch ( error ) { resolve ( this . _error ( error ) ) ; } } ) ; } async register < T = any > ( body ) { return new Promise ( async ( resolve , reject ) => { try { const { data , status , statusText } = await axios . post < TokenResponse < T > > ( `${ this . url }/auth/register` , body ) ; this . saveToken ( data . token ) ; const user = data . user ; resolve ( { user , status , statusText , token : data . token , } ) ; } catch ( error ) { resolve ( this . _error ( error ) ) ; } } ) ; } async user < T = any > ( ) { return new Promise ( async ( resolve , reject ) => { try { const { data , status , statusText } = await axios . get < T > ( `${ this . url }/auth/user` , { headers : this . _headers ( ) , } ) ; const user = data ; resolve ( { user , status , statusText , } ) ; } catch ( error ) { resolve ( this . _error ( error ) ) ; } } ) ; } async update < T = any > ( body ) { return new Promise ( async ( resolve , reject ) => { try { const { data , status , statusText } = await axios . patch < T > ( `${ this . url }/auth/user` , body , { headers : this . _headers ( ) , } ) ; const user = data ; resolve ( { user , status , statusText , } ) ; } catch ( error ) { resolve ( this . _error ( error ) ) ; } } ) ; } token ( ) { return this . currentToken ; } private _headers ( ) { const headers = this . headers ; const authBearer = this . token ( ) ; if ( authBearer && authBearer !== '' ) { headers [ 'Authorization' ] = `Bearer ${ authBearer }` ; } return headers ; } saveToken ( token ) { this . currentToken = token ; this . _setToken ( token ) ; } async logout < T = any > ( ) { return new Promise ( async ( resolve , reject ) => { try { const { data , status , statusText } = await axios . post < TokenResponse < T > > ( `${ this . url }/auth/logout` , null , { headers : this . _headers ( ) , } ) ; this . _removeToken ( ) ; const user = data . user ; resolve ( { user , status , statusText , token : data . token , } ) ; } catch ( error ) { resolve ( this . _error ( error ) ) ; } } ) ; } private _setToken ( token ) { if ( isBrowser ( ) ) { window . localStorage . setItem ( STORAGE_KEY , token ) ; } } private _removeToken ( ) { this . currentToken = null ; if ( isBrowser ( ) ) { window . localStorage . removeItem ( STORAGE_KEY ) ; } } private _initToken ( ) { if ( isBrowser ( ) ) { const token = window . localStorage . getItem ( STORAGE_KEY ) ; if ( token ) { this . currentToken = token ; } } } }