1- import { APIGatewayProxyEvent , APIGatewayEventRequestContext , APIGatewayProxyResult } from " aws-lambda" ;
2- import { ProcessMethod } from " ./EventProcessor" ;
1+ import { APIGatewayEventRequestContext , APIGatewayProxyEvent , APIGatewayProxyResult } from ' aws-lambda'
2+ import { ProcessMethod } from ' ./EventProcessor'
33
44export type ProxyIntegrationEvent = APIGatewayProxyEvent
55type ProxyIntegrationParams = {
@@ -8,12 +8,12 @@ type ProxyIntegrationParams = {
88export type ProxyIntegrationEventWithParams = APIGatewayProxyEvent & ProxyIntegrationParams
99
1010export interface ProxyIntegrationRoute {
11- path : string ;
12- method : string ;
11+ path : string
12+ method : string
1313 action : (
1414 request : ProxyIntegrationEventWithParams ,
1515 context : APIGatewayEventRequestContext
16- ) => APIGatewayProxyResult | Promise < APIGatewayProxyResult > ;
16+ ) => APIGatewayProxyResult | Promise < APIGatewayProxyResult >
1717}
1818
1919export type ProxyIntegrationErrorMapping = {
@@ -29,40 +29,40 @@ export type ProxyIntegrationError = {
2929}
3030
3131export interface ProxyIntegrationConfig {
32- cors ?: boolean ;
33- routes : ProxyIntegrationRoute [ ] ;
34- debug ?: boolean ;
35- errorMapping ?: ProxyIntegrationErrorMapping ;
36- defaultHeaders ?: APIGatewayProxyResult [ 'headers' ] ;
37- proxyPath ?: string ;
32+ cors ?: boolean
33+ routes : ProxyIntegrationRoute [ ]
34+ debug ?: boolean
35+ errorMapping ?: ProxyIntegrationErrorMapping
36+ defaultHeaders ?: APIGatewayProxyResult [ 'headers' ]
37+ proxyPath ?: string
3838}
3939
4040const NO_MATCHING_ACTION = ( request : APIGatewayProxyEvent ) => {
4141 throw {
4242 reason : 'NO_MATCHING_ACTION' ,
4343 message : `Could not find matching action for ${ request . path } and method ${ request . httpMethod } `
4444 }
45- } ;
45+ }
4646
4747const addCorsHeaders = ( toAdd : APIGatewayProxyResult [ 'headers' ] = { } ) => {
48- toAdd [ " Access-Control-Allow-Origin" ] = "*" ;
49- toAdd [ " Access-Control-Allow-Methods" ] = " GET,POST,PUT,DELETE,HEAD,PATCH" ;
50- toAdd [ " Access-Control-Allow-Headers" ] = " Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token" ;
51- return toAdd ;
48+ toAdd [ ' Access-Control-Allow-Origin' ] = '*'
49+ toAdd [ ' Access-Control-Allow-Methods' ] = ' GET,POST,PUT,DELETE,HEAD,PATCH'
50+ toAdd [ ' Access-Control-Allow-Headers' ] = ' Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
51+ return toAdd
5252}
5353
5454const processActionAndReturn = async ( actionConfig : Pick < ProxyIntegrationRoute , 'action' > , event : ProxyIntegrationEventWithParams ,
55- context : APIGatewayEventRequestContext , headers : APIGatewayProxyResult [ 'headers' ] ) => {
55+ context : APIGatewayEventRequestContext , headers : APIGatewayProxyResult [ 'headers' ] ) => {
5656
5757 const res = await actionConfig . action ( event , context )
5858 if ( ! res || ! res . body ) {
59- const consolidateBody = res && JSON . stringify ( res ) || '{}' ;
59+ const consolidateBody = res && JSON . stringify ( res ) || '{}'
6060
6161 return {
6262 statusCode : 200 ,
6363 headers,
6464 body : consolidateBody
65- } ;
65+ }
6666 }
6767
6868 return {
@@ -79,91 +79,91 @@ export const process: ProcessMethod<ProxyIntegrationConfig, ProxyIntegrationEven
7979 ( proxyIntegrationConfig , event , context ) => {
8080
8181 if ( proxyIntegrationConfig . debug ) {
82- console . log ( " Lambda proxyIntegrationConfig: " , proxyIntegrationConfig ) ;
83- console . log ( " Lambda event: " , event ) ;
84- console . log ( " Lambda context: " , context ) ;
82+ console . log ( ' Lambda proxyIntegrationConfig: ' , proxyIntegrationConfig )
83+ console . log ( ' Lambda event: ' , event )
84+ console . log ( ' Lambda context: ' , context )
8585 }
8686
8787 //validate config
8888 if ( ! Array . isArray ( proxyIntegrationConfig . routes ) || proxyIntegrationConfig . routes . length < 1 ) {
89- throw new Error ( 'proxyIntegration.routes must not be empty' ) ;
89+ throw new Error ( 'proxyIntegration.routes must not be empty' )
9090 }
9191
9292 // detect if it's an http-call at all:
9393 if ( ! event . httpMethod || ! event . path ) {
94- return null ;
94+ return null
9595 }
9696
97- const headers : APIGatewayProxyResult [ 'headers' ] = { } ;
97+ const headers : APIGatewayProxyResult [ 'headers' ] = { }
9898 if ( proxyIntegrationConfig . cors ) {
99- addCorsHeaders ( headers ) ;
99+ addCorsHeaders ( headers )
100100 if ( event . httpMethod === 'OPTIONS' ) {
101101 return Promise . resolve ( {
102102 statusCode : 200 ,
103103 headers,
104104 body : ''
105- } ) ;
105+ } )
106106 }
107107 }
108108 Object . assign ( headers , { 'Content-Type' : 'application/json' } , proxyIntegrationConfig . defaultHeaders )
109109
110110 // assure necessary values have sane defaults:
111- const errorMapping = proxyIntegrationConfig . errorMapping || { } ;
112- errorMapping [ 'NO_MATCHING_ACTION' ] = 404 ;
111+ const errorMapping = proxyIntegrationConfig . errorMapping || { }
112+ errorMapping [ 'NO_MATCHING_ACTION' ] = 404
113113
114114 if ( proxyIntegrationConfig . proxyPath ) {
115- console . log ( " proxy path is set: " + proxyIntegrationConfig . proxyPath )
116- event . path = ( event . pathParameters || { } ) [ proxyIntegrationConfig . proxyPath ] ;
117- console . log ( " proxy path with event path: " + event . path )
115+ console . log ( ' proxy path is set: ' + proxyIntegrationConfig . proxyPath )
116+ event . path = ( event . pathParameters || { } ) [ proxyIntegrationConfig . proxyPath ]
117+ console . log ( ' proxy path with event path: ' + event . path )
118118
119119 } else {
120- event . path = normalizeRequestPath ( event ) ;
120+ event . path = normalizeRequestPath ( event )
121121 }
122122
123123 try {
124124 const actionConfig = findMatchingActionConfig ( event . httpMethod , event . path , proxyIntegrationConfig ) || {
125125 action : NO_MATCHING_ACTION ,
126126 paths : undefined
127- } ;
127+ }
128128
129- event . paths = actionConfig . paths ;
129+ event . paths = actionConfig . paths
130130 if ( event . body ) {
131131 try {
132- event . body = JSON . parse ( event . body ) ;
132+ event . body = JSON . parse ( event . body )
133133 } catch ( parseError ) {
134- console . log ( `Could not parse body as json: ${ event . body } ` , parseError ) ;
134+ console . log ( `Could not parse body as json: ${ event . body } ` , parseError )
135135 return {
136136 statusCode : 400 ,
137137 headers,
138- body : JSON . stringify ( { message : " body is not a valid JSON" , error : " ParseError" } )
138+ body : JSON . stringify ( { message : ' body is not a valid JSON' , error : ' ParseError' } )
139139 }
140140 }
141141 }
142142 return processActionAndReturn ( actionConfig , event , context , headers ) . catch ( error => {
143143 console . log ( 'Error while handling action function.' , error )
144- return convertError ( error , errorMapping , headers ) ;
144+ return convertError ( error , errorMapping , headers )
145145 } )
146146 } catch ( error ) {
147- console . log ( 'Error while evaluating matching action handler' , error ) ;
148- return convertError ( error , errorMapping , headers ) ;
147+ console . log ( 'Error while evaluating matching action handler' , error )
148+ return convertError ( error , errorMapping , headers )
149149 }
150150 }
151151
152152const normalizeRequestPath = ( event : APIGatewayProxyEvent ) : string => {
153153 if ( isLocalExecution ( event ) ) {
154- return event . path ;
154+ return event . path
155155 }
156156
157157 // ugly hack: if host is from API-Gateway 'Custom Domain Name Mapping', then event.path has the value '/basepath/resource-path/';
158158 // if host is from amazonaws.com, then event.path is just '/resource-path':
159- const apiId = event . requestContext ? event . requestContext . apiId : null ; // the apiId that is the first part of the amazonaws.com-host
159+ const apiId = event . requestContext ? event . requestContext . apiId : null // the apiId that is the first part of the amazonaws.com-host
160160 if ( ( apiId && event . headers && event . headers . Host && event . headers . Host . substring ( 0 , apiId . length ) !== apiId ) ) {
161161 // remove first path element:
162- const groups = / \/ [ ^ \/ ] + ( .* ) / . exec ( event . path ) || [ null , null ] ;
163- return groups [ 1 ] || '/' ;
162+ const groups : any = / \/ [ ^ \/ ] + ( .* ) / . exec ( event . path ) || [ null , null ]
163+ return groups [ 1 ] || '/'
164164 }
165165
166- return event . path ;
166+ return event . path
167167}
168168
169169const hasReason = ( error : any ) : error is { reason : string } => typeof error . reason === 'string'
@@ -175,73 +175,74 @@ const convertError = (error: ProxyIntegrationError | Error, errorMapping?: Proxy
175175 statusCode : errorMapping [ error . reason ] ,
176176 body : JSON . stringify ( { message : error . message , error : error . reason } ) ,
177177 headers
178- } ;
178+ }
179179 } else if ( hasStatus ( error ) ) {
180180 return {
181181 statusCode : error . status ,
182182 body : JSON . stringify ( { message : error . message , error : error . status } ) ,
183183 headers : addCorsHeaders ( { } )
184- } ;
184+ }
185185 }
186186 try {
187187 return {
188188 statusCode : 500 ,
189- body : JSON . stringify ( { error : " ServerError" , message : `Generic error:${ JSON . stringify ( error ) } ` } ) ,
189+ body : JSON . stringify ( { error : ' ServerError' , message : `Generic error:${ JSON . stringify ( error ) } ` } ) ,
190190 headers : addCorsHeaders ( { } )
191- } ;
192- } catch ( stringifyError ) { }
191+ }
192+ } catch ( stringifyError ) {
193+ }
193194
194195 return {
195196 statusCode : 500 ,
196- body : JSON . stringify ( { error : " ServerError" , message : `Generic error` } )
197- } ;
197+ body : JSON . stringify ( { error : ' ServerError' , message : `Generic error` } )
198+ }
198199}
199200
200201const findMatchingActionConfig = ( httpMethod : string , httpPath : string , routeConfig : ProxyIntegrationConfig ) :
201202 Pick < ProxyIntegrationRoute , 'action' > & ProxyIntegrationParams | null => {
202203
203- const paths : ProxyIntegrationParams [ 'paths' ] = { } ;
204- const matchingMethodRoutes = routeConfig . routes . filter ( route => route . method === httpMethod ) ;
204+ const paths : ProxyIntegrationParams [ 'paths' ] = { }
205+ const matchingMethodRoutes = routeConfig . routes . filter ( route => route . method === httpMethod )
205206 for ( let route of matchingMethodRoutes ) {
206207 if ( routeConfig . debug ) {
207- console . log ( `Examining route ${ route . path } to match ${ httpPath } ` ) ;
208+ console . log ( `Examining route ${ route . path } to match ${ httpPath } ` )
208209 }
209- const pathPartNames = extractPathNames ( route . path ) ;
210- const pathValues = extractPathValues ( route . path , httpPath ) ;
210+ const pathPartNames = extractPathNames ( route . path )
211+ const pathValues = extractPathValues ( route . path , httpPath )
211212 if ( pathValues && pathPartNames ) {
212213 for ( let ii = 0 ; ii < pathValues . length ; ii ++ ) {
213- paths [ pathPartNames [ ii ] ] = decodeURIComponent ( pathValues [ ii ] ) ;
214+ paths [ pathPartNames [ ii ] ] = decodeURIComponent ( pathValues [ ii ] )
214215 }
215216 if ( routeConfig . debug ) {
216- console . log ( `Found matching route ${ route . path } with paths` , paths ) ;
217+ console . log ( `Found matching route ${ route . path } with paths` , paths )
217218 }
218219 return {
219220 action : route . action ,
220221 paths : paths
221- } ;
222+ }
222223 }
223224 }
224225 if ( routeConfig . debug ) {
225- console . log ( `No match for ${ httpPath } ` ) ;
226+ console . log ( `No match for ${ httpPath } ` )
226227 }
227228
228- return null ;
229+ return null
229230}
230231
231232const extractPathValues = ( pathExpression : string , httpPath : string ) => {
232- const pathValueRegex = new RegExp ( '^' + pathExpression . replace ( / : [ \w ] + / g, " ([^/]+)" ) + '$' ) ;
233- const pathValues = pathValueRegex . exec ( httpPath ) ;
234- return pathValues && pathValues . length > 0 ? pathValues . slice ( 1 ) : null ;
233+ const pathValueRegex = new RegExp ( '^' + pathExpression . replace ( / : [ \w ] + / g, ' ([^/]+)' ) + '$' )
234+ const pathValues = pathValueRegex . exec ( httpPath )
235+ return pathValues && pathValues . length > 0 ? pathValues . slice ( 1 ) : null
235236}
236237
237238const extractPathNames = ( pathExpression : string ) => {
238- const pathNameRegex = new RegExp ( '^' + pathExpression . replace ( / : [ \w . ] + / g, " :([\\w]+)" ) + '$' ) ;
239- const pathNames = pathNameRegex . exec ( pathExpression ) ;
240- return pathNames && pathNames . length > 0 ? pathNames . slice ( 1 ) : null ;
239+ const pathNameRegex = new RegExp ( '^' + pathExpression . replace ( / : [ \w . ] + / g, ' :([\\w]+)' ) + '$' )
240+ const pathNames = pathNameRegex . exec ( pathExpression )
241+ return pathNames && pathNames . length > 0 ? pathNames . slice ( 1 ) : null
241242}
242243
243244const isLocalExecution = ( event : ProxyIntegrationEvent ) => {
244245 return event . headers
245246 && event . headers . Host
246- && ( event . headers . Host . startsWith ( 'localhost' ) || event . headers . Host . startsWith ( '127.0.0.1' ) ) ;
247+ && ( event . headers . Host . startsWith ( 'localhost' ) || event . headers . Host . startsWith ( '127.0.0.1' ) )
247248}
0 commit comments