11"use strict" ;
22
3- // TODO: req id in log sync u async
4-
5- const NO_MATCHING_ACTION = request => {
6- throw { reason : 'NO_MATCHING_ACTION' , message : `Could not find matching action for ${ request . path } and method ${ request . httpMethod } ` }
3+ const NO_MATCHING_ACTION = request => {
4+ throw {
5+ reason : 'NO_MATCHING_ACTION' ,
6+ message : `Could not find matching action for ${ request . path } and method ${ request . httpMethod } `
7+ }
78} ;
89
9- function handler ( routeConfig ) {
10- return ( event , context , callback ) => process ( event , routeConfig , callback )
11- }
12-
13- function process ( event , routeConfig , callback ) {
14- if ( routeConfig . debug ) {
15- console . log ( 'Event' , event ) ;
10+ function process ( proxyIntegrationConfig , event ) {
11+ //validate config
12+ if ( ! Array . isArray ( proxyIntegrationConfig . routes ) || proxyIntegrationConfig . routes . length < 1 ) {
13+ throw new Error ( 'proxyIntegration.routes must not be empty' ) ;
1614 }
1715
18- const headers = {
16+ // detect if it's an http-call at all:
17+ if ( ! event . httpMethod || ! event . path ) {
18+ return null ;
19+ }
20+ const headers = Object . assign ( {
1921 'Content-Type' : 'application/json'
20- } ;
21- // assure necessary values have sane defaults:
22- event . path = event . path || '' ;
23- const errorMapping = routeConfig . errorMapping || { } ;
24- errorMapping [ 'NO_MATCHING_ACTION' ] = 404 ;
25- routeConfig . routes = routeConfig . routes || [ ] ;
26- if ( routeConfig . cors ) {
22+ } , proxyIntegrationConfig . defaultHeaders ) ;
23+ if ( proxyIntegrationConfig . cors ) {
2724 headers [ "Access-Control-Allow-Origin" ] = "*" ;
2825 }
29- // ugly hack: if host is from 'Custom Domain Name Mapping', then event.path has the value '/basepath/resource-path/';
30- // if host is from amazonaws.com, then event.path is just '/resource-path':
31- const apiId = event . requestContext ? event . requestContext . apiId : null ; // the apiId that is the first part of the amazonaws.com-host
32- if ( ( apiId && event . headers && event . headers . Host && event . headers . Host . substring ( 0 , apiId . length ) != apiId ) ) {
33- // remove first path element:
34- const groups = / \/ [ ^ \/ ] + ( .* ) / . exec ( event . path ) || [ null , null ] ;
35- event . path = groups [ 1 ] || '/' ;
36- }
26+
27+ // assure necessary values have sane defaults:
28+ const errorMapping = proxyIntegrationConfig . errorMapping || { } ;
29+ errorMapping [ 'NO_MATCHING_ACTION' ] = 404 ;
30+
31+ event . path = normalizeRequestPath ( event ) ;
3732
3833 try {
39- const actionConfig = findMatchingActionConfig ( event . httpMethod , event . path , routeConfig ) || { action : NO_MATCHING_ACTION } ;
34+ const actionConfig = findMatchingActionConfig ( event . httpMethod , event . path , proxyIntegrationConfig ) || { action : NO_MATCHING_ACTION } ;
4035 event . paths = actionConfig . paths ;
4136 if ( event . body ) {
4237 event . body = JSON . parse ( event . body ) ;
4338 }
44- const result = actionConfig . action ( event ) ;
45- if ( result && result . then ) {
46- return result
47- . then ( res => {
48- callback ( null , { statusCode : 200 , headers : headers , body : JSON . stringify ( res ) } ) ;
49- } )
50- . catch ( err => {
51- callback ( null , convertError ( err , errorMapping , headers ) )
52- } ) ;
53- } else {
54- callback ( null , { statusCode : 200 , headers : headers , body : JSON . stringify ( result ) } ) ;
55- }
39+ return Promise . resolve ( actionConfig . action ( event ) ) . then ( res => {
40+ return { statusCode : 200 , headers : headers , body : JSON . stringify ( res ) } ;
41+ } ) . catch ( err => {
42+ return convertError ( err , errorMapping , headers ) ;
43+ } ) ;
5644 } catch ( error ) {
5745 console . log ( 'Error while evaluating matching action handler' , error ) ;
58- callback ( null , convertError ( error , errorMapping , headers ) ) ;
46+ return Promise . resolve ( convertError ( error , errorMapping , headers ) ) ;
47+ }
48+ }
49+
50+ function normalizeRequestPath ( event ) {
51+ // ugly hack: if host is from API-Gateway 'Custom Domain Name Mapping', then event.path has the value '/basepath/resource-path/';
52+ // if host is from amazonaws.com, then event.path is just '/resource-path':
53+ const apiId = event . requestContext ? event . requestContext . apiId : null ; // the apiId that is the first part of the amazonaws.com-host
54+ if ( ( apiId && event . headers && event . headers . Host && event . headers . Host . substring ( 0 , apiId . length ) != apiId ) ) {
55+ // remove first path element:
56+ const groups = / \/ [ ^ \/ ] + ( .* ) / . exec ( event . path ) || [ null , null ] ;
57+ return groups [ 1 ] || '/' ;
5958 }
59+
60+ return event . path ;
6061}
6162
6263function convertError ( error , errorMapping , headers ) {
@@ -68,7 +69,7 @@ function convertError(error, errorMapping, headers) {
6869
6970function findMatchingActionConfig ( httpMethod , httpPath , routeConfig ) {
7071 const paths = { } ;
71- var matchingMethodRoutes = routeConfig . routes . filter ( route => route . method == httpMethod ) ;
72+ const matchingMethodRoutes = routeConfig . routes . filter ( route => route . method == httpMethod ) ;
7273 for ( let route of matchingMethodRoutes ) {
7374 if ( routeConfig . debug ) {
7475 console . log ( `Examining route ${ route . path } to match ${ httpPath } ` ) ;
@@ -104,5 +105,4 @@ function extractPathNames(pathExpression) {
104105 return pathNames && pathNames . length > 0 ? pathNames . slice ( 1 ) : null ;
105106}
106107
107-
108- module . exports = { handler : handler } ;
108+ module . exports = process ;
0 commit comments