@@ -20,6 +20,8 @@ const SERVER_HANDLER_NAME = '___netlify-server-handler'
20
20
* @property {string } [url] TThe relative path that should be requested. Defaults to '/'
21
21
* @property {Record<string, string> } [headers] The headers used for the invocation
22
22
* @property {Record<string, unknown> } [flags] Feature flags that should be set during the invocation
23
+ *
24
+ * @typedef {Pick<FunctionInvocationOptions, 'env'> } LoadFunctionOptions
23
25
*/
24
26
25
27
/**
@@ -109,76 +111,87 @@ const DEFAULT_FLAGS = {}
109
111
110
112
/**
111
113
* @param {FixtureTestContext } ctx
112
- * @param {FunctionInvocationOptions } options
114
+ * @param {LoadFunctionOptions } options
113
115
*/
114
- export async function loadAndInvokeFunctionImpl (
115
- ctx ,
116
- { headers, httpMethod, flags, url, env } = { } ,
117
- ) {
116
+ export async function loadFunction ( ctx , { env } = { } ) {
118
117
const restoreEnvironment = temporarilySetEnv ( ctx , env )
119
118
120
119
const { handler } = await import (
121
120
'file:///' + join ( ctx . functionDist , SERVER_HANDLER_NAME , '___netlify-entry-point.mjs' )
122
121
)
123
122
124
- let resolveInvocation , rejectInvocation
125
- const invocationPromise = new Promise ( ( resolve , reject ) => {
126
- resolveInvocation = resolve
127
- rejectInvocation = reject
128
- } )
123
+ /**
124
+ * @param {FunctionInvocationOptions } options
125
+ */
126
+ async function invokeFunction ( { headers, httpMethod, flags, url, env : invokeEnv } = { } ) {
127
+ const restoreEnvironment = temporarilySetEnv ( ctx , {
128
+ ...env ,
129
+ ...invokeEnv ,
130
+ } )
129
131
130
- const response = await execute ( {
131
- event : {
132
- headers : {
133
- // 'x-nf-debug-logging': 1,
134
- ...( headers || { } ) ,
132
+ let resolveInvocation , rejectInvocation
133
+ const invocationPromise = new Promise ( ( resolve , reject ) => {
134
+ resolveInvocation = resolve
135
+ rejectInvocation = reject
136
+ } )
137
+
138
+ const response = await execute ( {
139
+ event : {
140
+ headers : {
141
+ // 'x-nf-debug-logging': 1,
142
+ ...( headers || { } ) ,
143
+ } ,
144
+ httpMethod : httpMethod || 'GET' ,
145
+ rawUrl : new URL ( url || '/' , 'https://example.netlify' ) . href ,
146
+ flags : flags ?? DEFAULT_FLAGS ,
135
147
} ,
136
- httpMethod : httpMethod || 'GET' ,
137
- rawUrl : new URL ( url || '/' , 'https://example.netlify' ) . href ,
138
- flags : flags ?? DEFAULT_FLAGS ,
139
- } ,
140
- lambdaFunc : { handler } ,
141
- timeoutMs : 4_000 ,
142
- onInvocationEnd : ( error ) => {
143
- // lambda-local resolve promise return from execute when response is closed
144
- // but we should wait for tracked background work to finish
145
- // before resolving the promise to allow background work to finish
146
- if ( error ) {
147
- rejectInvocation ( error )
148
- } else {
149
- resolveInvocation ( )
150
- }
151
- } ,
152
- } )
148
+ lambdaFunc : { handler } ,
149
+ timeoutMs : 4_000 ,
150
+ onInvocationEnd : ( error ) => {
151
+ // lambda-local resolve promise return from execute when response is closed
152
+ // but we should wait for tracked background work to finish
153
+ // before resolving the promise to allow background work to finish
154
+ if ( error ) {
155
+ rejectInvocation ( error )
156
+ } else {
157
+ resolveInvocation ( )
158
+ }
159
+ } ,
160
+ } )
153
161
154
- await invocationPromise
162
+ await invocationPromise
155
163
156
- if ( ! response ) {
157
- throw new Error ( 'No response from lambda-local' )
158
- }
164
+ if ( ! response ) {
165
+ throw new Error ( 'No response from lambda-local' )
166
+ }
159
167
160
- const responseHeaders = Object . entries ( response . multiValueHeaders || { } ) . reduce (
161
- ( prev , [ key , value ] ) => ( {
162
- ...prev ,
163
- [ key ] : value . length === 1 ? `${ value } ` : value . join ( ', ' ) ,
164
- } ) ,
165
- response . headers || { } ,
166
- )
168
+ const responseHeaders = Object . entries ( response . multiValueHeaders || { } ) . reduce (
169
+ ( prev , [ key , value ] ) => ( {
170
+ ...prev ,
171
+ [ key ] : value . length === 1 ? `${ value } ` : value . join ( ', ' ) ,
172
+ } ) ,
173
+ response . headers || { } ,
174
+ )
167
175
168
- const bodyBuffer = await streamToBuffer ( response . body )
176
+ const bodyBuffer = await streamToBuffer ( response . body )
169
177
170
- restoreEnvironment ( )
178
+ restoreEnvironment ( )
171
179
172
- return {
173
- statusCode : response . statusCode ,
174
- bodyBuffer,
175
- body : bodyBuffer . toString ( 'utf-8' ) ,
176
- headers : responseHeaders ,
177
- isBase64Encoded : response . isBase64Encoded ,
180
+ return {
181
+ statusCode : response . statusCode ,
182
+ bodyBuffer,
183
+ body : bodyBuffer . toString ( 'utf-8' ) ,
184
+ headers : responseHeaders ,
185
+ isBase64Encoded : response . isBase64Encoded ,
186
+ }
178
187
}
188
+
189
+ restoreEnvironment ( )
190
+
191
+ return invokeFunction
179
192
}
180
193
181
194
/**
182
- * @typedef {typeof loadAndInvokeFunctionImpl } InvokeFunction
195
+ * @typedef {Awaited<ReturnType< typeof loadFunction>> } InvokeFunction
183
196
* @typedef {Promise<Awaited<ReturnType<InvokeFunction>>> } InvokeFunctionResult
184
197
*/
0 commit comments