serverless-offline 8.5.0 → 8.8.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.
Files changed (44) hide show
  1. package/README.md +118 -77
  2. package/dist/ServerlessOffline.js +27 -8
  3. package/dist/config/supportedRuntimes.js +1 -1
  4. package/dist/debugLog.js +3 -1
  5. package/dist/events/{http/authCanExecuteResource.js → authCanExecuteResource.js} +0 -0
  6. package/dist/events/{http/authFunctionNameExtractor.js → authFunctionNameExtractor.js} +1 -1
  7. package/dist/events/{http/authMatchPolicyResource.js → authMatchPolicyResource.js} +0 -0
  8. package/dist/events/authValidateContext.js +53 -0
  9. package/dist/events/http/Endpoint.js +3 -1
  10. package/dist/events/http/HttpServer.js +28 -21
  11. package/dist/events/http/OfflineEndpoint.js +23 -25
  12. package/dist/events/http/createAuthScheme.js +23 -12
  13. package/dist/events/http/createJWTAuthScheme.js +6 -2
  14. package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +26 -0
  15. package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +16 -14
  16. package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +22 -12
  17. package/dist/events/http/lambda-events/VelocityContext.js +3 -1
  18. package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +4 -1
  19. package/dist/events/schedule/Schedule.js +10 -9
  20. package/dist/events/websocket/HttpServer.js +3 -1
  21. package/dist/events/websocket/WebSocketClients.js +224 -5
  22. package/dist/events/websocket/WebSocketServer.js +5 -6
  23. package/dist/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +99 -0
  24. package/dist/events/websocket/lambda-events/index.js +8 -0
  25. package/dist/index.js +0 -4
  26. package/dist/lambda/HttpServer.js +3 -1
  27. package/dist/lambda/Lambda.js +5 -1
  28. package/dist/lambda/LambdaFunction.js +1 -1
  29. package/dist/lambda/handler-runner/HandlerRunner.js +0 -27
  30. package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +15 -6
  31. package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +6 -5
  32. package/dist/lambda/handler-runner/go-runner/GoRunner.js +34 -15
  33. package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +23 -14
  34. package/dist/lambda/handler-runner/java-runner/JavaRunner.js +4 -3
  35. package/dist/lambda/handler-runner/python-runner/PythonRunner.js +15 -10
  36. package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +3 -6
  37. package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +3 -1
  38. package/dist/utils/generateHapiPath.js +1 -1
  39. package/dist/utils/getHttpApiCorsConfig.js +4 -8
  40. package/dist/utils/index.js +11 -4
  41. package/dist/utils/lowerCaseKeys.js +14 -0
  42. package/dist/utils/resolveJoins.js +4 -2
  43. package/package.json +26 -29
  44. package/dist/checkEngine.js +0 -21
@@ -11,13 +11,15 @@ var _fs = require("fs");
11
11
 
12
12
  var pathUtils = _interopRequireWildcard(require("path"));
13
13
 
14
+ var _process = _interopRequireWildcard(require("process"));
15
+
14
16
  var _h2o = _interopRequireDefault(require("@hapi/h2o2"));
15
17
 
16
18
  var _hapi = require("@hapi/hapi");
17
19
 
18
20
  var _module = require("module");
19
21
 
20
- var _authFunctionNameExtractor = _interopRequireDefault(require("./authFunctionNameExtractor.js"));
22
+ var _authFunctionNameExtractor = _interopRequireDefault(require("../authFunctionNameExtractor.js"));
21
23
 
22
24
  var _authJWTSettingsExtractor = _interopRequireDefault(require("./authJWTSettingsExtractor.js"));
23
25
 
@@ -57,6 +59,11 @@ const {
57
59
  parse,
58
60
  stringify
59
61
  } = JSON;
62
+ const {
63
+ assign,
64
+ entries,
65
+ keys
66
+ } = Object;
60
67
 
61
68
  var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
62
69
 
@@ -208,7 +215,7 @@ class HttpServer {
208
215
  } // Override default headers with headers that have been explicitly set
209
216
 
210
217
 
