1
1
"use strict" ;
2
2
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
+ }
7
8
} ;
8
9
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' ) ;
16
14
}
17
15
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 ( {
19
21
'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 ) {
27
24
headers [ "Access-Control-Allow-Origin" ] = "*" ;
28
25
}
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 ) ;
37
32
38
33
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 } ;
40
35
event . paths = actionConfig . paths ;
41
36
if ( event . body ) {
42
37
event . body = JSON . parse ( event . body ) ;
43
38
}
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
+ } ) ;
56
44
} catch ( error ) {
57
45
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 ] || '/' ;
59
58
}
59
+
60
+ return event . path ;
60
61
}
61
62
62
63
function convertError ( error , errorMapping , headers ) {
@@ -68,7 +69,7 @@ function convertError(error, errorMapping, headers) {
68
69
69
70
function findMatchingActionConfig ( httpMethod , httpPath , routeConfig ) {
70
71
const paths = { } ;
71
- var matchingMethodRoutes = routeConfig . routes . filter ( route => route . method == httpMethod ) ;
72
+ const matchingMethodRoutes = routeConfig . routes . filter ( route => route . method == httpMethod ) ;
72
73
for ( let route of matchingMethodRoutes ) {
73
74
if ( routeConfig . debug ) {
74
75
console . log ( `Examining route ${ route . path } to match ${ httpPath } ` ) ;
@@ -104,5 +105,4 @@ function extractPathNames(pathExpression) {
104
105
return pathNames && pathNames . length > 0 ? pathNames . slice ( 1 ) : null ;
105
106
}
106
107
107
-
108
- module . exports = { handler : handler } ;
108
+ module . exports = process ;
0 commit comments