import fetch from "cross-fetch" ; import * as debug from "debug" ; import { removeUndefined , throwError } from "./utils" ; import { MC_NAME , MC_VERSION } from "../version" ; const HttpsProxyAgent = require ( "https-proxy-agent" ) ; const log = debug ( "mindconnect" ) ; export interface export interface TokenRotation { returns { Promise < boolean > } memberOf RenewToken ( ) : Promise < boolean > ; returns { Promise < string > } memberOf GetToken ( ) : Promise < string > ; returns { string } memberOf GetGateway ( ) : string ; returns { string } memberOf GetTenant ( ) : string ; HttpAction ( { verb , gateway , baseUrl , authorization , body , message , octetStream , multiPartFormData , additionalHeaders , noResponse , rawResponse , returnHeaders , ignoreCodes , } ) : Promise < Object | undefined > ; } export function isTokenRotation ( obj ) { const tr = obj as TokenRotation ; return ( tr . GetGateway !== undefined && tr . GetTenant !== undefined && tr . GetToken !== undefined && tr . RenewToken !== undefined && tr instanceof Object && typeof tr . GetGateway === "function" && typeof tr . GetTenant === "function" && typeof tr . GetToken === "function" && typeof tr . RenewToken === "function" ) ; } export abstract class export abstract class MindConnectBase { protected type { * } memberof protected _proxyHttpAgent : any ; protected _headers = { Accept : "*/*" , "X-Powered-By" : "meowz" , "User-Agent" : `${ MC_NAME } (${ MC_VERSION })` , } ; protected memberof protected _multipartHeaders = { ... this . _headers , "Content-Type" : "multipart/mixed; boundary=mindspheremessage" , } ; protected _multipartFormData = { ... this . _headers , "Content-Type" : "multipart/form-data; boundary=--mindsphere" , } ; protected memberof protected _apiHeaders = { ... this . _headers , "Content-Type" : "application/json" , } ; protected _octetStreamHeaders = { ... this . _headers , "Content-Type" : "application/octet-stream" , } ; protected memberof protected _urlEncodedHeaders = { ... this . _headers , "Content-Type" : "application/x-www-form-urlencoded" , } ; param { ( { verb : "GET" | "POST" | "PATCH" | "PUT" | "DELETE" ; gateway : string ; baseUrl : string ; authorization : string ; body ? : Object ; message ? : string ; octetStream ? : boolean ; multiPartFormData ? : boolean ; additionalHeaders ? : Object ; noResponse ? : boolean ; rawResponse ? : boolean ; returnHeaders ? : boolean ; ignoreCodes ? : number [ ] ; * } ) } returns { Promise < Object > } memberOf public async HttpAction ( { verb , gateway , baseUrl , authorization , body , message , octetStream , multiPartFormData , additionalHeaders , noResponse , rawResponse , returnHeaders , ignoreCodes , } ) { additionalHeaders = additionalHeaders || { } ; let apiheaders = octetStream ? this . _octetStreamHeaders : this . _apiHeaders ; apiheaders = multiPartFormData ? this . _multipartFormData : apiheaders ; ignoreCodes = ignoreCodes || [ ] ; let headers = { ... apiheaders , Authorization : `Bearer ${ authorization }` , } ; if ( verb === "GET" || verb === "DELETE" ) { delete headers [ "Content-Type" ] ; } headers = removeUndefined ( { ... headers , ... additionalHeaders } ) ; const url = `${ gateway }${ baseUrl }` ; log ( `${ message } Headers ${ JSON . stringify ( headers ) } Url ${ url }` ) ; try { const request = { method : verb , headers : headers , agent : this . _proxyHttpAgent } ; if ( verb !== "GET" && verb !== "DELETE" ) { request . body = octetStream || multiPartFormData ? body : JSON . stringify ( body ) ; } const response = await fetch ( url , request ) ; const codeIgnored = ignoreCodes . indexOf ( response . status ) >= 0 ; ! codeIgnored && ! response . ok && throwError ( `${ response . statusText } ${ await response . text ( ) }` ) ; ! codeIgnored && ( response . status < 200 || response . status > 299 ) && throwError ( `invalid response ${ JSON . stringify ( response ) }` ) ; if ( codeIgnored ) return undefined ; if ( rawResponse ) return response ; if ( noResponse ) { if ( returnHeaders ) { return response . headers ; } return { } ; } const json = await response . json ( ) ; log ( `${ message } Response ${ JSON . stringify ( json ) }` ) ; return json ; } catch ( err ) { log ( err ) ; throw new Error ( `Network error occured ${ err . message }` ) ; } } constructor ( ) { const proxy = process . env . http_proxy || process . env . HTTP_PROXY ; log ( `Proxy: ${ proxy }` ) ; this . _proxyHttpAgent = proxy ? new HttpsProxyAgent ( proxy ) : null ; } }