UNPKG

@devmn/cloud-cli

Version:

CLI tool for Intelligo Cloud.

179 lines (160 loc) 6.02 kB
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: string, private appToken: string | undefined, private authToken: string, private onAuthFailure: () => Promise<any> ) { // } createHeaders() { const headers: any = {} if (this.authToken) { headers[TOKEN_HEADER] = this.authToken } if (this.appToken) { headers[APP_TOKEN_HEADER] = this.appToken } headers[NAMESPACE] = CAPTAIN // check user/appData or apiManager.uploadAppData before changing this signature. return headers } setAuthToken(authToken: string) { this.authToken = authToken } destroy() { this.isDestroyed = true } fetch( method: 'GET' | 'POST' | 'POST_DATA', endpoint: string, variables: any ) { 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) { // tslint:disable-next-line: max-line-length // These two blocks are clearly memory leaks! But I don't have time to fix them now... I need to CANCEL the promise, but since I don't // have CANCEL method on the native Promise, I return a promise that will never RETURN if the HttpClient is destroyed. // tslint:disable-next-line: max-line-length // Will fix them later... but it shouldn't be a big deal anyways as it's only a problem when user navigates away from a page before the // network request returns back. return new Promise(function(resolve, reject) { // data.data here is the "data" field inside the API response! {status: 100, description: "Login succeeded", data: {…}} if (!self.isDestroyed) { return resolve(data.data) } Logger.dev('Destroyed then not called') }) }) .catch(function(error) { // Logger.log(''); // Logger.error(error.message || error); return new Promise(function(resolve, reject) { if (!self.isDestroyed) { return reject(error) } Logger.dev('Destroyed catch not called') }) }) } } fetchInternal( method: 'GET' | 'POST' | 'POST_DATA', endpoint: string, variables: any ) { 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: string, variables: any) { const self = this return Request.get(this.baseUrl + endpoint, { headers: self.createHeaders(), qs: variables, json: true }).then(function(data) { return data }) } postReq( endpoint: string, variables: any, method: 'GET' | 'POST' | 'POST_DATA' ) { 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 }) } }