import * as express from 'express' ; import * as http from 'http' ; interface IRequestOptions { method : string ; headers ? : { } ; redirect ? : string ; follow ? : number ; timeout ? : number ; compress ? : boolean ; size ? : number ; body : any ; agent ? : null ; } param repo const proxyRequester = ( repo ) => express . Router ( ) . use ( async ( req , res , next ) => { const path = req . url . split ( '/' ) . filter ( param => param !== '' ) . filter ( param => param !== req . url . split ( '/' ) [ 1 ] ) . join ( '/' ) ; const token = req . get ( 'x-access-token' ) || req . get ( 'authentication' ) || req . get ( 'authorization' ) || undefined ; const { serverConfig : { backendToken = null } = { } } = req ; const repoFind = await repo . find ( req . url . split ( '/' ) [ 1 ] ) . catch ( err => err ) ; if ( ! repoFind || repoFind instanceof Error ) return next ( { code : 500 , message : 'Error Route not existing or unactive: ' + `/${ req . url . split ( '/' ) [ 1 ] }/${ path }` , stack : repoFind } ) ; const { label : service = null , host = null , port = null } = repoFind || { } ; let responseStatus = 200 ; if ( ! host || ! port ) return next ( { code : 500 , message : 'Service not have PORT or HOST' } ) ; const hostname = ( process . env . NODE_ENV === 'production' ) ? `${ host }:${ port }` : `http://${ host }:${ port }` ; console . log ( '[INFO]: Send request proxy to -->' , hostname + '/api/v2/' + path , req . method . toUpperCase ( ) ) ; const body = JSON . stringify ( { ... req . body || { } } ) ; const requestOptions = { method : req . method . toUpperCase ( ) , hostname : hostname . split ( '//' ) . find ( i => i . indexOf ( 'http' ) < 0 ) . split ( ':' ) [ 0 ] , port : port || hostname . split ( ':' ) [ 2 ] , path : '/api/v2/' + path , headers : { 'Content-type' : req . headers [ 'content-type' ] || 'application/json' , 'x-access-token' : token || '' , 'x-backend-token' : backendToken || '' , 'Content-Length' : Buffer . byteLength ( body , 'utf8' ) } , } ; let responseType ; const responseProxy = await new Promise ( ( resolve , reject ) => { const request = http . request ( requestOptions , ( resp ) => { let data = '' ; resp . on ( 'data' , ( chunk ) => data += chunk ) ; resp . on ( 'end' , ( ) => { responseType = resp . headers [ 'content-type' ] ; if ( responseType && responseType . includes ( 'application/json' ) ) { resolve ( JSON . parse ( data || null ) ) ; } else { resolve ( data || null ) ; } } ) ; } ) . on ( 'error' , ( err ) => reject ( err || { } ) ) ; request . write ( body ) ; request . end ( ) ; } ) . catch ( err => err ) ; if ( responseProxy . status || responseProxy . code ) responseStatus = responseProxy . status || responseProxy . code ; if ( responseType ) res . setHeader ( 'Content-Type' , responseType ) ; return res . status ( responseStatus ) . send ( responseProxy ) ; } ) ; param options { repo export const proxyRoutes = ( options ) => { const { repo } = options ; return proxyRequester ( repo ) ; } ;