serverless-offline 8.4.0 → 8.7.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 (28) hide show
  1. package/README.md +81 -9
  2. package/dist/ServerlessOffline.js +12 -0
  3. package/dist/events/{http/authCanExecuteResource.js → authCanExecuteResource.js} +0 -0
  4. package/dist/events/{http/authFunctionNameExtractor.js → authFunctionNameExtractor.js} +1 -1
  5. package/dist/events/{http/authMatchPolicyResource.js → authMatchPolicyResource.js} +0 -0
  6. package/dist/events/http/HttpServer.js +48 -10
  7. package/dist/events/http/authValidateContext.js +48 -0
  8. package/dist/events/http/createAuthScheme.js +23 -12
  9. package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +24 -0
  10. package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +21 -1
  11. package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +28 -2
  12. package/dist/events/websocket/WebSocketClients.js +259 -26
  13. package/dist/events/websocket/WebSocketServer.js +50 -4
  14. package/dist/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +99 -0
  15. package/dist/events/websocket/lambda-events/index.js +8 -0
  16. package/dist/lambda/LambdaFunction.js +3 -2
  17. package/dist/lambda/handler-runner/HandlerRunner.js +2 -1
  18. package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +9 -1
  19. package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +4 -1
  20. package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +22 -7
  21. package/dist/lambda/handler-runner/java-runner/JavaRunner.js +1 -2
  22. package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +0 -2
  23. package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +2 -0
  24. package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +3 -2
  25. package/dist/lambda/routes/invocations/invocationsRoute.js +2 -1
  26. package/dist/utils/splitHandlerPathAndName.js +13 -9
  27. package/package.json +13 -11
  28. package/CHANGELOG.md +0 -21
@@ -244,7 +244,10 @@ class DockerContainer {
244
244
  // Add `host.docker.internal` DNS name to access host from inside the container
245
245
  // https://github.com/docker/for-linux/issues/264
246
246
  const gatewayIp = await this._getBridgeGatewayIp();
247
- dockerArgs.push('--add-host', `host.docker.internal:${gatewayIp}`);
247
+
248
+ if (gatewayIp) {
249
+ dockerArgs.push('--add-host', `host.docker.internal:${gatewayIp}`);
250
+ }
248
251
  }
249
252
 
