import ErrorFactory from '../utils/ErrorFactory' ; import Logger from '../utils/Logger' ; import * as Request from 'request-promise' ; const TOKEN_HEADER = 'x-captain-auth' ; const APP_TOKEN_HEADER = 'x-captain-app-token' ; const NAMESPACE = 'x-namespace' ; const CAPTAIN = 'captain' ; export default class HttpClient { readonly GET = 'GET' ; readonly POST = 'POST' ; readonly POST_DATA = 'POST_DATA' ; isDestroyed = false ; constructor ( private baseUrl , private appToken , private authToken , private onAuthFailure ) { } createHeaders ( ) { const headers = { } ; if ( this . authToken ) { headers [ TOKEN_HEADER ] = this . authToken ; } if ( this . appToken ) { headers [ APP_TOKEN_HEADER ] = this . appToken ; } headers [ NAMESPACE ] = CAPTAIN ; return headers ; } setAuthToken ( authToken ) { this . authToken = authToken ; } destroy ( ) { this . isDestroyed = true ; } fetch ( method , endpoint , variables ) { const self = this ; return function ( ) : Promise < any > { return Promise . resolve ( ) . then ( function ( ) { if ( ! process . env . REACT_APP_IS_DEBUG ) { return Promise . resolve ( ) ; } return new Promise < void > ( function ( res ) { setTimeout ( res , 500 ) ; } ) ; } ) . then ( function ( ) { return self . fetchInternal ( method , endpoint , variables ) ; } ) . then ( function ( data ) { if ( data . status === ErrorFactory . STATUS_AUTH_TOKEN_INVALID ) { return self . onAuthFailure ( ) . then ( function ( ) { return self . fetchInternal ( method , endpoint , variables ) . then ( function ( newRequestResponse ) { return newRequestResponse ; } ) ; } ) ; } else { return data ; } } ) . then ( function ( data ) { if ( data . status !== ErrorFactory . OKAY && data . status !== ErrorFactory . OKAY_BUILD_STARTED ) { throw ErrorFactory . createError ( data . status || ErrorFactory . UNKNOWN_ERROR , data . description || '' ) ; } return data ; } ) . then ( function ( data ) { return new Promise ( function ( resolve , reject ) { if ( ! self . isDestroyed ) { return resolve ( data . data ) ; } Logger . dev ( 'Destroyed then not called' ) ; } ) ; } ) . catch ( function ( error ) { return new Promise ( function ( resolve , reject ) { if ( ! self . isDestroyed ) { return reject ( error ) ; } Logger . dev ( 'Destroyed catch not called' ) ; } ) ; } ) ; } ; } fetchInternal ( method , endpoint , variables ) { if ( method === this . GET ) { return this . getReq ( endpoint , variables ) ; } if ( method === this . POST || method === this . POST_DATA ) { return this . postReq ( endpoint , variables , method ) ; } throw new Error ( 'Unknown method: ' + method ) ; } getReq ( endpoint , variables ) { const self = this ; return Request . get ( this . baseUrl + endpoint , { headers : self . createHeaders ( ) , qs : variables , json : true } ) . then ( function ( data ) { return data ; } ) ; } postReq ( endpoint , variables , method ) { const self = this ; if ( method === this . POST_DATA ) { return Request . post ( this . baseUrl + endpoint , { headers : self . createHeaders ( ) , formData : variables , json : true } ) . then ( function ( data ) { return data ; } ) ; } return Request . post ( this . baseUrl + endpoint , { headers : self . createHeaders ( ) , body : variables , json : true } ) . then ( function ( data ) { return data ; } ) ; } }