@@ -7,31 +7,41 @@ import type {
7
7
import { HeaderMap } from '@apollo/server' ;
8
8
import type { WithRequired } from '@apollo/utils.withrequired' ;
9
9
import type {
10
+ ALBEvent ,
11
+ ALBResult ,
10
12
APIGatewayProxyEvent ,
11
- APIGatewayProxyEventHeaders ,
12
- APIGatewayProxyEventQueryStringParameters ,
13
13
APIGatewayProxyEventV2 ,
14
14
APIGatewayProxyResult ,
15
15
APIGatewayProxyStructuredResultV2 ,
16
16
Context ,
17
17
Handler ,
18
18
} from 'aws-lambda' ;
19
19
20
- export type GatewayEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2 ;
20
+ export type IncomingEvent =
21
+ | APIGatewayProxyEvent
22
+ | APIGatewayProxyEventV2
23
+ | ALBEvent ;
24
+
25
+ /**
26
+ * @deprecated Use {IncomingEvent} instead
27
+ */
28
+ export type GatewayEvent = IncomingEvent ;
21
29
22
30
export interface LambdaContextFunctionArgument {
23
- event : GatewayEvent ;
31
+ event : IncomingEvent ;
24
32
context : Context ;
25
33
}
26
34
27
35
export interface LambdaHandlerOptions < TContext extends BaseContext > {
28
36
context ?: ContextFunction < [ LambdaContextFunctionArgument ] , TContext > ;
29
37
}
30
38
31
- type LambdaHandler = Handler <
32
- GatewayEvent ,
33
- APIGatewayProxyStructuredResultV2 | APIGatewayProxyResult
34
- > ;
39
+ export type HandlerResult =
40
+ | APIGatewayProxyStructuredResultV2
41
+ | APIGatewayProxyResult
42
+ | ALBResult ;
43
+
44
+ type LambdaHandler = Handler < IncomingEvent , HandlerResult > ;
35
45
36
46
export function startServerAndCreateLambdaHandler (
37
47
server : ApolloServer < BaseContext > ,
@@ -62,7 +72,7 @@ export function startServerAndCreateLambdaHandler<TContext extends BaseContext>(
62
72
63
73
return async function ( event , context ) {
64
74
try {
65
- const normalizedEvent = normalizeGatewayEvent ( event ) ;
75
+ const normalizedEvent = normalizeIncomingEvent ( event ) ;
66
76
67
77
const { body, headers, status } = await server . executeHTTPGraphQLRequest ( {
68
78
httpGraphQLRequest : normalizedEvent ,
@@ -90,63 +100,33 @@ export function startServerAndCreateLambdaHandler<TContext extends BaseContext>(
90
100
} ;
91
101
}
92
102
93
- function normalizeGatewayEvent ( event : GatewayEvent ) : HTTPGraphQLRequest {
94
- if ( isV1Event ( event ) ) {
95
- return normalizeV1Event ( event ) ;
96
- }
97
-
98
- if ( isV2Event ( event ) ) {
99
- return normalizeV2Event ( event ) ;
103
+ function normalizeIncomingEvent ( event : IncomingEvent ) : HTTPGraphQLRequest {
104
+ let httpMethod : string ;
105
+ if ( 'httpMethod' in event ) {
106
+ httpMethod = event . httpMethod ;
107
+ } else {
108
+ httpMethod = event . requestContext . http . method ;
100
109
}
101
-
102
- throw Error ( 'Unknown event type' ) ;
103
- }
104
-
105
- function isV1Event ( event : GatewayEvent ) : event is APIGatewayProxyEvent {
106
- // APIGatewayProxyEvent incorrectly omits `version` even though API Gateway v1
107
- // events may include `version: "1.0"`
108
- return (
109
- ! ( 'version' in event ) || ( 'version' in event && event . version === '1.0' )
110
- ) ;
111
- }
112
-
113
- function isV2Event ( event : GatewayEvent ) : event is APIGatewayProxyEventV2 {
114
- return 'version' in event && event . version === '2.0' ;
115
- }
116
-
117
- function normalizeV1Event ( event : APIGatewayProxyEvent ) : HTTPGraphQLRequest {
118
110
const headers = normalizeHeaders ( event . headers ) ;
119
- const body = parseBody ( event . body , headers . get ( 'content-type' ) ) ;
120
- // Single value parameters can be directly added
121
- const searchParams = new URLSearchParams (
122
- normalizeQueryStringParams ( event . queryStringParameters ) ,
123
- ) ;
124
- // Passing a key with an array entry to the constructor yields
125
- // one value in the querystring with %2C as the array was flattened to a string
126
- // Multi values must be appended individually to get the to-spec output
127
- for ( const [ key , values ] of Object . entries (
128
- event . multiValueQueryStringParameters ?? { } ,
129
- ) ) {
130
- for ( const value of values ?? [ ] ) {
131
- searchParams . append ( key , value ) ;
132
- }
111
+ let search : string ;
112
+ if ( 'rawQueryString' in event ) {
113
+ search = event . rawQueryString ;
114
+ } else if ( 'queryStringParameters' in event ) {
115
+ search = normalizeQueryStringParams (
116
+ event . queryStringParameters ,
117
+ event . multiValueQueryStringParameters ,
118
+ ) . toString ( ) ;
119
+ } else {
120
+ throw new Error ( 'Search params not parsable from event' ) ;
133
121
}
134
122
135
- return {
136
- method : event . httpMethod ,
137
- headers,
138
- search : searchParams . toString ( ) ,
139
- body,
140
- } ;
141
- }
123
+ const body = event . body ?? '' ;
142
124
143
- function normalizeV2Event ( event : APIGatewayProxyEventV2 ) : HTTPGraphQLRequest {
144
- const headers = normalizeHeaders ( event . headers ) ;
145
125
return {
146
- method : event . requestContext . http . method ,
126
+ method : httpMethod ,
147
127
headers,
148
- search : event . rawQueryString ,
149
- body : parseBody ( event . body , headers . get ( 'content-type' ) ) ,
128
+ search,
129
+ body : parseBody ( body , headers . get ( 'content-type' ) ) ,
150
130
} ;
151
131
}
152
132
@@ -165,20 +145,31 @@ function parseBody(
165
145
return '' ;
166
146
}
167
147
168
- function normalizeHeaders ( headers : APIGatewayProxyEventHeaders ) : HeaderMap {
148
+ function normalizeHeaders ( headers : IncomingEvent [ 'headers' ] ) : HeaderMap {
169
149
const headerMap = new HeaderMap ( ) ;
170
- for ( const [ key , value ] of Object . entries ( headers ) ) {
150
+ for ( const [ key , value ] of Object . entries ( headers ?? { } ) ) {
171
151
headerMap . set ( key , value ?? '' ) ;
172
152
}
173
153
return headerMap ;
174
154
}
175
155
176
156
function normalizeQueryStringParams (
177
- queryStringParams : APIGatewayProxyEventQueryStringParameters | null ,
178
- ) : Record < string , string > {
179
- const queryStringRecord : Record < string , string > = { } ;
157
+ queryStringParams : Record < string , string | undefined > | null | undefined ,
158
+ multiValueQueryStringParameters :
159
+ | Record < string , string [ ] | undefined >
160
+ | null
161
+ | undefined ,
162
+ ) : URLSearchParams {
163
+ const params = new URLSearchParams ( ) ;
180
164
for ( const [ key , value ] of Object . entries ( queryStringParams ?? { } ) ) {
181
- queryStringRecord [ key ] = value ?? '' ;
165
+ params . append ( key , value ?? '' ) ;
166
+ }
167
+ for ( const [ key , value ] of Object . entries (
168
+ multiValueQueryStringParameters ?? { } ,
169
+ ) ) {
170
+ for ( const v of value ?? [ ] ) {
171
+ params . append ( key , v ) ;
172
+ }
182
173
}
183
- return queryStringRecord ;
174
+ return params ;
184
175
}
0 commit comments