serverless-offline 8.0.0 → 8.3.1

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.
Files changed (53) hide show
  1. package/README.md +125 -112
  2. package/dist/ServerlessOffline.js +91 -24
  3. package/dist/config/constants.js +1 -1
  4. package/dist/config/supportedRuntimes.js +1 -1
  5. package/dist/events/http/Endpoint.js +27 -9
  6. package/dist/events/http/Http.js +3 -3
  7. package/dist/events/http/HttpServer.js +311 -76
  8. package/dist/events/http/authFunctionNameExtractor.js +14 -8
  9. package/dist/events/http/authJWTSettingsExtractor.js +14 -7
  10. package/dist/events/http/createAuthScheme.js +42 -8
  11. package/dist/events/http/createJWTAuthScheme.js +52 -13
  12. package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +7 -6
  13. package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +18 -7
  14. package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +17 -6
  15. package/dist/events/http/lambda-events/VelocityContext.js +4 -4
  16. package/dist/events/http/lambda-events/index.js +4 -4
  17. package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +19 -7
  18. package/dist/events/schedule/Schedule.js +64 -20
  19. package/dist/events/websocket/HttpServer.js +24 -7
  20. package/dist/events/websocket/WebSocket.js +14 -6
  21. package/dist/events/websocket/WebSocketClients.js +65 -17
  22. package/dist/events/websocket/WebSocketServer.js +28 -6
  23. package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +9 -2
  24. package/dist/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
  25. package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +28 -5
  26. package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +5 -5
  27. package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +1 -1
  28. package/dist/events/websocket/lambda-events/WebSocketEvent.js +3 -3
  29. package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +4 -4
  30. package/dist/lambda/HttpServer.js +34 -10
  31. package/dist/lambda/Lambda.js +15 -7
  32. package/dist/lambda/LambdaContext.js +1 -1
  33. package/dist/lambda/LambdaFunction.js +40 -23
  34. package/dist/lambda/LambdaFunctionPool.js +9 -8
  35. package/dist/lambda/handler-runner/HandlerRunner.js +48 -15
  36. package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +21 -8
  37. package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +1 -10
  38. package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +168 -69
  39. package/dist/lambda/handler-runner/docker-runner/DockerImage.js +21 -5
  40. package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +4 -4
  41. package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +9 -21
  42. package/dist/lambda/handler-runner/java-runner/JavaRunner.js +26 -14
  43. package/dist/lambda/handler-runner/python-runner/PythonRunner.js +20 -7
  44. package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +22 -24
  45. package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +2 -2
  46. package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +1 -11
  47. package/dist/lambda/routes/invocations/InvocationsController.js +37 -11
  48. package/dist/lambda/routes/invocations/invocationsRoute.js +2 -2
  49. package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +2 -6
  50. package/dist/serverlessLog.js +1 -1
  51. package/dist/utils/getHttpApiCorsConfig.js +18 -5
  52. package/dist/utils/index.js +16 -16
  53. package/package.json +58 -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 cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
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
- console.error(`Unexpected error while starting serverless-offline server on port ${httpPort}:`, err);
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
- (0, _serverlessLog.default)('Enter "rp" to replay the last request');
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
- (0, _serverlessLog.default)(err);
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
- console.log();
295
+ if (this.log) {
296
+ this.log.notice();
297
+ } else {
298
+ console.log();
299
+ }
273
300
  }
274
301
  }
275
302
 