211
- Object.keys(explicitlySetHeaders).forEach(key => {
218
+ keys(explicitlySetHeaders).forEach(key => {
212
219
  const value = explicitlySetHeaders[key];
213
220
 
214
221
  if (value) {
@@ -238,7 +245,7 @@ class HttpServer {
238
245
  console.error(`Unexpected error while starting serverless-offline server on port ${httpPort}:`, err);
239
246
  }
240
247
 
241
- process.exit(1);
248
+ (0, _process.exit)(1);
242
249
  } // TODO move the following block
243
250
 
244
251
 
@@ -257,8 +264,8 @@ class HttpServer {
257
264
  (0, _serverlessLog.default)('Enter "rp" to replay the last request');
258
265
  }
259
266
 
260
- if (process.env.NODE_ENV !== 'test') {
261
- process.openStdin().addListener('data', data => {
267
+ if (_process.env.NODE_ENV !== 'test') {
268
+ _process.default.openStdin().addListener('data', data => {
262
269
  // note: data is an object, and when converted to a string it will
263
270
  // end with a linefeed. so we (rather crudely) account for that
264
271
  // with toString() and then trim()
@@ -293,7 +300,7 @@ class HttpServer {
293
300
 
294
301
 
295
302
  _printBlankLine() {
296
- if (process.env.NODE_ENV !== 'test') {
303
+ if (_process.env.NODE_ENV !== 'test') {
297
304
  if (this.log) {
298
305
  this.log.notice();
299
306
  } else {
@@ -405,7 +412,7 @@ class HttpServer {
405
412
  if (typeof endpoint.authorizer === 'string') {
406
413
  authorizerOptions.name = authFunctionName;
407
414
  } else {
408
- Object.assign(authorizerOptions, endpoint.authorizer);
415
+ assign(authorizerOptions, endpoint.authorizer);
409
416
  } // Create a unique scheme per endpoint
410
417
  // This allows the methodArn on the event property to be set appropriately
411
418
 
@@ -803,7 +810,7 @@ class HttpServer {
803
810
  }
804
811
  }
805
812
 
806
- for (const [key, value] of Object.entries(endpoint.responses)) {
813
+ for (const [key, value] of entries(endpoint.responses)) {
807
814
  if (key !== 'default' && errorMessage.match(`^${value.selectionPattern || key}$`)) {
808
815
  responseName = key;
809
816
  break;
@@ -825,7 +832,7 @@ class HttpServer {
825
832
  } = chosenResponse;
826
833
 
827
834
  if (responseParameters) {
828
- const responseParametersKeys = Object.keys(responseParameters);
835
+ const responseParametersKeys = keys(responseParameters);
829
836
 
830
837
  if (this.log) {
831
838
  this.log.debug('_____ RESPONSE PARAMETERS PROCCESSING _____');
@@ -836,7 +843,7 @@ class HttpServer {
836
843
  } // responseParameters use the following shape: "key": "value"
837
844
 
838
845
 
839
- Object.entries(responseParameters).forEach(([key, value]) => {
846
+ entries(responseParameters).forEach(([key, value]) => {
840
847
  const keyArray = key.split('.'); // eg: "method.response.header.location"
841
848
 
842
849
  const valueArray = value.split('.'); // eg: "integration.response.body.redirect.url"
@@ -930,7 +937,7 @@ class HttpServer {
930
937
 
931
938
  if (integration === 'AWS') {
932
939
  const endpointResponseHeaders = endpoint.response && endpoint.response.headers || {};
933
- Object.entries(endpointResponseHeaders).filter(([, value]) => typeof value === 'string' && /^'.*?'$/.test(value)).forEach(([key, value]) => response.header(key, value.slice(1, -1)));
940
+ entries(endpointResponseHeaders).filter(([, value]) => typeof value === 'string' && /^'.*?'$/.test(value)).forEach(([key, value]) => response.header(key, value.slice(1, -1)));
934
941
  /* LAMBDA INTEGRATION RESPONSE TEMPLATE PROCCESSING */
935
942
  // If there is a responseTemplate, we apply it to the result
936
943
 
@@ -939,7 +946,7 @@ class HttpServer {
939
946
  } = chosenResponse;
940
947
 
941
948
  if (typeof responseTemplates === 'object') {
942
- const responseTemplatesKeys = Object.keys(responseTemplates);
949
+ const responseTemplatesKeys = keys(responseTemplates);
943
950
 
944
951
  if (responseTemplatesKeys.length) {
945
952
  // BAD IMPLEMENTATION: first key in responseTemplates
@@ -1001,7 +1008,7 @@ class HttpServer {
1001
1008
  response.source = _buffer.Buffer.from(result, 'base64');
1002
1009
  response.variety = 'buffer';
1003
1010
  } else if (typeof result === 'string') {
1004
- response.source = JSON.stringify(result);
1011
+ response.source = stringify(result);
1005
1012
  } else if (result && result.body && typeof result.body !== 'string') {
1006
1013
  return this._reply502(response, 'According to the API Gateway specs, the body content must be stringified. Check your Lambda response and make sure you are invoking JSON.stringify(YOUR_CONTENT) on your body object', {});
1007
1014
  } else {
@@ -1010,7 +1017,7 @@ class HttpServer {
1010
1017
  } else if (integration === 'AWS_PROXY') {
1011
1018
  /* LAMBDA PROXY INTEGRATION HAPIJS RESPONSE CONFIGURATION */
1012
1019
  if (endpoint.isHttpApi && endpoint.payload === '2.0' && (typeof result === 'string' || !result.statusCode)) {
1013
- const body = typeof result === 'string' ? result : JSON.stringify(result);
1020
+ const body = typeof result === 'string' ? result : stringify(result);
1014
1021
  result = {
1015
1022
  isBase64Encoded: false,
1016
1023
  statusCode: 200,
@@ -1031,13 +1038,13 @@ class HttpServer {
1031
1038
  const headers = {};
1032
1039
 
1033
1040
  if (result && result.headers) {
1034
- Object.keys(result.headers).forEach(header => {
1041
+ keys(result.headers).forEach(header => {
1035
1042
  headers[header] = (headers[header] || []).concat(result.headers[header]);
1036
1043
  });
1037
1044
  }
1038
1045
 
1039
1046
  if (result && result.multiValueHeaders) {
1040
- Object.keys(result.multiValueHeaders).forEach(header => {
1047
+ keys(result.multiValueHeaders).forEach(header => {
1041
1048
  headers[header] = (headers[header] || []).concat(result.multiValueHeaders[header]);
1042
1049
  });
1043
1050
  }
@@ -1057,7 +1064,7 @@ class HttpServer {
1057
1064
  });
1058
1065
  };
1059
1066
 
1060
- Object.keys(headers).forEach(header => {
1067
+ keys(headers).forEach(header => {
1061
1068
  if (header.toLowerCase() === 'set-cookie') {
1062
1069
  headers[header].forEach(parseCookies);
1063
1070
  } else {
@@ -1081,7 +1088,7 @@ class HttpServer {
1081
1088
  });
1082
1089
 
1083
1090
  if (typeof result === 'string') {
1084
- response.source = JSON.stringify(result);
1091
+ response.source = stringify(result);
1085
1092
  } else if (result && typeof result.body !== 'undefined') {
1086
1093
  if (result.isBase64Encoded) {
1087
1094
  response.encoding = 'binary';
@@ -1164,7 +1171,7 @@ class HttpServer {
1164
1171
 
1165
1172
  const resourceRoutes = (0, _parseResources.default)(_classPrivateFieldLooseBase(this, _serverless)[_serverless].service.resources);
1166
1173
 
1167
- if (!resourceRoutes || !Object.keys(resourceRoutes).length) {
1174
+ if (!resourceRoutes || !keys(resourceRoutes).length) {
1168
1175
  return;
1169
1176
  }
1170
1177
 
@@ -1177,7 +1184,7 @@ class HttpServer {
1177
1184
  (0, _serverlessLog.default)('Routes defined in resources:');
1178
1185
  }
1179
1186
 
1180
- Object.entries(resourceRoutes).forEach(([methodId, resourceRoutesObj]) => {
1187
+ entries(resourceRoutes).forEach(([methodId, resourceRoutesObj]) => {
1181
1188
  const {
1182
1189
  isProxy,
1183
1190
  method,
@@ -1265,7 +1272,7 @@ class HttpServer {
1265
1272
  params
1266
1273
  } = request;
1267
1274
  let resultUri = proxyUriInUse;
1268
- Object.entries(params).forEach(([key, value]) => {
1275
+ entries(params).forEach(([key, value]) => {
1269
1276
  resultUri = resultUri.replace(`{${key}}`, value);
1270
1277
  });
1271
1278
 
@@ -7,32 +7,30 @@ exports.default = void 0;
7
7
 
8
8
  class OfflineEndpoint {
9
9
  constructor() {
10
- return {
11
- apiKeyRequired: false,
12
- authorizationType: 'none',
13
- authorizerFunction: false,
14
- path: '',
15
- requestParameters: {},
16
- requestTemplates: {
17
- 'application/json': ''
18
- },
19
- responses: {
20
- default: {
21
- 400: {
22
- statusCode: '400'
23
- },
24
- responseModels: {
25
- 'application/json;charset=UTF-8': 'Empty'
26
- },
27
- responseParameters: {},
28
- responseTemplates: {
29
- 'application/json;charset=UTF-8': ''
30
- },
31
- statusCode: 200
32
- }
33
- },
34
- type: 'AWS'
10
+ this.apiKeyRequired = false;
11
+ this.authorizationType = 'none';
12
+ this.authorizerFunction = false;
13
+ this.path = '';
14
+ this.requestParameters = {};
15
+ this.requestTemplates = {
16
+ 'application/json': ''
35
17
  };
18
+ this.responses = {
19
+ default: {
20
+ 400: {
21
+ statusCode: '400'
22
+ },
23
+ responseModels: {
24
+ 'application/json;charset=UTF-8': 'Empty'
25
+ },
26
+ responseParameters: {},
27
+ responseTemplates: {
28
+ 'application/json;charset=UTF-8': ''
29
+ },
30
+ statusCode: 200
31
+ }
32
+ };
33
+ this.type = 'AWS';
36
34
  }
37
35
 
38
36
  }
@@ -7,7 +7,9 @@ exports.default = createAuthScheme;
7
7
 
8
8
  var _boom = _interopRequireDefault(require("@hapi/boom"));
9
9
 
10
- var _authCanExecuteResource = _interopRequireDefault(require("./authCanExecuteResource.js"));
10
+ var _authCanExecuteResource = _interopRequireDefault(require("../authCanExecuteResource.js"));
11
+
12
+ var _authValidateContext = _interopRequireDefault(require("../authValidateContext.js"));
11
13
 
12
14
  var _debugLog = _interopRequireDefault(require("../../debugLog.js"));
13
15
 
@@ -113,11 +115,9 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
113
115
 
114
116
  try {
115
117
  const result = await lambdaFunction.runHandler();
116
- if (result === 'Unauthorized') return _boom.default.unauthorized('Unauthorized'); // return processResponse(null, result)
117
-
118
- const policy = result; // Validate that the policy document has the principalId set
118
+ if (result === 'Unauthorized') return _boom.default.unauthorized('Unauthorized'); // Validate that the policy document has the principalId set
119
119
 
120
- if (!policy.principalId) {
120
+ if (!result.principalId) {
121
121
  if (log) {
122
122
  log.notice(`Authorization response did not include a principalId: (λ: ${authFunName})`);
123
123
  } else {
@@ -127,7 +127,7 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
127
127
  return _boom.default.forbidden('No principalId set on the Response');
128
128
  }
129
129
 
130
- if (!(0, _authCanExecuteResource.default)(policy.policyDocument, event.methodArn)) {
130
+ if (!(0, _authCanExecuteResource.default)(result.policyDocument, event.methodArn)) {
131
131
  if (log) {
132
132
  log.notice(`Authorization response didn't authorize user to access resource: (λ: ${authFunName})`);
133
133
  } else {
@@ -135,6 +135,18 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
135
135
  }
136
136
 
137
137
  return _boom.default.forbidden('User is not authorized to access this resource');
138
+ } // validate the resulting context, ensuring that all
139
+ // values are either string, number, or boolean types
140
+
141
+
142
+ if (result.context) {
143
+ const validationResult = (0, _authValidateContext.default)(result.context, authFunName);
144
+
145
+ if (validationResult instanceof Error) {
146
+ return validationResult;
147
+ }
148
+
149
+ result.context = validationResult;
138
150
  }
139
151
 
140
152
  if (log) {
@@ -145,17 +157,16 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
145
157
 
146
158
  const authorizer = {
147
159
  integrationLatency: '42',
148
- principalId: policy.principalId,
149
- ...policy.context
160
+ principalId: result.principalId,
161
+ ...result.context
150
162
  }; // Set the credentials for the rest of the pipeline
151
- // return resolve(
152
163
 
153
164
  return h.authenticated({
154
165
  credentials: {
155
166
  authorizer,
156
- context: policy.context,
157
- principalId: policy.principalId,
158
- usageIdentifierKey: policy.usageIdentifierKey
167
+ context: result.context,
168
+ principalId: result.principalId,
169
+ usageIdentifierKey: result.usageIdentifierKey
159
170
  }
160
171
  });
161
172
  } catch (err) {
@@ -13,6 +13,10 @@ var _serverlessLog = _interopRequireDefault(require("../../serverlessLog.js"));
13
13
 
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
15
 
16
+ const {
17
+ isArray
18
+ } = Array;
19
+
16
20
  function createAuthScheme(jwtOptions, {
17
21
  log
18
22
  }) {
@@ -82,8 +86,8 @@ function createAuthScheme(jwtOptions, {
82
86
  return _boom.default.unauthorized('JWT Token not from correct issuer url');
83
87
  }
84
88
 
85
- const validAudiences = Array.isArray(jwtOptions.audience) ? jwtOptions.audience : [jwtOptions.audience];
86
- const providedAudiences = Array.isArray(aud) ? aud : [aud];
89
+ const validAudiences = isArray(jwtOptions.audience) ? jwtOptions.audience : [jwtOptions.audience];
90
+ const providedAudiences = isArray(aud) ? aud : [aud];
87
91
  const validAudienceProvided = providedAudiences.some(a => validAudiences.includes(a));
88
92
 
89
93
  if (!validAudienceProvided && !validAudiences.includes(clientId)) {
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _process = require("process");
9
+
8
10
  var _renderVelocityTemplateObject = _interopRequireDefault(require("./renderVelocityTemplateObject.js"));
9
11
 
10
12
  var _VelocityContext = _interopRequireDefault(require("./VelocityContext.js"));
@@ -17,6 +19,10 @@ var id = 0;
17
19
 
18
20
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
19
21
 
22
+ const {
23
+ parse
24
+ } = JSON;
25
+
20
26
  var _path = /*#__PURE__*/_classPrivateFieldLooseKey("path");
21
27
 
22
28
  var _request = /*#__PURE__*/_classPrivateFieldLooseKey("request");
@@ -51,6 +57,26 @@ class LambdaIntegrationEvent {
51
57
  }
52
58
 
53
59
  create() {
60
+ if (_process.env.AUTHORIZER) {
61
+ try {
62
+ const authorizerContext = parse(_process.env.AUTHORIZER);
63
+
64
+ if (authorizerContext) {
65
+ _classPrivateFieldLooseBase(this, _request)[_request].auth = { ..._classPrivateFieldLooseBase(this, _request)[_request].auth,
66
+ credentials: {
67
+ authorizer: authorizerContext
68
+ }
69
+ };
70
+ }
71
+ } catch (error) {
72
+ if (this.log) {
73
+ this.log.error('Could not parse process.env.AUTHORIZER, make sure it is correct JSON');
74
+ } else {
75
+ console.error('Serverless-offline: Could not parse process.env.AUTHORIZER, make sure it is correct JSON.');
76
+ }
77
+ }
78
+ }
79
+
54
80
  const velocityContext = new _VelocityContext.default(_classPrivateFieldLooseBase(this, _request)[_request], _classPrivateFieldLooseBase(this, _stage)[_stage], _classPrivateFieldLooseBase(this, _request)[_request].payload || {}, _classPrivateFieldLooseBase(this, _path)[_path]).getContext();
55
81
  const event = (0, _renderVelocityTemplateObject.default)(_classPrivateFieldLooseBase(this, _requestTemplate)[_requestTemplate], velocityContext, this.v3Utils);
56
82
  return event;
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _buffer = require("buffer");
9
9
 
10
+ var _process = require("process");
11
+
10
12
  var _jsonwebtoken = require("jsonwebtoken");
11
13
 
12
14
  var _index = require("../../../utils/index.js");
@@ -42,7 +44,7 @@ var _stageVariables = /*#__PURE__*/_classPrivateFieldLooseKey("stageVariables");
42
44
  var _additionalRequestContext = /*#__PURE__*/_classPrivateFieldLooseKey("additionalRequestContext");
43
45
 
44
46
  class LambdaProxyIntegrationEvent {
45
- constructor(request, stage, path, stageVariables, routeKey = null, additionalRequestContext = null, v3Utils) {
47
+ constructor(request, stage, path, stageVariables, routeKey, additionalRequestContext, v3Utils) {
46
48
  Object.defineProperty(this, _path, {
47
49
  writable: true,
48
50
  value: null
@@ -88,14 +90,14 @@ class LambdaProxyIntegrationEvent {
88
90
  const authContext = _classPrivateFieldLooseBase(this, _request)[_request].auth && _classPrivateFieldLooseBase(this, _request)[_request].auth.credentials && _classPrivateFieldLooseBase(this, _request)[_request].auth.credentials.context || {};
89
91
  let authAuthorizer;
90
92
 
91
- if (process.env.AUTHORIZER) {
93
+ if (_process.env.AUTHORIZER) {
92
94
  try {
93
- authAuthorizer = parse(process.env.AUTHORIZER);
95
+ authAuthorizer = parse(_process.env.AUTHORIZER);
94
96
  } catch (error) {
95
97
  if (this.log) {
96
- this.log.error('Could not parse process.env.AUTHORIZER, make sure it is correct JSON');
98
+ this.log.error('Could not parse env.AUTHORIZER, make sure it is correct JSON');
97
99
  } else {
98
- console.error('Serverless-offline: Could not parse process.env.AUTHORIZER, make sure it is correct JSON.');
100
+ console.error('Serverless-offline: Could not parse env.AUTHORIZER, make sure it is correct JSON.');
99
101
  }
100
102
  }
101
103
  }
@@ -201,7 +203,7 @@ class LambdaProxyIntegrationEvent {
201
203
  claims,
202
204
  scopes,
203
205
  // 'principalId' should have higher priority
204
- principalId: authPrincipalId || process.env.PRINCIPAL_ID || 'offlineContext_authorizer_principalId' // See #24
206
+ principalId: authPrincipalId || _process.env.PRINCIPAL_ID || 'offlineContext_authorizer_principalId' // See #24
205
207
 
206
208
  }),
207
209
  domainName: 'offlineContext_domainName',
@@ -210,14 +212,14 @@ class LambdaProxyIntegrationEvent {
210
212
  httpMethod,
211
213
  identity: {
212
214
  accessKey: null,
213
- accountId: process.env.SLS_ACCOUNT_ID || 'offlineContext_accountId',
214
- apiKey: process.env.SLS_API_KEY || 'offlineContext_apiKey',
215
- apiKeyId: process.env.SLS_API_KEY_ID || 'offlineContext_apiKeyId',
216
- caller: process.env.SLS_CALLER || 'offlineContext_caller',
217
- cognitoAuthenticationProvider: _headers['cognito-authentication-provider'] || process.env.SLS_COGNITO_AUTHENTICATION_PROVIDER || 'offlineContext_cognitoAuthenticationProvider',
218
- cognitoAuthenticationType: process.env.SLS_COGNITO_AUTHENTICATION_TYPE || 'offlineContext_cognitoAuthenticationType',
219
- cognitoIdentityId: _headers['cognito-identity-id'] || process.env.SLS_COGNITO_IDENTITY_ID || 'offlineContext_cognitoIdentityId',
220
- cognitoIdentityPoolId: process.env.SLS_COGNITO_IDENTITY_POOL_ID || 'offlineContext_cognitoIdentityPoolId',
215
+ accountId: _process.env.SLS_ACCOUNT_ID || 'offlineContext_accountId',
216
+ apiKey: _process.env.SLS_API_KEY || 'offlineContext_apiKey',
217
+ apiKeyId: _process.env.SLS_API_KEY_ID || 'offlineContext_apiKeyId',
218
+ caller: _process.env.SLS_CALLER || 'offlineContext_caller',
219
+ cognitoAuthenticationProvider: _headers['cognito-authentication-provider'] || _process.env.SLS_COGNITO_AUTHENTICATION_PROVIDER || 'offlineContext_cognitoAuthenticationProvider',
220
+ cognitoAuthenticationType: _process.env.SLS_COGNITO_AUTHENTICATION_TYPE || 'offlineContext_cognitoAuthenticationType',
221
+ cognitoIdentityId: _headers['cognito-identity-id'] || _process.env.SLS_COGNITO_IDENTITY_ID || 'offlineContext_cognitoIdentityId',
222
+ cognitoIdentityPoolId: _process.env.SLS_COGNITO_IDENTITY_POOL_ID || 'offlineContext_cognitoIdentityPoolId',
221
223
  principalOrgId: null,
222
224
  sourceIp: remoteAddress,
223
225
  user: 'offlineContext_user',
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _buffer = require("buffer");
9
9
 
10
+ var _process = require("process");
11
+
10
12
  var _jsonwebtoken = require("jsonwebtoken");
11
13
 
12
14
  var _index = require("../../../utils/index.js");
@@ -18,13 +20,15 @@ var id = 0;
18
20
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
19
21
 
20
22
  const {
21
- byteLength
22
- } = _buffer.Buffer;
23
+ isArray
24
+ } = Array;
23
25
  const {
24
26
  parse
25
27
  } = JSON;
26
28
  const {
27
- assign
29
+ assign,
30
+ entries,
31
+ fromEntries
28
32
  } = Object; // https://www.serverless.com/framework/docs/providers/aws/events/http-api/
29
33
  // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
30
34
 
@@ -78,9 +82,9 @@ class LambdaProxyIntegrationEventV2 {
78
82
  const authContext = _classPrivateFieldLooseBase(this, _request)[_request].auth && _classPrivateFieldLooseBase(this, _request)[_request].auth.credentials && _classPrivateFieldLooseBase(this, _request)[_request].auth.credentials.context || {};
79
83
  let authAuthorizer;
80
84
 
81
- if (process.env.AUTHORIZER) {
85
+ if (_process.env.AUTHORIZER) {
82
86
  try {
83
- authAuthorizer = parse(process.env.AUTHORIZER);
87
+ authAuthorizer = parse(_process.env.AUTHORIZER);
84
88
  } catch (error) {
85
89
  if (this.log) {
86
90
  this.log.error('Could not parse process.env.AUTHORIZER, make sure it is correct JSON');
@@ -97,7 +101,7 @@ class LambdaProxyIntegrationEventV2 {
97
101
  } = _classPrivateFieldLooseBase(this, _request)[_request].raw.req; // NOTE FIXME request.raw.req.rawHeaders can only be null for testing (hapi shot inject())
98
102
 
99
103
 
100
- const headers = (0, _index.parseHeaders)(rawHeaders || []) || {};
104
+ const headers = (0, _index.lowerCaseKeys)((0, _index.parseHeaders)(rawHeaders || [])) || {};
101
105
 
102
106
  if (headers['sls-offline-authorizer-override']) {
103
107
  try {
@@ -117,13 +121,13 @@ class LambdaProxyIntegrationEventV2 {
117
121
  body = _classPrivateFieldLooseBase(this, _request)[_request].rawPayload;
118
122
  }
119
123
 
120
- if (!headers['Content-Length'] && !headers['content-length'] && !headers['Content-length'] && (typeof body === 'string' || body instanceof _buffer.Buffer || body instanceof ArrayBuffer)) {
121
- headers['Content-Length'] = String(byteLength(body));
124
+ if (!headers['content-length'] && (typeof body === 'string' || body instanceof _buffer.Buffer || body instanceof ArrayBuffer)) {
125
+ headers['content-length'] = String(_buffer.Buffer.byteLength(body));
122
126
  } // Set a default Content-Type if not provided.
123
127
 
124
128
 
125
- if (!headers['Content-Type'] && !headers['content-type'] && !headers['Content-type']) {
126
- headers['Content-Type'] = 'application/json';
129
+ if (!headers['content-type']) {
130
+ headers['content-type'] = 'application/json';
127
131
  }
128
132
  } else if (typeof body === 'undefined' || body === '') {
129
133
  body = null;
@@ -169,7 +173,13 @@ class LambdaProxyIntegrationEventV2 {
169
173
  const httpMethod = method.toUpperCase();
170
174
  const requestTime = (0, _index.formatToClfTime)(received);
171
175
  const requestTimeEpoch = received;
172
- const cookies = Object.entries(_classPrivateFieldLooseBase(this, _request)[_request].state).map(([key, value]) => `${key}=${value}`);
176
+ const cookies = entries(_classPrivateFieldLooseBase(this, _request)[_request].state).flatMap(([key, value]) => {
177
+ if (isArray(value)) {
178
+ return value.map(v => `${key}=${v}`);
179
+ }
180
+
181
+ return `${key}=${value}`;
182
+ });
173
183
  return {
174
184
  version: '2.0',
175
185
  routeKey: _classPrivateFieldLooseBase(this, _routeKey)[_routeKey],
@@ -177,7 +187,7 @@ class LambdaProxyIntegrationEventV2 {
177
187
  rawQueryString: _classPrivateFieldLooseBase(this, _request)[_request].url.searchParams.toString(),
178
188
  cookies,
179
189
  headers,
180
- queryStringParameters: _classPrivateFieldLooseBase(this, _request)[_request].url.search ? Object.fromEntries(Array.from(_classPrivateFieldLooseBase(this, _request)[_request].url.searchParams)) : null,
190
+ queryStringParameters: _classPrivateFieldLooseBase(this, _request)[_request].url.search ? fromEntries(Array.from(_classPrivateFieldLooseBase(this, _request)[_request].url.searchParams)) : null,
181
191
  requestContext: {
182
192
  accountId: 'offlineContext_accountId',
183
193
  apiId: 'offlineContext_apiId',
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _buffer = require("buffer");
9
9
 
10
+ var _process = require("process");
11
+
10
12
  var _jsStringEscape = _interopRequireDefault(require("js-string-escape"));
11
13
 
12
14
  var _jsonwebtoken = require("jsonwebtoken");
@@ -102,7 +104,7 @@ class VelocityContext {
102
104
  }
103
105
 
104
106
  if (!authorizer) authorizer = {};
105
- authorizer.principalId = authPrincipalId || process.env.PRINCIPAL_ID || 'offlineContext_authorizer_principalId'; // See #24
107
+ authorizer.principalId = authPrincipalId || _process.env.PRINCIPAL_ID || 'offlineContext_authorizer_principalId'; // See #24
106
108
 
107
109
  if (token) {
108
110
  try {
@@ -15,6 +15,9 @@ var _index = require("../../../utils/index.js");
15
15
 
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
17
 
18
+ const {
19
+ parse
20
+ } = JSON;
18
21
  const {
19
22
  entries
20
23
  } = Object;
@@ -23,7 +26,7 @@ function tryToParseJSON(string) {
23
26
  let parsed;
24
27
 
25
28
  try {
26
- parsed = JSON.parse(string);
29
+ parsed = parse(string);
27
30
  } catch (err) {// nothing! Some things are not meant to be parsed.
28
31
  }
29
32
 
@@ -19,7 +19,7 @@ var id = 0;
19
19
 
20
20
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
21
21
 
22
- // const CRON_LENGTH_WITH_YEAR = 6
22
+ const CRON_LENGTH_WITH_YEAR = 6;
23
23
  const {
24
24
  stringify
25
25
  } = JSON;
@@ -106,14 +106,15 @@ class Schedule {
106
106
  }
107
107
  });
108
108
  });
109
- } // _convertCronSyntax(cronString) {
110
- // if (cronString.split(' ').length < CRON_LENGTH_WITH_YEAR) {
111
- // return cronString
112
- // }
113
- //
114
- // return cronString.replace(/\s\S+$/, '')
115
- // }
109
+ }
110
+
111
+ _convertCronSyntax(cronString) {
112
+ if (cronString.split(' ').length < CRON_LENGTH_WITH_YEAR) {
113
+ return cronString;
114
+ }
116
115
 
116
+ return cronString.replace(/\s\S+$/, '');
117
+ }
117
118
 
118
119
  _convertRateToCron(rate) {
119
120
  const [number, unit] = rate.split(' ');
@@ -146,7 +147,7 @@ class Schedule {
146
147
  const params = scheduleEvent.replace('rate(', '').replace('cron(', '').replace(')', '');
147
148
 
148
149
  if (scheduleEvent.startsWith('cron(')) {
149
- if (!this.log) console.log('schedule rate "cron" not yet supported!'); // return this._convertCronSyntax(params)
150
+ return this._convertCronSyntax(params);
150
151
  }
151
152
 
152
153
  if (scheduleEvent.startsWith('rate(')) {
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _process = require("process");
9
+
8
10
  var _hapi = require("@hapi/hapi");
9
11
 
10
12
  var _index = require("./http-routes/index.js");
@@ -86,7 +88,7 @@ class HttpServer {
86
88
  console.error(`Unexpected error while starting serverless-offline websocket server on port ${websocketPort}:`, err);
87
89
  }
88
90
 
89
- process.exit(1);
91
+ (0, _process.exit)(1);
90
92
  }
91
93
 
92
94
  if (this.log) {