@@ -9,6 +9,7 @@ const $RefParser = require('@apidevtools/json-schema-ref-parser');
99const url = require ( 'url' ) ;
1010const deepmerge = require ( 'deepmerge' ) ;
1111const path = require ( 'path' ) ;
12+ const jsonpath = require ( 'jsonpath' ) ;
1213
1314const httpUtils = require ( './http_utils' ) ;
1415
@@ -114,6 +115,7 @@ class Template {
114115 this . _allOf = [ ] ;
115116 this . _anyOf = [ ] ;
116117 this . contentType = 'text/plain' ;
118+ this . httpForward = null ;
117119 }
118120
119121 _loadTypeSchemas ( schemaProvider ) {
@@ -431,12 +433,9 @@ class Template {
431433 _createParametersValidator ( ) {
432434 const loadSchema = ( uri ) => {
433435 uri = url . parse ( uri ) ;
434- const opts = {
435- host : uri . host ,
436- port : uri . port ,
437- parth : uri . pathName ,
436+ const opts = Object . assign ( { } , url . parse ( uri ) , {
438437 method : 'GET'
439- } ;
438+ } ) ;
440439 return httpUtils . makeRequest ( opts )
441440 . then ( ( res ) => {
442441 if ( res . statusCode >= 400 ) {
@@ -772,6 +771,80 @@ class Template {
772771 return acc ;
773772 } ) ;
774773 }
774+
775+ fetchHttp ( ) {
776+ const promises = [ ] ;
777+ const view = { } ;
778+ Object . entries ( this . definitions ) . forEach ( ( [ def , defProp ] ) => {
779+ if ( ! defProp . url ) {
780+ return ;
781+ }
782+
783+ const defaultOpts = {
784+ method : 'GET' ,
785+ host : null ,
786+ port : null ,
787+ headers : {
788+ }
789+ } ;
790+ const urlOpts = ( typeof defProp . url === 'string' ) ? url . parse ( defProp . url ) : defProp . url ;
791+ const opts = Object . assign ( { } , defaultOpts , urlOpts ) ;
792+ promises . push ( Promise . resolve ( )
793+ . then ( ( ) => httpUtils . makeRequest ( opts ) )
794+ . then ( ( res ) => {
795+ if ( res . statusCode >= 400 ) {
796+ return Promise . reject ( new Error ( `error loading ${ defProp . url } : ${ res . statusCode } ` ) ) ;
797+ }
798+ try {
799+ view [ def ] = JSON . parse ( res . body ) ;
800+ } catch ( e ) {
801+ view [ def ] = res . body ;
802+ }
803+ if ( defProp . pathQuery ) {
804+ const results = jsonpath . query ( view [ def ] , defProp . pathQuery , 1 ) ;
805+ view [ def ] = results [ 0 ] ;
806+ }
807+ return Promise . resolve ( ) ;
808+ } ) ) ;
809+ } ) ;
810+ return Promise . all ( promises )
811+ . then ( ( ) => view ) ;
812+ }
813+
814+ fetchAndRender ( parameters ) {
815+ return Promise . resolve ( )
816+ . then ( ( ) => this . fetchHttp ( ) )
817+ . then ( httpView => Object . assign ( { } , parameters , httpView ) )
818+ . then ( combParams => this . render ( combParams ) ) ;
819+ }
820+
821+ forwardHttp ( parameters ) {
822+ if ( ! this . httpForward ) {
823+ return Promise . reject (
824+ new Error ( 'httpForward was not defined for this template' )
825+ ) ;
826+ }
827+
828+ const defaultOpts = {
829+ method : 'POST' ,
830+ host : null ,
831+ port : null ,
832+ headers : {
833+ 'Content-Type' : this . contentType
834+ }
835+ } ;
836+ const urlOpts = ( typeof this . httpForward . url === 'string' ) ? url . parse ( this . httpForward . url ) : this . httpForward . url ;
837+ const opts = Object . assign ( { } , defaultOpts , urlOpts ) ;
838+ return Promise . resolve ( )
839+ . then ( ( ) => this . fetchAndRender ( parameters ) )
840+ . then ( ( ) => httpUtils . makeRequest ( opts ) )
841+ . then ( ( res ) => {
842+ if ( res . statusCode >= 400 ) {
843+ return Promise . reject ( new Error ( `error forwarding to ${ this . httpForward . url } : ${ res . statusCode } ` ) ) ;
844+ }
845+ return Promise . resolve ( res ) ;
846+ } ) ;
847+ }
775848}
776849
777850module . exports = {
0 commit comments