@@ -7,7 +7,7 @@ const path = require("path");
7
7
const getPort = require ( "get-port" ) ;
8
8
const chokidar = require ( "chokidar" ) ;
9
9
const jwtDecode = require ( "jwt-decode" ) ;
10
- // const chalk = require("chalk");
10
+ const chalk = require ( "chalk" ) ;
11
11
const {
12
12
NETLIFYDEVLOG ,
13
13
// NETLIFYDEVWARN,
@@ -27,52 +27,10 @@ function handleErr(err, response) {
27
27
console . log ( `${ NETLIFYDEVERR } Error during invocation: ` , err ) ; // eslint-disable-line no-console
28
28
}
29
29
30
- function createCallback ( response ) {
31
- return function ( err , lambdaResponse ) {
32
- if ( err ) {
33
- return handleErr ( err , response ) ;
34
- }
35
- if ( lambdaResponse === undefined ) {
36
- return handleErr (
37
- "lambda response was undefined. check your function code again." ,
38
- response
39
- ) ;
40
- }
41
- if ( ! Number ( lambdaResponse . statusCode ) ) {
42
- console . log (
43
- `${ NETLIFYDEVERR } Your function response must have a numerical statusCode. You gave: $` ,
44
- lambdaResponse . statusCode
45
- ) ;
46
- return handleErr ( "Incorrect function response statusCode" , response ) ;
47
- }
48
- if ( typeof lambdaResponse . body !== "string" ) {
49
- console . log (
50
- `${ NETLIFYDEVERR } Your function response must have a string body. You gave:` ,
51
- lambdaResponse . body
52
- ) ;
53
- return handleErr ( "Incorrect function response body" , response ) ;
54
- }
55
-
56
- response . statusCode = lambdaResponse . statusCode ;
57
- // eslint-disable-line guard-for-in
58
- for ( const key in lambdaResponse . headers ) {
59
- response . setHeader ( key , lambdaResponse . headers [ key ] ) ;
60
- }
61
- console . log ( { lambdaResponse } ) ;
62
- response . write (
63
- lambdaResponse . isBase64Encoded
64
- ? Buffer . from ( lambdaResponse . body , "base64" )
65
- : lambdaResponse . body
66
- ) ;
67
- response . end ( ) ;
68
- } ;
69
- }
70
-
71
30
// function getHandlerPath(functionPath) {
72
31
// if (functionPath.match(/\.js$/)) {
73
32
// return functionPath;
74
33
// }
75
-
76
34
// return path.join(functionPath, `${path.basename(functionPath)}.js`);
77
35
// }
78
36
@@ -122,7 +80,12 @@ function createHandler(dir) {
122
80
123
81
Object . keys ( functions ) . forEach ( name => {
124
82
const fn = functions [ name ] ;
125
- const clearCache = ( ) => {
83
+ const clearCache = action => ( ) => {
84
+ console . log (
85
+ `${ NETLIFYDEVLOG } function ${ chalk . yellow (
86
+ name
87
+ ) } ${ action } , reloading...`
88
+ ) ; // eslint-disable-line no-console
126
89
const before = module . paths ;
127
90
module . paths = [ fn . moduleDir ] ;
128
91
delete require . cache [ require . resolve ( fn . functionPath ) ] ;
@@ -136,9 +99,9 @@ function createHandler(dir) {
136
99
ignored : / n o d e _ m o d u l e s /
137
100
} ) ;
138
101
fn . watcher
139
- . on ( "add" , clearCache )
140
- . on ( "change" , clearCache )
141
- . on ( "unlink" , clearCache ) ;
102
+ . on ( "add" , clearCache ( "added" ) )
103
+ . on ( "change" , clearCache ( "modified" ) )
104
+ . on ( "unlink" , clearCache ( "deleted" ) ) ;
142
105
} ) ;
143
106
144
107
return function ( request , response ) {
@@ -177,7 +140,7 @@ function createHandler(dir) {
177
140
if ( body instanceof Buffer ) {
178
141
isBase64Encoded = true ;
179
142
body = body . toString ( "base64" ) ;
180
- } else if ( typeof ( body ) === "string" ) {
143
+ } else if ( typeof body === "string" ) {
181
144
// body is already processed as string
182
145
} else {
183
146
body = "" ;
@@ -192,13 +155,64 @@ function createHandler(dir) {
192
155
isBase64Encoded : isBase64Encoded
193
156
} ;
194
157
158
+ let callbackWasCalled = false ;
195
159
const callback = createCallback ( response ) ;
196
160
const promise = handler . handler (
197
161
lambdaRequest ,
198
162
{ clientContext : buildClientContext ( request . headers ) || { } } ,
199
163
callback
200
164
) ;
201
- promiseCallback ( promise , callback ) ;
165
+ /** guard against using BOTH async and callback */
166
+ if ( callbackWasCalled && promise && typeof promise . then === "function" ) {
167
+ throw new Error (
168
+ "Error: your function seems to be using both a callback and returning a promise (aka async function). This is invalid, pick one. (Hint: async!)"
169
+ ) ;
170
+ } else {
171
+ // it is definitely an async function with no callback called, good.
172
+ promiseCallback ( promise , callback ) ;
173
+ }
174
+
175
+ /** need to keep createCallback in scope so we can know if cb was called AND handler is async */
176
+ function createCallback ( response ) {
177
+ return function ( err , lambdaResponse ) {
178
+ callbackWasCalled = true ;
179
+ if ( err ) {
180
+ return handleErr ( err , response ) ;
181
+ }
182
+ if ( lambdaResponse === undefined ) {
183
+ return handleErr (
184
+ "lambda response was undefined. check your function code again." ,
185
+ response
186
+ ) ;
187
+ }
188
+ if ( ! Number ( lambdaResponse . statusCode ) ) {
189
+ console . log (
190
+ `${ NETLIFYDEVERR } Your function response must have a numerical statusCode. You gave: $` ,
191
+ lambdaResponse . statusCode
192
+ ) ;
193
+ return handleErr ( "Incorrect function response statusCode" , response ) ;
194
+ }
195
+ if ( typeof lambdaResponse . body !== "string" ) {
196
+ console . log (
197
+ `${ NETLIFYDEVERR } Your function response must have a string body. You gave:` ,
198
+ lambdaResponse . body
199
+ ) ;
200
+ return handleErr ( "Incorrect function response body" , response ) ;
201
+ }
202
+
203
+ response . statusCode = lambdaResponse . statusCode ;
204
+ // eslint-disable-line guard-for-in
205
+ for ( const key in lambdaResponse . headers ) {
206
+ response . setHeader ( key , lambdaResponse . headers [ key ] ) ;
207
+ }
208
+ response . write (
209
+ lambdaResponse . isBase64Encoded
210
+ ? Buffer . from ( lambdaResponse . body , "base64" )
211
+ : lambdaResponse . body
212
+ ) ;
213
+ response . end ( ) ;
214
+ } ;
215
+ }
202
216
} ;
203
217
}
204
218
@@ -225,7 +239,12 @@ async function serveFunctions(settings) {
225
239
port : assignLoudly ( settings . port , defaultPort )
226
240
} ) ;
227
241
228
- app . use ( bodyParser . text ( { limit : "6mb" , type : [ "text/*" , "application/json" , "multipart/form-data" ] } ) ) ;
242
+ app . use (
243
+ bodyParser . text ( {
244
+ limit : "6mb" ,
245
+ type : [ "text/*" , "application/json" , "multipart/form-data" ]
246
+ } )
247
+ ) ;
229
248
app . use ( bodyParser . raw ( { limit : "6mb" , type : "*/*" } ) ) ;
230
249
app . use (
231
250
expressLogging ( console , {
0 commit comments