serverless-offline 8.1.0 → 8.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +127 -113
- package/dist/ServerlessOffline.js +98 -26
- package/dist/config/commandOptions.js +4 -0
- package/dist/config/constants.js +1 -1
- package/dist/config/defaultOptions.js +1 -0
- package/dist/events/http/Endpoint.js +27 -9
- package/dist/events/http/Http.js +3 -3
- package/dist/events/http/HttpServer.js +311 -76
- package/dist/events/http/authFunctionNameExtractor.js +14 -8
- package/dist/events/http/authJWTSettingsExtractor.js +14 -7
- package/dist/events/http/createAuthScheme.js +44 -9
- package/dist/events/http/createJWTAuthScheme.js +52 -13
- package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +7 -6
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +18 -7
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +17 -6
- package/dist/events/http/lambda-events/VelocityContext.js +4 -4
- package/dist/events/http/lambda-events/index.js +4 -4
- package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +19 -7
- package/dist/events/schedule/Schedule.js +64 -20
- package/dist/events/websocket/HttpServer.js +24 -7
- package/dist/events/websocket/WebSocket.js +14 -6
- package/dist/events/websocket/WebSocketClients.js +65 -17
- package/dist/events/websocket/WebSocketServer.js +28 -6
- package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +9 -2
- package/dist/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
- package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +28 -5
- package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +5 -5
- package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +1 -1
- package/dist/events/websocket/lambda-events/WebSocketEvent.js +3 -3
- package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +4 -4
- package/dist/lambda/HttpServer.js +34 -10
- package/dist/lambda/Lambda.js +15 -7
- package/dist/lambda/LambdaContext.js +1 -1
- package/dist/lambda/LambdaFunction.js +40 -23
- package/dist/lambda/LambdaFunctionPool.js +9 -8
- package/dist/lambda/handler-runner/HandlerRunner.js +51 -16
- package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +21 -8
- package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +1 -10
- package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +168 -69
- package/dist/lambda/handler-runner/docker-runner/DockerImage.js +21 -5
- package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +4 -4
- package/dist/lambda/handler-runner/go-runner/GoRunner.js +211 -0
- package/dist/lambda/handler-runner/go-runner/index.js +15 -0
- package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +15 -21
- package/dist/lambda/handler-runner/java-runner/JavaRunner.js +26 -14
- package/dist/lambda/handler-runner/python-runner/PythonRunner.js +20 -7
- package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +22 -24
- package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +2 -2
- package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +1 -11
- package/dist/lambda/routes/invocations/InvocationsController.js +37 -11
- package/dist/lambda/routes/invocations/invocationsRoute.js +2 -2
- package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +2 -6
- package/dist/serverlessLog.js +1 -1
- package/dist/utils/checkGoVersion.js +27 -0
- package/dist/utils/getHttpApiCorsConfig.js +18 -5
- package/dist/utils/index.js +24 -16
- package/package.json +85 -37
|
@@ -39,9 +39,9 @@ var _index2 = require("../../utils/index.js");
|
|
|
39
39
|
|
|
40
40
|
var _LambdaProxyIntegrationEventV = _interopRequireDefault(require("./lambda-events/LambdaProxyIntegrationEventV2.js"));
|
|
41
41
|
|
|
42
|
-
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var
|
|
42
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
43
43
|
|
|
44
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
44
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
45
45
|
|
|
46
46
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
47
47
|
|
|
@@ -56,20 +56,20 @@ const {
|
|
|
56
56
|
stringify
|
|
57
57
|
} = JSON;
|
|
58
58
|
|
|
59
|
-
var _lambda = _classPrivateFieldLooseKey("lambda");
|
|
59
|
+
var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
|
|
60
60
|
|
|
61
|
-
var _lastRequestOptions = _classPrivateFieldLooseKey("lastRequestOptions");
|
|
61
|
+
var _lastRequestOptions = /*#__PURE__*/_classPrivateFieldLooseKey("lastRequestOptions");
|
|
62
62
|
|
|
63
|
-
var _options = _classPrivateFieldLooseKey("options");
|
|
63
|
+
var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
|
|
64
64
|
|
|
65
|
-
var _serverless = _classPrivateFieldLooseKey("serverless");
|
|
65
|
+
var _serverless = /*#__PURE__*/_classPrivateFieldLooseKey("serverless");
|
|
66
66
|
|
|
67
|
-
var _server = _classPrivateFieldLooseKey("server");
|
|
67
|
+
var _server = /*#__PURE__*/_classPrivateFieldLooseKey("server");
|
|
68
68
|
|
|
69
|
-
var _terminalInfo = _classPrivateFieldLooseKey("terminalInfo");
|
|
69
|
+
var _terminalInfo = /*#__PURE__*/_classPrivateFieldLooseKey("terminalInfo");
|
|
70
70
|
|
|
71
71
|
class HttpServer {
|
|
72
|
-
constructor(serverless, options, lambda) {
|
|
72
|
+
constructor(serverless, options, lambda, v3Utils) {
|
|
73
73
|
Object.defineProperty(this, _lambda, {
|
|
74
74
|
writable: true,
|
|
75
75
|
value: null
|
|
@@ -98,6 +98,13 @@ class HttpServer {
|
|
|
98
98
|
_classPrivateFieldLooseBase(this, _options)[_options] = options;
|
|
99
99
|
_classPrivateFieldLooseBase(this, _serverless)[_serverless] = serverless;
|
|
100
100
|
|
|
101
|
+
if (v3Utils) {
|
|
102
|
+
this.log = v3Utils.log;
|
|
103
|
+
this.progress = v3Utils.progress;
|
|
104
|
+
this.writeText = v3Utils.writeText;
|
|
105
|
+
this.v3Utils = v3Utils;
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
const {
|
|
102
109
|
enforceSecureCookies,
|
|
103
110
|
host,
|
|
@@ -142,7 +149,7 @@ class HttpServer {
|
|
|
142
149
|
};
|
|
143
150
|
|
|
144
151
|
if (_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi && _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi.cors) {
|
|
145
|
-
const httpApiCors = (0, _index2.getHttpApiCorsConfig)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi.cors);
|
|
152
|
+
const httpApiCors = (0, _index2.getHttpApiCorsConfig)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi.cors, this);
|
|
146
153
|
|
|
147
154
|
if (request.method === 'options') {
|
|
148
155
|
response.statusCode = 204;
|
|
@@ -223,18 +230,30 @@ class HttpServer {
|
|
|
223
230
|
try {
|
|
224
231
|
await _classPrivateFieldLooseBase(this, _server)[_server].start();
|
|
225
232
|
} catch (err) {
|
|
226
|
-
|
|
233
|
+
if (this.log) {
|
|
234
|
+
this.log.error(`Unexpected error while starting serverless-offline server on port ${httpPort}:`, err);
|
|
235
|
+
} else {
|
|
236
|
+
console.error(`Unexpected error while starting serverless-offline server on port ${httpPort}:`, err);
|
|
237
|
+
}
|
|
238
|
+
|
|
227
239
|
process.exit(1);
|
|
228
240
|
} // TODO move the following block
|
|
229
241
|
|
|
230
242
|
|
|
231
243
|
const server = `${httpsProtocol ? 'https' : 'http'}://${host}:${httpPort}`;
|
|
232
|
-
(0, _serverlessLog.default)(`[HTTP] server ready: ${server} 🚀`);
|
|
233
|
-
(0, _serverlessLog.default)(''); // serverlessLog('OpenAPI/Swagger documentation:')
|
|
234
|
-
// logRoute('GET', server, '/documentation')
|
|
235
|
-
// serverlessLog('')
|
|
236
244
|
|
|
237
|
-
(
|
|
245
|
+
if (this.log) {
|
|
246
|
+
this.log.notice(`Server ready: ${server} 🚀`);
|
|
247
|
+
this.log.notice();
|
|
248
|
+
this.log.notice('Enter "rp" to replay the last request');
|
|
249
|
+
} else {
|
|
250
|
+
(0, _serverlessLog.default)(`[HTTP] server ready: ${server} 🚀`);
|
|
251
|
+
(0, _serverlessLog.default)(''); // serverlessLog('OpenAPI/Swagger documentation:')
|
|
252
|
+
// logRoute('GET', server, '/documentation')
|
|
253
|
+
// serverlessLog('')
|
|
254
|
+
|
|
255
|
+
(0, _serverlessLog.default)('Enter "rp" to replay the last request');
|
|
256
|
+
}
|
|
238
257
|
|
|
239
258
|
if (process.env.NODE_ENV !== 'test') {
|
|
240
259
|
process.openStdin().addListener('data', data => {
|
|
@@ -259,7 +278,11 @@ class HttpServer {
|
|
|
259
278
|
try {
|
|
260
279
|
await _classPrivateFieldLooseBase(this, _server)[_server].register([_h2o.default]);
|
|
261
280
|
} catch (err) {
|
|
262
|
-
(
|
|
281
|
+
if (this.log) {
|
|
282
|
+
this.log.error(err);
|
|
283
|
+
} else {
|
|
284
|
+
(0, _serverlessLog.default)(err);
|
|
285
|
+
}
|
|
263
286
|
}
|
|
264
287
|
} // // TODO unused:
|
|
265
288
|
// get server() {
|
|
@@ -269,17 +292,26 @@ class HttpServer {
|
|
|
269
292
|
|
|
270
293
|
_printBlankLine() {
|
|
271
294
|
if (process.env.NODE_ENV !== 'test') {
|
|
272
|
-
|
|
295
|
+
if (this.log) {
|
|
296
|
+
this.log.notice();
|
|
297
|
+
} else {
|
|
298
|
+
console.log();
|
|
299
|
+
}
|
|
273
300
|
}
|
|
274
301
|
}
|
|
275
302
|
|
|
276
303
|
_logPluginIssue() {
|
|
277
|
-
(
|
|
278
|
-
|
|
304
|
+
if (this.log) {
|
|
305
|
+
this.log.notice('If you think this is an issue with the plugin please submit it, thanks!\nhttps://github.com/dherault/serverless-offline/issues');
|
|
306
|
+
this.log.notice();
|
|
307
|
+
} else {
|
|
308
|
+
(0, _serverlessLog.default)('If you think this is an issue with the plugin please submit it, thanks!');
|
|
309
|
+
(0, _serverlessLog.default)('https://github.com/dherault/serverless-offline/issues');
|
|
310
|
+
}
|
|
279
311
|
}
|
|
280
312
|
|
|
281
313
|
_extractJWTAuthSettings(endpoint) {
|
|
282
|
-
const result = (0, _authJWTSettingsExtractor.default)(endpoint, _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider, _classPrivateFieldLooseBase(this, _options)[_options].ignoreJWTSignature);
|
|
314
|
+
const result = (0, _authJWTSettingsExtractor.default)(endpoint, _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider, _classPrivateFieldLooseBase(this, _options)[_options].ignoreJWTSignature, this);
|
|
283
315
|
return result.unsupportedAuth ? null : result;
|
|
284
316
|
}
|
|
285
317
|
|
|
@@ -300,16 +332,26 @@ class HttpServer {
|
|
|
300
332
|
return null;
|
|
301
333
|
}
|
|
302
334
|
|
|
303
|
-
(
|
|
335
|
+
if (this.log) {
|
|
336
|
+
this.log.notice(`Configuring JWT Authorization: ${method} ${path}`);
|
|
337
|
+
} else {
|
|
338
|
+
(0, _serverlessLog.default)(`Configuring JWT Authorization: ${method} ${path}`);
|
|
339
|
+
} // Create a unique scheme per endpoint
|
|
304
340
|
// This allows the methodArn on the event property to be set appropriately
|
|
305
341
|
|
|
342
|
+
|
|
306
343
|
const authKey = `${functionKey}-${jwtSettings.authorizerName}-${method}-${path}`;
|
|
307
344
|
const authSchemeName = `scheme-${authKey}`;
|
|
308
345
|
const authStrategyName = `strategy-${authKey}`; // set strategy name for the route config
|
|
309
346
|
|
|
310
|
-
(
|
|
347
|
+
if (this.log) {
|
|
348
|
+
this.log.debug(`Creating Authorization scheme for ${authKey}`);
|
|
349
|
+
} else {
|
|
350
|
+
(0, _debugLog.default)(`Creating Authorization scheme for ${authKey}`);
|
|
351
|
+
} // Create the Auth Scheme for the endpoint
|
|
352
|
+
|
|
311
353
|
|
|
312
|
-
const scheme = (0, _createJWTAuthScheme.default)(jwtSettings); // Set the auth scheme and strategy on the server
|
|
354
|
+
const scheme = (0, _createJWTAuthScheme.default)(jwtSettings, this); // Set the auth scheme and strategy on the server
|
|
313
355
|
|
|
314
356
|
_classPrivateFieldLooseBase(this, _server)[_server].auth.scheme(authSchemeName, scheme);
|
|
315
357
|
|
|
@@ -319,7 +361,7 @@ class HttpServer {
|
|
|
319
361
|
}
|
|
320
362
|
|
|
321
363
|
_extractAuthFunctionName(endpoint) {
|
|
322
|
-
const result = (0, _authFunctionNameExtractor.default)(endpoint);
|
|
364
|
+
const result = (0, _authFunctionNameExtractor.default)(endpoint, null, this);
|
|
323
365
|
return result.unsupportedAuth ? null : result.authorizerName;
|
|
324
366
|
}
|
|
325
367
|
|
|
@@ -334,11 +376,24 @@ class HttpServer {
|
|
|
334
376
|
return null;
|
|
335
377
|
}
|
|
336
378
|
|
|
337
|
-
(
|
|
379
|
+
if (this.log) {
|
|
380
|
+
this.log.notice(`Configuring Authorization: ${path} ${authFunctionName}`);
|
|
381
|
+
} else {
|
|
382
|
+
(0, _serverlessLog.default)(`Configuring Authorization: ${path} ${authFunctionName}`);
|
|
383
|
+
}
|
|
338
384
|
|
|
339
385
|
const authFunction = _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.getFunction(authFunctionName);
|
|
340
386
|
|
|
341
|
-
if (!authFunction)
|
|
387
|
+
if (!authFunction) {
|
|
388
|
+
if (this.log) {
|
|
389
|
+
this.log.error(`Authorization function ${authFunctionName} does not exist`);
|
|
390
|
+
} else {
|
|
391
|
+
(0, _serverlessLog.default)(`WARNING: Authorization function ${authFunctionName} does not exist`);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
|
|
342
397
|
const authorizerOptions = {
|
|
343
398
|
identitySource: 'method.request.header.Authorization',
|
|
344
399
|
identityValidationExpression: '(.*)',
|
|
@@ -357,9 +412,14 @@ class HttpServer {
|
|
|
357
412
|
const authSchemeName = `scheme-${authKey}`;
|
|
358
413
|
const authStrategyName = `strategy-${authKey}`; // set strategy name for the route config
|
|
359
414
|
|
|
360
|
-
(
|
|
415
|
+
if (this.log) {
|
|
416
|
+
this.log.debug(`Creating Authorization scheme for ${authKey}`);
|
|
417
|
+
} else {
|
|
418
|
+
(0, _debugLog.default)(`Creating Authorization scheme for ${authKey}`);
|
|
419
|
+
} // Create the Auth Scheme for the endpoint
|
|
420
|
+
|
|
361
421
|
|
|
362
|
-
const scheme = (0, _createAuthScheme.default)(authorizerOptions, _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider, _classPrivateFieldLooseBase(this, _lambda)[_lambda]); // Set the auth scheme and strategy on the server
|
|
422
|
+
const scheme = (0, _createAuthScheme.default)(authorizerOptions, _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider, _classPrivateFieldLooseBase(this, _lambda)[_lambda], this); // Set the auth scheme and strategy on the server
|
|
363
423
|
|
|
364
424
|
_classPrivateFieldLooseBase(this, _server)[_server].auth.scheme(authSchemeName, scheme);
|
|
365
425
|
|
|
@@ -395,7 +455,7 @@ class HttpServer {
|
|
|
395
455
|
hapiPath = (0, _index2.generateHapiPath)(path, _classPrivateFieldLooseBase(this, _options)[_options], _classPrivateFieldLooseBase(this, _serverless)[_serverless]);
|
|
396
456
|
}
|
|
397
457
|
|
|
398
|
-
const endpoint = new _Endpoint.default((0, _path.join)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].config.servicePath, handlerPath), httpEvent);
|
|
458
|
+
const endpoint = new _Endpoint.default((0, _path.join)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].config.servicePath, handlerPath), httpEvent, this.v3Utils);
|
|
399
459
|
const stage = endpoint.isHttpApi ? '$default' : _classPrivateFieldLooseBase(this, _options)[_options].stage || _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.stage;
|
|
400
460
|
const protectedRoutes = [];
|
|
401
461
|
|
|
@@ -431,7 +491,7 @@ class HttpServer {
|
|
|
431
491
|
origin: endpoint.cors.origins || _classPrivateFieldLooseBase(this, _options)[_options].corsConfig.origin
|
|
432
492
|
};
|
|
433
493
|
} else if (_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi && _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi.cors) {
|
|
434
|
-
const httpApiCors = (0, _index2.getHttpApiCorsConfig)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi.cors);
|
|
494
|
+
const httpApiCors = (0, _index2.getHttpApiCorsConfig)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.provider.httpApi.cors, this);
|
|
435
495
|
cors = {
|
|
436
496
|
origin: httpApiCors.allowedOrigins || [],
|
|
437
497
|
credentials: httpApiCors.allowCredentials,
|
|
@@ -460,7 +520,12 @@ class HttpServer {
|
|
|
460
520
|
// for more details, check https://github.com/dherault/serverless-offline/issues/204
|
|
461
521
|
|
|
462
522
|
if (hapiMethod === 'HEAD') {
|
|
463
|
-
(
|
|
523
|
+
if (this.log) {
|
|
524
|
+
this.log.notice('HEAD method event detected. Skipping HAPI server route mapping');
|
|
525
|
+
} else {
|
|
526
|
+
(0, _serverlessLog.default)('HEAD method event detected. Skipping HAPI server route mapping ...');
|
|
527
|
+
}
|
|
528
|
+
|
|
464
529
|
return;
|
|
465
530
|
}
|
|
466
531
|
|
|
@@ -499,7 +564,13 @@ class HttpServer {
|
|
|
499
564
|
|
|
500
565
|
this._printBlankLine();
|
|
501
566
|
|
|
502
|
-
(
|
|
567
|
+
if (this.log) {
|
|
568
|
+
this.log.notice();
|
|
569
|
+
this.log.notice(`${method} ${request.path} (λ: ${functionKey})`);
|
|
570
|
+
} else {
|
|
571
|
+
(0, _serverlessLog.default)(`${method} ${request.path} (λ: ${functionKey})`);
|
|
572
|
+
} // Check for APIKey
|
|
573
|
+
|
|
503
574
|
|
|
504
575
|
if ((protectedRoutes.includes(`${hapiMethod}#${hapiPath}`) || protectedRoutes.includes(`ANY#${hapiPath}`)) && !_classPrivateFieldLooseBase(this, _options)[_options].noAuth) {
|
|
505
576
|
const errorResponse = () => h.response({
|
|
@@ -523,7 +594,12 @@ class HttpServer {
|
|
|
523
594
|
return errorResponse();
|
|
524
595
|
}
|
|
525
596
|
} else {
|
|
526
|
-
(
|
|
597
|
+
if (this.log) {
|
|
598
|
+
this.log.debug(`Missing x-api-key on private function ${functionKey}`);
|
|
599
|
+
} else {
|
|
600
|
+
(0, _debugLog.default)(`Missing x-api-key on private function ${functionKey}`);
|
|
601
|
+
}
|
|
602
|
+
|
|
527
603
|
return errorResponse();
|
|
528
604
|
}
|
|
529
605
|
}
|
|
@@ -550,17 +626,32 @@ class HttpServer {
|
|
|
550
626
|
|
|
551
627
|
request.payload = parse(request.payload);
|
|
552
628
|
} catch (err) {
|
|
553
|
-
(
|
|
629
|
+
if (this.log) {
|
|
630
|
+
this.log.debug('error in converting request.payload to JSON:', err);
|
|
631
|
+
} else {
|
|
632
|
+
(0, _debugLog.default)('error in converting request.payload to JSON:', err);
|
|
633
|
+
}
|
|
554
634
|
}
|
|
555
635
|
}
|
|
556
636
|
|
|
557
|
-
(
|
|
558
|
-
|
|
559
|
-
|
|
637
|
+
if (this.log) {
|
|
638
|
+
this.log.debug('contentType:', contentType);
|
|
639
|
+
this.log.debug('requestTemplate:', requestTemplate);
|
|
640
|
+
this.log.debug('payload:', request.payload);
|
|
641
|
+
} else {
|
|
642
|
+
(0, _debugLog.default)('contentType:', contentType);
|
|
643
|
+
(0, _debugLog.default)('requestTemplate:', requestTemplate);
|
|
644
|
+
(0, _debugLog.default)('payload:', request.payload);
|
|
645
|
+
}
|
|
560
646
|
/* REQUEST PAYLOAD SCHEMA VALIDATION */
|
|
561
647
|
|
|
648
|
+
|
|
562
649
|
if (schema) {
|
|
563
|
-
(
|
|
650
|
+
if (this.log) {
|
|
651
|
+
this.log.debug('schema:', schema);
|
|
652
|
+
} else {
|
|
653
|
+
(0, _debugLog.default)('schema:', schema);
|
|
654
|
+
}
|
|
564
655
|
|
|
565
656
|
try {
|
|
566
657
|
_payloadSchemaValidator.default.validate(schema, request.payload);
|
|
@@ -576,8 +667,13 @@ class HttpServer {
|
|
|
576
667
|
if (integration === 'AWS') {
|
|
577
668
|
if (requestTemplate) {
|
|
578
669
|
try {
|
|
579
|
-
(
|
|
580
|
-
|
|
670
|
+
if (this.log) {
|
|
671
|
+
this.log.debug('_____ REQUEST TEMPLATE PROCESSING _____');
|
|
672
|
+
} else {
|
|
673
|
+
(0, _debugLog.default)('_____ REQUEST TEMPLATE PROCESSING _____');
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
event = new _index.LambdaIntegrationEvent(request, stage, requestTemplate, requestPath, this.v3Utils).create();
|
|
581
677
|
} catch (err) {
|
|
582
678
|
return this._reply502(response, `Error while parsing template "${contentType}" for ${functionKey}`, err);
|
|
583
679
|
}
|
|
@@ -586,11 +682,15 @@ class HttpServer {
|
|
|
586
682
|
}
|
|
587
683
|
} else if (integration === 'AWS_PROXY') {
|
|
588
684
|
const stageVariables = _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.custom ? _classPrivateFieldLooseBase(this, _serverless)[_serverless].service.custom.stageVariables : null;
|
|
589
|
-
const lambdaProxyIntegrationEvent = endpoint.isHttpApi && endpoint.payload === '2.0' ? new _LambdaProxyIntegrationEventV.default(request, stage, endpoint.routeKey, stageVariables) : new _index.LambdaProxyIntegrationEvent(request, stage, requestPath, stageVariables, endpoint.isHttpApi ? endpoint.routeKey : null);
|
|
685
|
+
const lambdaProxyIntegrationEvent = endpoint.isHttpApi && endpoint.payload === '2.0' ? new _LambdaProxyIntegrationEventV.default(request, stage, endpoint.routeKey, stageVariables, this.v3Utils) : new _index.LambdaProxyIntegrationEvent(request, stage, requestPath, stageVariables, endpoint.isHttpApi ? endpoint.routeKey : null, this.v3Utils);
|
|
590
686
|
event = lambdaProxyIntegrationEvent.create();
|
|
591
687
|
}
|
|
592
688
|
|
|
593
|
-
(
|
|
689
|
+
if (this.log) {
|
|
690
|
+
this.log.debug('event:', event);
|
|
691
|
+
} else {
|
|
692
|
+
(0, _debugLog.default)('event:', event);
|
|
693
|
+
}
|
|
594
694
|
|
|
595
695
|
const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(functionKey);
|
|
596
696
|
|
|
@@ -606,7 +706,12 @@ class HttpServer {
|
|
|
606
706
|
// Everything in this block happens once the lambda function has resolved
|
|
607
707
|
|
|
608
708
|
|
|
609
|
-
(
|
|
709
|
+
if (this.log) {
|
|
710
|
+
this.log.debug('_____ HANDLER RESOLVED _____');
|
|
711
|
+
} else {
|
|
712
|
+
(0, _debugLog.default)('_____ HANDLER RESOLVED _____');
|
|
713
|
+
}
|
|
714
|
+
|
|
610
715
|
let responseName = 'default';
|
|
611
716
|
const {
|
|
612
717
|
contentHandling,
|
|
@@ -645,10 +750,19 @@ class HttpServer {
|
|
|
645
750
|
errorType: err.constructor.name,
|
|
646
751
|
stackTrace: this._getArrayStackTrace(err.stack)
|
|
647
752
|
};
|
|
648
|
-
|
|
753
|
+
|
|
754
|
+
if (this.log) {
|
|
755
|
+
this.log.error(errorMessage);
|
|
756
|
+
} else {
|
|
757
|
+
(0, _serverlessLog.default)(`Failure: ${errorMessage}`);
|
|
758
|
+
}
|
|
649
759
|
|
|
650
760
|
if (!_classPrivateFieldLooseBase(this, _options)[_options].hideStackTraces) {
|
|
651
|
-
|
|
761
|
+
if (this.log) {
|
|
762
|
+
this.log.error(err.stack);
|
|
763
|
+
} else {
|
|
764
|
+
console.error(err.stack);
|
|
765
|
+
}
|
|
652
766
|
}
|
|
653
767
|
|
|
654
768
|
for (const [key, value] of Object.entries(endpoint.responses)) {
|
|
@@ -659,7 +773,12 @@ class HttpServer {
|
|
|
659
773
|
}
|
|
660
774
|
}
|
|
661
775
|
|
|
662
|
-
(
|
|
776
|
+
if (this.log) {
|
|
777
|
+
this.log.debug(`Using response '${responseName}'`);
|
|
778
|
+
} else {
|
|
779
|
+
(0, _debugLog.default)(`Using response '${responseName}'`);
|
|
780
|
+
}
|
|
781
|
+
|
|
663
782
|
const chosenResponse = endpoint.responses[responseName];
|
|
664
783
|
/* RESPONSE PARAMETERS PROCCESSING */
|
|
665
784
|
|
|
@@ -669,24 +788,46 @@ class HttpServer {
|
|
|
669
788
|
|
|
670
789
|
if (responseParameters) {
|
|
671
790
|
const responseParametersKeys = Object.keys(responseParameters);
|
|
672
|
-
|
|
673
|
-
(
|
|
791
|
+
|
|
792
|
+
if (this.log) {
|
|
793
|
+
this.log.debug('_____ RESPONSE PARAMETERS PROCCESSING _____');
|
|
794
|
+
this.log.debug(`Found ${responseParametersKeys.length} responseParameters for '${responseName}' response`);
|
|
795
|
+
} else {
|
|
796
|
+
(0, _debugLog.default)('_____ RESPONSE PARAMETERS PROCCESSING _____');
|
|
797
|
+
(0, _debugLog.default)();
|
|
798
|
+
} // responseParameters use the following shape: "key": "value"
|
|
799
|
+
|
|
674
800
|
|
|
675
801
|
Object.entries(responseParameters).forEach(([key, value]) => {
|
|
676
802
|
const keyArray = key.split('.'); // eg: "method.response.header.location"
|
|
677
803
|
|
|
678
804
|
const valueArray = value.split('.'); // eg: "integration.response.body.redirect.url"
|
|
679
805
|
|
|
680
|
-
(
|
|
806
|
+
if (this.log) {
|
|
807
|
+
this.log.debug(`Processing responseParameter "${key}": "${value}"`);
|
|
808
|
+
} else {
|
|
809
|
+
(0, _debugLog.default)(`Processing responseParameter "${key}": "${value}"`);
|
|
810
|
+
} // For now the plugin only supports modifying headers
|
|
811
|
+
|
|
681
812
|
|
|
682
813
|
if (key.startsWith('method.response.header') && keyArray[3]) {
|
|
683
814
|
const headerName = keyArray.slice(3).join('.');
|
|
684
815
|
let headerValue;
|
|
685
|
-
|
|
816
|
+
|
|
817
|
+
if (this.log) {
|
|
818
|
+
this.log.debug('Found header in left-hand:', headerName);
|
|
819
|
+
} else {
|
|
820
|
+
(0, _debugLog.default)('Found header in left-hand:', headerName);
|
|
821
|
+
}
|
|
686
822
|
|
|
687
823
|
if (value.startsWith('integration.response')) {
|
|
688
824
|
if (valueArray[2] === 'body') {
|
|
689
|
-
(
|
|
825
|
+
if (this.log) {
|
|
826
|
+
this.log.debug('Found body in right-hand');
|
|
827
|
+
} else {
|
|
828
|
+
(0, _debugLog.default)('Found body in right-hand');
|
|
829
|
+
}
|
|
830
|
+
|
|
690
831
|
headerValue = valueArray[3] ? (0, _index2.jsonPath)(result, valueArray.slice(3).join('.')) : result;
|
|
691
832
|
|
|
692
833
|
if (typeof headerValue === 'undefined' || headerValue === null) {
|
|
@@ -697,8 +838,13 @@ class HttpServer {
|
|
|
697
838
|
} else {
|
|
698
839
|
this._printBlankLine();
|
|
699
840
|
|
|
700
|
-
(
|
|
701
|
-
|
|
841
|
+
if (this.log) {
|
|
842
|
+
this.log.warning();
|
|
843
|
+
this.log.warning(`Offline plugin only supports "integration.response.body[.JSON_path]" right-hand responseParameter. Found "${value}" (for "${key}"") instead. Skipping.`);
|
|
844
|
+
} else {
|
|
845
|
+
(0, _serverlessLog.default)(`Warning: while processing responseParameter "${key}": "${value}"`);
|
|
846
|
+
(0, _serverlessLog.default)(`Offline plugin only supports "integration.response.body[.JSON_path]" right-hand responseParameter. Found "${value}" instead. Skipping.`);
|
|
847
|
+
}
|
|
702
848
|
|
|
703
849
|
this._logPluginIssue();
|
|
704
850
|
|
|
@@ -710,16 +856,30 @@ class HttpServer {
|
|
|
710
856
|
|
|
711
857
|
|
|
712
858
|
if (headerValue === '') {
|
|
713
|
-
(
|
|
859
|
+
if (this.log) {
|
|
860
|
+
this.log.warning(`Empty value for responseParameter "${key}": "${value}", it won't be set`);
|
|
861
|
+
} else {
|
|
862
|
+
(0, _serverlessLog.default)(`Warning: empty value for responseParameter "${key}": "${value}", it won't be set`);
|
|
863
|
+
}
|
|
714
864
|
} else {
|
|
715
|
-
(
|
|
865
|
+
if (this.log) {
|
|
866
|
+
this.log.debug(`Will assign "${headerValue}" to header "${headerName}"`);
|
|
867
|
+
} else {
|
|
868
|
+
(0, _debugLog.default)(`Will assign "${headerValue}" to header "${headerName}"`);
|
|
869
|
+
}
|
|
870
|
+
|
|
716
871
|
response.header(headerName, headerValue);
|
|
717
872
|
}
|
|
718
873
|
} else {
|
|
719
874
|
this._printBlankLine();
|
|
720
875
|
|
|
721
|
-
(
|
|
722
|
-
|
|
876
|
+
if (this.log) {
|
|
877
|
+
this.log.warning();
|
|
878
|
+
this.log.warning(`Offline plugin only supports "method.response.header.PARAM_NAME" left-hand responseParameter. Found "${key}" instead. Skipping.`);
|
|
879
|
+
} else {
|
|
880
|
+
(0, _serverlessLog.default)(`Warning: while processing responseParameter "${key}": "${value}"`);
|
|
881
|
+
(0, _serverlessLog.default)(`Offline plugin only supports "method.response.header.PARAM_NAME" left-hand responseParameter. Found "${key}" instead. Skipping.`);
|
|
882
|
+
}
|
|
723
883
|
|
|
724
884
|
this._logPluginIssue();
|
|
725
885
|
|
|
@@ -748,17 +908,26 @@ class HttpServer {
|
|
|
748
908
|
const responseTemplate = responseTemplates[responseContentType];
|
|
749
909
|
|
|
750
910
|
if (responseTemplate && responseTemplate !== '\n') {
|
|
751
|
-
(
|
|
752
|
-
|
|
911
|
+
if (this.log) {
|
|
912
|
+
this.log.debug('_____ RESPONSE TEMPLATE PROCCESSING _____');
|
|
913
|
+
this.log.debug(`Using responseTemplate '${responseContentType}'`);
|
|
914
|
+
} else {
|
|
915
|
+
(0, _debugLog.default)('_____ RESPONSE TEMPLATE PROCCESSING _____');
|
|
916
|
+
(0, _debugLog.default)(`Using responseTemplate '${responseContentType}'`);
|
|
917
|
+
}
|
|
753
918
|
|
|
754
919
|
try {
|
|
755
920
|
const reponseContext = new _index.VelocityContext(request, stage, result).getContext();
|
|
756
921
|
result = (0, _index.renderVelocityTemplateObject)({
|
|
757
922
|
root: responseTemplate
|
|
758
|
-
}, reponseContext).root;
|
|
923
|
+
}, reponseContext, this.v3Utils).root;
|
|
759
924
|
} catch (error) {
|
|
760
|
-
(
|
|
761
|
-
|
|
925
|
+
if (this.log) {
|
|
926
|
+
this.log.error(`Error while parsing responseTemplate '${responseContentType}' for lambda ${functionKey}:\n${error.stack}`);
|
|
927
|
+
} else {
|
|
928
|
+
(0, _serverlessLog.default)(`Error while parsing responseTemplate '${responseContentType}' for lambda ${functionKey}:`);
|
|
929
|
+
console.log(error.stack);
|
|
930
|
+
}
|
|
762
931
|
}
|
|
763
932
|
}
|
|
764
933
|
}
|
|
@@ -775,7 +944,12 @@ class HttpServer {
|
|
|
775
944
|
if (!chosenResponse.statusCode) {
|
|
776
945
|
this._printBlankLine();
|
|
777
946
|
|
|
778
|
-
(
|
|
947
|
+
if (this.log) {
|
|
948
|
+
this.log.warning();
|
|
949
|
+
this.log.warning(`No statusCode found for response "${responseName}".`);
|
|
950
|
+
} else {
|
|
951
|
+
(0, _serverlessLog.default)(`Warning: No statusCode found for response "${responseName}".`);
|
|
952
|
+
}
|
|
779
953
|
}
|
|
780
954
|
|
|
781
955
|
response.header('Content-Type', responseContentType, {
|
|
@@ -830,7 +1004,11 @@ class HttpServer {
|
|
|
830
1004
|
});
|
|
831
1005
|
}
|
|
832
1006
|
|
|
833
|
-
(
|
|
1007
|
+
if (this.log) {
|
|
1008
|
+
this.log.debug('headers', headers);
|
|
1009
|
+
} else {
|
|
1010
|
+
(0, _debugLog.default)('headers', headers);
|
|
1011
|
+
}
|
|
834
1012
|
|
|
835
1013
|
const parseCookies = headerValue => {
|
|
836
1014
|
const cookieName = headerValue.slice(0, headerValue.indexOf('='));
|
|
@@ -888,7 +1066,13 @@ class HttpServer {
|
|
|
888
1066
|
whatToLog = stringify(result);
|
|
889
1067
|
} catch (error) {// nothing
|
|
890
1068
|
} finally {
|
|
891
|
-
if (_classPrivateFieldLooseBase(this, _options)[_options].printOutput)
|
|
1069
|
+
if (_classPrivateFieldLooseBase(this, _options)[_options].printOutput) {
|
|
1070
|
+
if (this.log) {
|
|
1071
|
+
this.log.notice(err ? `Replying ${statusCode}` : `[${statusCode}] ${whatToLog}`);
|
|
1072
|
+
} else {
|
|
1073
|
+
(0, _serverlessLog.default)(err ? `Replying ${statusCode}` : `[${statusCode}] ${whatToLog}`);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
892
1076
|
} // Bon voyage!
|
|
893
1077
|
|
|
894
1078
|
|
|
@@ -905,7 +1089,13 @@ class HttpServer {
|
|
|
905
1089
|
|
|
906
1090
|
_replyError(statusCode, response, message, error) {
|
|
907
1091
|
(0, _serverlessLog.default)(message);
|
|
908
|
-
|
|
1092
|
+
|
|
1093
|
+
if (this.log) {
|
|
1094
|
+
this.log.error(error);
|
|
1095
|
+
} else {
|
|
1096
|
+
console.error(error);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
909
1099
|
response.header('Content-Type', 'application/json');
|
|
910
1100
|
response.statusCode = statusCode;
|
|
911
1101
|
response.source = {
|
|
@@ -942,7 +1132,13 @@ class HttpServer {
|
|
|
942
1132
|
|
|
943
1133
|
this._printBlankLine();
|
|
944
1134
|
|
|
945
|
-
(
|
|
1135
|
+
if (this.log) {
|
|
1136
|
+
this.log.notice();
|
|
1137
|
+
this.log.notice('Routes defined in resources:');
|
|
1138
|
+
} else {
|
|
1139
|
+
(0, _serverlessLog.default)('Routes defined in resources:');
|
|
1140
|
+
}
|
|
1141
|
+
|
|
946
1142
|
Object.entries(resourceRoutes).forEach(([methodId, resourceRoutesObj]) => {
|
|
947
1143
|
const {
|
|
948
1144
|
isProxy,
|
|
@@ -952,12 +1148,22 @@ class HttpServer {
|
|
|
952
1148
|
} = resourceRoutesObj;
|
|
953
1149
|
|
|
954
1150
|
if (!isProxy) {
|
|
955
|
-
(
|
|
1151
|
+
if (this.log) {
|
|
1152
|
+
this.log.warning(`Only HTTP_PROXY is supported. Path '${pathResource}' is ignored.`);
|
|
1153
|
+
} else {
|
|
1154
|
+
(0, _serverlessLog.default)(`WARNING: Only HTTP_PROXY is supported. Path '${pathResource}' is ignored.`);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
956
1157
|
return;
|
|
957
1158
|
}
|
|
958
1159
|
|
|
959
1160
|
if (!pathResource) {
|
|
960
|
-
(
|
|
1161
|
+
if (this.log) {
|
|
1162
|
+
this.log.warning(`Could not resolve path for '${methodId}'.`);
|
|
1163
|
+
} else {
|
|
1164
|
+
(0, _serverlessLog.default)(`WARNING: Could not resolve path for '${methodId}'.`);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
961
1167
|
return;
|
|
962
1168
|
}
|
|
963
1169
|
|
|
@@ -966,7 +1172,12 @@ class HttpServer {
|
|
|
966
1172
|
const proxyUriInUse = proxyUriOverwrite.Uri || proxyUri;
|
|
967
1173
|
|
|
968
1174
|
if (!proxyUriInUse) {
|
|
969
|
-
(
|
|
1175
|
+
if (this.log) {
|
|
1176
|
+
this.log.warning(`Could not load Proxy Uri for '${methodId}'`);
|
|
1177
|
+
} else {
|
|
1178
|
+
(0, _serverlessLog.default)(`WARNING: Could not load Proxy Uri for '${methodId}'`);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
970
1181
|
return;
|
|
971
1182
|
}
|
|
972
1183
|
|
|
@@ -985,7 +1196,12 @@ class HttpServer {
|
|
|
985
1196
|
// for more details, check https://github.com/dherault/serverless-offline/issues/204
|
|
986
1197
|
|
|
987
1198
|
if (hapiMethod === 'HEAD') {
|
|
988
|
-
(
|
|
1199
|
+
if (this.log) {
|
|
1200
|
+
this.log.notice('HEAD method event detected. Skipping HAPI server route mapping');
|
|
1201
|
+
} else {
|
|
1202
|
+
(0, _serverlessLog.default)('HEAD method event detected. Skipping HAPI server route mapping ...');
|
|
1203
|
+
}
|
|
1204
|
+
|
|
989
1205
|
return;
|
|
990
1206
|
}
|
|
991
1207
|
|
|
@@ -995,8 +1211,16 @@ class HttpServer {
|
|
|
995
1211
|
};
|
|
996
1212
|
}
|
|
997
1213
|
|
|
998
|
-
(
|
|
1214
|
+
if (this.log) {
|
|
1215
|
+
this.log.notice(`${method} ${hapiPath} -> ${proxyUriInUse}`);
|
|
1216
|
+
} else {
|
|
1217
|
+
(0, _serverlessLog.default)(`${method} ${hapiPath} -> ${proxyUriInUse}`);
|
|
1218
|
+
} // hapiOptions.tags = ['api']
|
|
999
1219
|
|
|
1220
|
+
|
|
1221
|
+
const {
|
|
1222
|
+
log
|
|
1223
|
+
} = this;
|
|
1000
1224
|
const route = {
|
|
1001
1225
|
handler(request, h) {
|
|
1002
1226
|
const {
|
|
@@ -1011,7 +1235,12 @@ class HttpServer {
|
|
|
1011
1235
|
resultUri += request.url.search; // search is empty string by default
|
|
1012
1236
|
}
|
|
1013
1237
|
|
|
1014
|
-
(
|
|
1238
|
+
if (log) {
|
|
1239
|
+
log.notice(`PROXY ${request.method} ${request.url.pathname} -> ${resultUri}`);
|
|
1240
|
+
} else {
|
|
1241
|
+
(0, _serverlessLog.default)(`PROXY ${request.method} ${request.url.pathname} -> ${resultUri}`);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1015
1244
|
return h.proxy({
|
|
1016
1245
|
passThrough: true,
|
|
1017
1246
|
uri: resultUri
|
|
@@ -1068,9 +1297,15 @@ class HttpServer {
|
|
|
1068
1297
|
|
|
1069
1298
|
_injectLastRequest() {
|
|
1070
1299
|
if (_classPrivateFieldLooseBase(this, _lastRequestOptions)[_lastRequestOptions]) {
|
|
1071
|
-
(
|
|
1300
|
+
if (this.log) {
|
|
1301
|
+
this.log.notice('Replaying HTTP last request');
|
|
1072
1302
|
|
|
1073
|
-
|
|
1303
|
+
_classPrivateFieldLooseBase(this, _server)[_server].inject(_classPrivateFieldLooseBase(this, _lastRequestOptions)[_lastRequestOptions]);
|
|
1304
|
+
} else {
|
|
1305
|
+
(0, _serverlessLog.default)('Replaying HTTP last request');
|
|
1306
|
+
}
|
|
1307
|
+
} else if (this.log) {
|
|
1308
|
+
this.log.notice('No last HTTP request to replay!');
|
|
1074
1309
|
} else {
|
|
1075
1310
|
(0, _serverlessLog.default)('No last HTTP request to replay!');
|
|
1076
1311
|
}
|