276
303
  _logPluginIssue() {
277
- (0, _serverlessLog.default)('If you think this is an issue with the plugin please submit it, thanks!');
278
- (0, _serverlessLog.default)('https://github.com/dherault/serverless-offline/issues');
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
- (0, _serverlessLog.default)(`Configuring JWT Authorization: ${method} ${path}`); // Create a unique scheme per endpoint
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
- (0, _debugLog.default)(`Creating Authorization scheme for ${authKey}`); // Create the Auth Scheme for the endpoint
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
- (0, _serverlessLog.default)(`Configuring Authorization: ${path} ${authFunctionName}`);
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) return (0, _serverlessLog.default)(`WARNING: Authorization function ${authFunctionName} does not exist`);
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
- (0, _debugLog.default)(`Creating Authorization scheme for ${authKey}`); // Create the Auth Scheme for the endpoint
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
- (0, _serverlessLog.default)('HEAD method event detected. Skipping HAPI server route mapping ...');
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
- (0, _serverlessLog.default)(`${method} ${request.path} (λ: ${functionKey})`); // Check for APIKey
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
- (0, _debugLog.default)(`Missing x-api-key on private function ${functionKey}`);
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
- (0, _debugLog.default)('error in converting request.payload to JSON:', err);
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
- (0, _debugLog.default)('contentType:', contentType);
558
- (0, _debugLog.default)('requestTemplate:', requestTemplate);
559
- (0, _debugLog.default)('payload:', request.payload);
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
- (0, _debugLog.default)('schema:', schema);
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
- (0, _debugLog.default)('_____ REQUEST TEMPLATE PROCESSING _____');
580
- event = new _index.LambdaIntegrationEvent(request, stage, requestTemplate, requestPath).create();
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
- (0, _debugLog.default)('event:', event);
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
- (0, _debugLog.default)('_____ HANDLER RESOLVED _____');
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
- (0, _serverlessLog.default)(`Failure: ${errorMessage}`);
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
- console.error(err.stack);
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
- (0, _debugLog.default)(`Using response '${responseName}'`);
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
- (0, _debugLog.default)('_____ RESPONSE PARAMETERS PROCCESSING _____');
673
- (0, _debugLog.default)(`Found ${responseParametersKeys.length} responseParameters for '${responseName}' response`); // responseParameters use the following shape: "key": "value"
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
- (0, _debugLog.default)(`Processing responseParameter "${key}": "${value}"`); // For now the plugin only supports modifying headers
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
- (0, _debugLog.default)('Found header in left-hand:', headerName);
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
- (0, _debugLog.default)('Found body in right-hand');
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
- (0, _serverlessLog.default)(`Warning: while processing responseParameter "${key}": "${value}"`);
701
- (0, _serverlessLog.default)(`Offline plugin only supports "integration.response.body[.JSON_path]" right-hand responseParameter. Found "${value}" instead. Skipping.`);
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
- (0, _serverlessLog.default)(`Warning: empty value for responseParameter "${key}": "${value}", it won't be set`);
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
- (0, _debugLog.default)(`Will assign "${headerValue}" to header "${headerName}"`);
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
- (0, _serverlessLog.default)(`Warning: while processing responseParameter "${key}": "${value}"`);
722
- (0, _serverlessLog.default)(`Offline plugin only supports "method.response.header.PARAM_NAME" left-hand responseParameter. Found "${key}" instead. Skipping.`);
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
- (0, _debugLog.default)('_____ RESPONSE TEMPLATE PROCCESSING _____');
752
- (0, _debugLog.default)(`Using responseTemplate '${responseContentType}'`);
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
- (0, _serverlessLog.default)(`Error while parsing responseTemplate '${responseContentType}' for lambda ${functionKey}:`);
761
- console.log(error.stack);
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
- (0, _serverlessLog.default)(`Warning: No statusCode found for response "${responseName}".`);
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
- (0, _debugLog.default)('headers', headers);
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) (0, _serverlessLog.default)(err ? `Replying ${statusCode}` : `[${statusCode}] ${whatToLog}`);
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
- console.error(error);
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
- (0, _serverlessLog.default)('Routes defined in resources:');
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
- (0, _serverlessLog.default)(`WARNING: Only HTTP_PROXY is supported. Path '${pathResource}' is ignored.`);
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
- (0, _serverlessLog.default)(`WARNING: Could not resolve path for '${methodId}'.`);
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
- (0, _serverlessLog.default)(`WARNING: Could not load Proxy Uri for '${methodId}'`);
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
- (0, _serverlessLog.default)('HEAD method event detected. Skipping HAPI server route mapping ...');
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
- (0, _serverlessLog.default)(`${method} ${hapiPath} -> ${proxyUriInUse}`); // hapiOptions.tags = ['api']
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
- (0, _serverlessLog.default)(`PROXY ${request.method} ${request.url.pathname} -> ${resultUri}`);
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
- (0, _serverlessLog.default)('Replaying HTTP last request');
1300
+ if (this.log) {
1301
+ this.log.notice('Replaying HTTP last request');
1072
1302
 
1073
- _classPrivateFieldLooseBase(this, _server)[_server].inject(_classPrivateFieldLooseBase(this, _lastRequestOptions)[_lastRequestOptions]);
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
  }