import { Request , Response , NextFunction } from 'express' ; import { SPClient , SPResponse , FetchError } from '../utils/client' ; import { UrlUtils } from '../utils/url' ; import { Logger } from '../utils/logger' ; import { IProxyContext , IProxySettings } from './interfaces' ; import { copyHeaders } from '../utils/headers' ; const keepHeaders = [ 'cache-control' , 'content-length' , 'content-type' , 'date' , 'etag' , 'expires' , 'last-modified' , 'request-id' ] ; export class BasicRouter { public sp : SPClient ; public url : UrlUtils ; public logger : Logger ; constructor ( public ctx , public settings ) { this . sp = new SPClient ( ctx , settings ) ; this . url = new UrlUtils ( ctx , settings ) ; this . logger = new Logger ( settings . logLevel ) ; } public router : ( req : Request , r : Response , next ? : NextFunction ) => void ; public handlers = { isOK : async ( resp ) : Promise < SPResponse > => { if ( ! resp . ok ) { const error = { status : resp . status , statusText : resp . statusText , response : resp } ; try { error . body = await resp . clone ( ) . text ( ) ; } catch ( ex ) { } throw error ; } return resp ; } , response : ( r ) => async ( resp , bodyReader ? ) : Promise < void > => { bodyReader = bodyReader || ( ( a ) => a . text ( ) ) ; const data = await bodyReader ( resp ) ; this . logger . verbose ( resp . status , `${ data }` ) ; if ( typeof this . settings . hooks ?. responseMapper === 'function' ) { try { resp = await this . settings . hooks . responseMapper ( r . req , resp , this ) ; } catch ( ex ) { } } copyHeaders ( r , resp . headers , [ ] , [ 'content-encoding' , 'content-security-policy' , 'set-cookie' , 'transfer-encoding' ] ) ; r . status ( resp . status ) ; const ct = resp . headers . get ( 'content-type' ) ; if ( ct ) { r . contentType ( ct ) ; } r . send ( data ) ; } , error : ( r ) => ( err ) : void => { const { status , statusText , body , response : apiResp } = err ; if ( status ) { this . logger . error ( 'Error' , { status , statusText , body } ) ; } else { this . logger . error ( 'Error' , err ) ; } r . status ( status || 400 ) ; if ( apiResp ) { copyHeaders ( r , apiResp . headers , keepHeaders ) ; const ct = apiResp . headers . get ( 'content-type' ) ; if ( ct ) { r . contentType ( ct ) ; } } const message = ( err as unknown as { message : string ; } ) . message ; r . send ( body || statusText || ( message && `Proxy Error: ${ message } (see more in sp-rest-proxy console)` ) || 'Unknown error' ) ; } } ; }