250
253
  if (_classPrivateFieldLooseBase(this, _dockerOptions)[_dockerOptions].network) {
@@ -58,8 +58,8 @@ const clearModule = (fP, opts) => {
58
58
  delete require.cache[filePath];
59
59
 
60
60
  for (const c of cld) {
61
- // Unload any non node_modules children
62
- if (!c.filename.match(/node_modules/)) {
61
+ // Unload any non node_modules and non-binary children
62
+ if (!c.filename.match(/\/node_modules\//i) && !c.filename.match(/\.node$/i)) {
63
63
  clearModule(c.id, { ...options,
64
64
  cleanup: false
65
65
  });
@@ -74,7 +74,7 @@ const clearModule = (fP, opts) => {
74
74
  cleanup = false;
75
75
 
76
76
  for (const fn of Object.keys(require.cache)) {
77
- if (require.cache[fn].id !== '.' && require.cache[fn].parent && require.cache[fn].parent.id !== '.' && !require.cache[require.cache[fn].parent.id]) {
77
+ if (require.cache[fn] && require.cache[fn].id !== '.' && require.cache[fn].parent && require.cache[fn].parent.id !== '.' && !require.cache[require.cache[fn].parent.id] && !fn.match(/\/node_modules\//i) && !fn.match(/\.node$/i)) {
78
78
  delete require.cache[fn];
79
79
  cleanup = true;
80
80
  }
@@ -92,12 +92,14 @@ var _handlerName = /*#__PURE__*/_classPrivateFieldLooseKey("handlerName");
92
92
 
93
93
  var _handlerPath = /*#__PURE__*/_classPrivateFieldLooseKey("handlerPath");
94
94
 
95
+ var _handlerModuleNesting = /*#__PURE__*/_classPrivateFieldLooseKey("handlerModuleNesting");
96
+
95
97
  var _timeout = /*#__PURE__*/_classPrivateFieldLooseKey("timeout");
96
98
 
97
99
  var _allowCache = /*#__PURE__*/_classPrivateFieldLooseKey("allowCache");
98
100
 
99
101
  class InProcessRunner {
100
- constructor(functionKey, handlerPath, handlerName, env, timeout, allowCache) {
102
+ constructor(functionKey, handlerPath, handlerName, handlerModuleNesting, env, timeout, allowCache) {
101
103
  Object.defineProperty(this, _env, {
102
104
  writable: true,
103
105
  value: null
@@ -114,6 +116,10 @@ class InProcessRunner {
114
116
  writable: true,
115
117
  value: null
116
118
  });
119
+ Object.defineProperty(this, _handlerModuleNesting, {
120
+ writable: true,
121
+ value: null
122
+ });
117
123
  Object.defineProperty(this, _timeout, {
118
124
  writable: true,
119
125
  value: null
@@ -126,6 +132,7 @@ class InProcessRunner {
126
132
  _classPrivateFieldLooseBase(this, _functionKey)[_functionKey] = functionKey;
127
133
  _classPrivateFieldLooseBase(this, _handlerName)[_handlerName] = handlerName;
128
134
  _classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath] = handlerPath;
135
+ _classPrivateFieldLooseBase(this, _handlerModuleNesting)[_handlerModuleNesting] = handlerModuleNesting;
129
136
  _classPrivateFieldLooseBase(this, _timeout)[_timeout] = timeout;
130
137
  _classPrivateFieldLooseBase(this, _allowCache)[_allowCache] = allowCache;
131
138
  } // no-op
@@ -152,9 +159,17 @@ class InProcessRunner {
152
159
  });
153
160
  }
154
161
 
155
- const {
156
- [_classPrivateFieldLooseBase(this, _handlerName)[_handlerName]]: handler
157
- } = await Promise.resolve(`${_classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath]}`).then(s => _interopRequireWildcard(require(s)));
162
+ let handler;
163
+
164
+ try {
165
+ const handlerPathExport = await Promise.resolve(`${_classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath]}`).then(s => _interopRequireWildcard(require(s))); // this supports handling of nested handler paths like <pathToFile>/<fileName>.object1.object2.object3.handler
166
+ // a use case for this, is when the handler is further down the export tree or in nested objects
167
+ // NOTE: this feature is supported in AWS Lambda
168
+
169
+ handler = _classPrivateFieldLooseBase(this, _handlerModuleNesting)[_handlerModuleNesting].reduce((obj, key) => obj[key], handlerPathExport);
170
+ } catch (error) {
171
+ throw new Error(`offline: one of the module nesting ${_classPrivateFieldLooseBase(this, _handlerModuleNesting)[_handlerModuleNesting]} for handler ${_classPrivateFieldLooseBase(this, _handlerName)[_handlerName]} is undefined or not exported`);
172
+ }
158
173
 
159
174
  if (typeof handler !== 'function') {
160
175
  throw new Error(`offline: handler '${_classPrivateFieldLooseBase(this, _handlerName)[_handlerName]}' in ${_classPrivateFieldLooseBase(this, _handlerPath)[_handlerPath]} is not a function`);
@@ -116,8 +116,7 @@ class JavaRunner {
116
116
  data: input,
117
117
  function: _classPrivateFieldLooseBase(this, _functionName)[_functionName],
118
118
  jsonOutput: true,
119
- serverlessOffline: true,
120
- allowCache: _classPrivateFieldLooseBase(this, _allowCache)[_allowCache]
119
+ serverlessOffline: true
121
120
  });
122
121
  const httpOptions = {
123
122
  method: 'POST',
@@ -138,8 +138,6 @@ class RubyRunner {
138
138
  } else {
139
139
  console.log(stderr);
140
140
  }
141
-
142
- return stderr;
143
141
  }
144
142
 
145
143
  return this._parsePayload(stdout);
@@ -39,6 +39,7 @@ class WorkerThreadRunner {
39
39
  functionKey,
40
40
  handlerName,
41
41
  handlerPath,
42
+ handlerModuleNesting,
42
43
  timeout
43
44
  } = funOptions;
44
45
  _classPrivateFieldLooseBase(this, _allowCache)[_allowCache] = allowCache;
@@ -49,6 +50,7 @@ class WorkerThreadRunner {
49
50
  functionKey,
50
51
  handlerName,
51
52
  handlerPath,
53
+ handlerModuleNesting,
52
54
  timeout
53
55
  }
54
56
  });
@@ -10,7 +10,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
10
10
  const {
11
11
  functionKey,
12
12
  handlerName,
13
- handlerPath
13
+ handlerPath,
14
+ handlerModuleNesting
14
15
  } = _worker_threads.workerData;
15
16
 
16
17
  _worker_threads.parentPort.on('message', async messageData => {
@@ -22,7 +23,7 @@ _worker_threads.parentPort.on('message', async messageData => {
22
23
  allowCache
23
24
  } = messageData; // TODO we could probably cache this in the module scope?
24
25
 
25
- const inProcessRunner = new _index.default(functionKey, handlerPath, handlerName, process.env, timeout, allowCache);
26
+ const inProcessRunner = new _index.default(functionKey, handlerPath, handlerName, handlerModuleNesting, process.env, timeout, allowCache);
26
27
  const result = await inProcessRunner.run(event, context); // TODO check serializeability (contains function, symbol etc)
27
28
 
28
29
  port.postMessage(result);
@@ -53,7 +53,8 @@ function invocationsRoute(lambda, options, v3Utils) {
53
53
  let functionError = null;
54
54
 
55
55
  if (invokeResults) {
56
- resultPayload = invokeResults.Payload || '';
56
+ const isPayloadDefined = typeof invokeResults.Payload !== 'undefined';
57
+ resultPayload = isPayloadDefined ? invokeResults.Payload : '';
57
58
  statusCode = invokeResults.StatusCode || 200;
58
59
  functionError = invokeResults.FunctionError || null;
59
60
  }
@@ -8,18 +8,18 @@ exports.default = splitHandlerPathAndName;
8
8
  // some-folder/src.index => some-folder/src
9
9
  function splitHandlerPathAndName(handler) {
10
10
  // Split handler into method name and path i.e. handler.run
11
- // Support Ruby paths with namespace resolution operators e.g.
11
+ const prepathDelimiter = handler.lastIndexOf('/');
12
+ const prepath = handler.substr(0, prepathDelimiter + 1); // include '/' for path
13
+
14
+ const postpath = handler.substr(prepathDelimiter + 1); // Support Ruby paths with namespace resolution operators e.g.
12
15
  // ./src/somefolder/source.LambdaFunctions::Handler.process
13
16
  // prepath: ./src/somefolder/
14
17
  // postpath: source.LambdaFunctions::Handler.process
15
18
  // filename: source
16
19
  // path: ./src/somefolder/source
17
20
  // name: LambdaFunctions::Handler.process
18
- if (handler.match(/::/)) {
19
- const prepathDelimiter = handler.lastIndexOf('/');
20
- const prepath = handler.substr(0, prepathDelimiter + 1); // include '/' for path
21
21
 
22
- const postpath = handler.substr(prepathDelimiter + 1);
22
+ if (handler.match(/::/)) {
23
23
  const nameDelimiter = postpath.indexOf('.');
24
24
  const filename = postpath.substr(0, nameDelimiter);
25
25
  const path = prepath + filename;
@@ -30,8 +30,12 @@ function splitHandlerPathAndName(handler) {
30
30
  // name: run
31
31
 
32
32
 
33
- const delimiter = handler.lastIndexOf('.');
34
- const path = handler.substr(0, delimiter);
35
- const name = handler.substr(delimiter + 1);
36
- return [path, name];
33
+ const [filename, ...moduleNesting] = postpath.split('.');
34
+ const [name] = moduleNesting.slice(-1);
35
+ const path = prepath + filename; // module nesting has been added to support when the
36
+ // handler function is buried deep inside of a module
37
+ // e.g /src/somefoler/handlers/index.layer1.layer2.handler
38
+ // AWS supports this feature
39
+
40
+ return [path, name, moduleNesting];
37
41
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dedicatedTo": "Blue, a great migrating bird.",
3
3
  "name": "serverless-offline",
4
- "version": "8.4.0",
4
+ "version": "8.7.0",
5
5
  "description": "Emulate AWS λ and API Gateway locally when developing your Serverless project",
6
6
  "license": "MIT",
7
7
  "main": "dist/main.js",
@@ -117,6 +117,7 @@
117
117
  "Kiryl Yermakou (https://github.com/rma4ok)",
118
118
  "kobanyan (https://github.com/kobanyan)",
119
119
  "Leonardo Alifraco (https://github.com/lalifraco-devspark)",
120
+ "Leonardo Medici (https://github.com/doclm)",
120
121
  "Luke Chavers (https://github.com/vmadman)",
121
122
  "Manuel Böhm (https://github.com/boehmers)",
122
123
  "Marc Campbell (https://github.com/marccampbell)",
@@ -149,6 +150,7 @@
149
150
  "Stewart Gleadow (https://github.com/sgleadow)",
150
151
  "Thales Minussi (https://github.com/tminussi)",
151
152
  "Thang Minh Vu (https://github.com/ittus)",
153
+ "Tom St. Clair (https://github.com/tom-stclair)",
152
154
  "Trevor Leach (https://github.com/trevor-leach)",
153
155
  "Tuan Minh Huynh (https://github.com/tuanmh)",
154
156
  "Utku Turunc (https://github.com/utkuturunc)",
@@ -156,7 +158,8 @@
156
158
  "Dima Krutolianov (https://github.com/dimadk24)",
157
159
  "Bryan Vaz (https://github.com/bryanvaz)",
158
160
  "Justin Ng (https://github.com/njyjn)",
159
- "Fernando Alvarez (https://github.com/jefer590)"
161
+ "Fernando Alvarez (https://github.com/jefer590)",
162
+ "Eric Carter (https://github.com/ericctsf)"
160
163
  ],
161
164
  "husky": {
162
165
  "hooks": {
@@ -202,7 +205,7 @@
202
205
  "@hapi/boom": "^9.1.4",
203
206
  "@hapi/h2o2": "^9.1.0",
204
207
  "@hapi/hapi": "^20.2.1",
205
- "aws-sdk": "^2.1065.0",
208
+ "aws-sdk": "^2.1097.0",
206
209
  "boxen": "^5.1.2",
207
210
  "chalk": "^4.1.2",
208
211
  "cuid": "^2.1.8",
@@ -223,21 +226,20 @@
223
226
  "p-queue": "^6.6.2",
224
227
  "p-retry": "^4.6.1",
225
228
  "please-upgrade-node": "^3.2.0",
226
- "portfinder": "^1.0.28",
227
229
  "semver": "^7.3.5",
228
230
  "update-notifier": "^5.1.0",
229
231
  "velocityjs": "^2.0.6",
230
- "ws": "^7.5.6"
232
+ "ws": "^7.5.7"
231
233
  },
232
234
  "devDependencies": {
233
- "@babel/cli": "^7.16.8",
234
- "@babel/core": "^7.16.12",
235
+ "@babel/cli": "^7.17.6",
236
+ "@babel/core": "^7.17.8",
235
237
  "@babel/plugin-proposal-class-properties": "^7.16.7",
236
238
  "@babel/plugin-proposal-dynamic-import": "^7.16.7",
237
239
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
238
240
  "@babel/plugin-proposal-optional-chaining": "^7.16.7",
239
- "@babel/plugin-transform-modules-commonjs": "^7.16.8",
240
- "@babel/register": "^7.16.9",
241
+ "@babel/plugin-transform-modules-commonjs": "^7.17.7",
242
+ "@babel/register": "^7.17.7",
241
243
  "archiver": "^5.3.0",
242
244
  "babel-eslint": "^10.1.0",
243
245
  "copyfiles": "^2.4.1",
@@ -251,9 +253,9 @@
251
253
  "jest": "^26.6.3",
252
254
  "lint-staged": "^11.2.6",
253
255
  "p-map": "^4.0.0",
254
- "prettier": "^2.5.1",
256
+ "prettier": "^2.6.0",
255
257
  "rimraf": "^3.0.2",
256
- "serverless": "^2.72.2",
258
+ "serverless": "^2.72.3",
257
259
  "standard-version": "^9.3.2"
258
260
  },
259
261
  "peerDependencies": {
package/CHANGELOG.md DELETED
@@ -1,21 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
-
5
- ## [8.4.0](https://github.com/dherault/serverless-offline/compare/v8.3.1...v8.4.0) (2022-01-28)
6
-
7
- ### Features
8
-
9
- - `go-runner` implementation ([#1320](https://github.com/dherault/serverless-offline/issues/1320)) ([6bb54fd](https://github.com/dherault/serverless-offline/commit/6bb54fdccebd3db61221a9b8f709414876086324))
10
- - `--disableScheduledEvents` CLI param support ([#1185](https://github.com/dherault/serverless-offline/issues/1185)) ([4503567](https://github.com/dherault/serverless-offline/commit/4503567cdb8fa31ac9df98b667a403b0408f8444))
11
-
12
- ### Bug Fixes
13
-
14
- - Handle custom authorizer 401 in non in-process runners ([#1319](https://github.com/dherault/serverless-offline/issues/1319)) ([8d61bde](https://github.com/dherault/serverless-offline/commit/8d61bde74cdfb37410a5c1952ca608e815eeb1cf))
15
- - Support `httpApi` payload override on function level ([#1312](https://github.com/dherault/serverless-offline/issues/1312)) ([8db63dd](https://github.com/dherault/serverless-offline/commit/8db63dda6054198775ed3b567dc3c1dbf73eb574))
16
-
17
- ### [8.3.1](https://github.com/dherault/serverless-offline/compare/v8.3.0...v8.3.1) (2021-11-25)
18
-
19
- ### Bug Fixes
20
-
21
- - Fix handling of modern logs (`Cannot read properties of undefined (reading 'notice')` error)