serverless-offline 8.2.0 → 8.5.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 (57) hide show
  1. package/README.md +157 -116
  2. package/dist/ServerlessOffline.js +98 -26
  3. package/dist/config/commandOptions.js +4 -0
  4. package/dist/config/constants.js +1 -1
  5. package/dist/config/defaultOptions.js +1 -0
  6. package/dist/events/http/Endpoint.js +27 -9
  7. package/dist/events/http/Http.js +3 -3
  8. package/dist/events/http/HttpServer.js +355 -82
  9. package/dist/events/http/authFunctionNameExtractor.js +14 -8
  10. package/dist/events/http/authJWTSettingsExtractor.js +14 -7
  11. package/dist/events/http/createAuthScheme.js +44 -9
  12. package/dist/events/http/createJWTAuthScheme.js +52 -13
  13. package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +7 -6
  14. package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +38 -7
  15. package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +37 -6
  16. package/dist/events/http/lambda-events/VelocityContext.js +4 -4
  17. package/dist/events/http/lambda-events/index.js +4 -4
  18. package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +19 -7
  19. package/dist/events/schedule/Schedule.js +45 -10
  20. package/dist/events/websocket/HttpServer.js +24 -7
  21. package/dist/events/websocket/WebSocket.js +14 -6
  22. package/dist/events/websocket/WebSocketClients.js +127 -38
  23. package/dist/events/websocket/WebSocketServer.js +79 -11
  24. package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +9 -2
  25. package/dist/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
  26. package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +28 -5
  27. package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +5 -5
  28. package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +1 -1
  29. package/dist/events/websocket/lambda-events/WebSocketEvent.js +3 -3
  30. package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +4 -4
  31. package/dist/lambda/HttpServer.js +34 -10
  32. package/dist/lambda/Lambda.js +15 -7
  33. package/dist/lambda/LambdaContext.js +1 -1
  34. package/dist/lambda/LambdaFunction.js +40 -23
  35. package/dist/lambda/LambdaFunctionPool.js +9 -8
  36. package/dist/lambda/handler-runner/HandlerRunner.js +51 -16
  37. package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +21 -8
  38. package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +1 -10
  39. package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +168 -69
  40. package/dist/lambda/handler-runner/docker-runner/DockerImage.js +21 -5
  41. package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +4 -4
  42. package/dist/lambda/handler-runner/go-runner/GoRunner.js +211 -0
  43. package/dist/lambda/handler-runner/go-runner/index.js +15 -0
  44. package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +16 -22
  45. package/dist/lambda/handler-runner/java-runner/JavaRunner.js +26 -14
  46. package/dist/lambda/handler-runner/python-runner/PythonRunner.js +20 -7
  47. package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +22 -24
  48. package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +2 -2
  49. package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +1 -11
  50. package/dist/lambda/routes/invocations/InvocationsController.js +30 -11
  51. package/dist/lambda/routes/invocations/invocationsRoute.js +4 -3
  52. package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +2 -6
  53. package/dist/serverlessLog.js +1 -1
  54. package/dist/utils/checkGoVersion.js +27 -0
  55. package/dist/utils/getHttpApiCorsConfig.js +18 -5
  56. package/dist/utils/index.js +24 -16
  57. package/package.json +86 -37
@@ -24,12 +24,12 @@ const {
24
24
  stringify
25
25
  } = JSON;
26
26
 
27
- var _lambda = _classPrivateFieldLooseKey("lambda");
27
+ var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
28
28
 
29
- var _region = _classPrivateFieldLooseKey("region");
29
+ var _region = /*#__PURE__*/_classPrivateFieldLooseKey("region");
30
30
 
31
31
  class Schedule {
32
- constructor(lambda, region) {
32
+ constructor(lambda, region, v3Utils) {
33
33
  Object.defineProperty(this, _lambda, {
34
34
  writable: true,
35
35
  value: null
@@ -40,6 +40,13 @@ class Schedule {
40
40
  });
41
41
  _classPrivateFieldLooseBase(this, _lambda)[_lambda] = lambda;
42
42
  _classPrivateFieldLooseBase(this, _region)[_region] = region;
43
+
44
+ if (v3Utils) {
45
+ this.log = v3Utils.log;
46
+ this.progress = v3Utils.progress;
47
+ this.writeText = v3Utils.writeText;
48
+ this.v3Utils = v3Utils;
49
+ }
43
50
  }
44
51
 
45
52
  _scheduleEvent(functionKey, scheduleEvent) {
@@ -50,7 +57,12 @@ class Schedule {
50
57
  } = scheduleEvent;
51
58
 
52
59
  if (!enabled) {
53
- console.log(`Scheduling [${functionKey}] cron: disabled`);
60
+ if (this.log) {
61
+ this.log.notice(`Scheduling [${functionKey}] cron: disabled`);
62
+ } else {
63
+ console.log(`Scheduling [${functionKey}] cron: disabled`);
64
+ }
65
+
54
66
  return;
55
67
  } // Convert string rate to array to support Serverless v2.57.0 and lower.
56
68
 
@@ -64,7 +76,11 @@ class Schedule {
64
76
  rates.forEach(entry => {
65
77
  const cron = this._convertExpressionToCron(entry);
66
78
 
67
- console.log(`Scheduling [${functionKey}] cron: [${cron}] input: ${stringify(input)}`);
79
+ if (this.log) {
80
+ this.log.notice(`Scheduling [${functionKey}] cron: [${cron}] input: ${stringify(input)}`);
81
+ } else {
82
+ console.log(`Scheduling [${functionKey}] cron: [${cron}] input: ${stringify(input)}`);
83
+ }
68
84
 
69
85
  _nodeSchedule.default.scheduleJob(cron, async () => {
70
86
  try {
@@ -75,9 +91,18 @@ class Schedule {
75
91
  /* const result = */
76
92
 
77
93
  await lambdaFunction.runHandler();
78
- console.log(`Successfully invoked scheduled function: [${functionKey}]`);
94
+
95
+ if (this.log) {
96
+ this.log.notice(`Successfully invoked scheduled function: [${functionKey}]`);
97
+ } else {
98
+ console.log(`Successfully invoked scheduled function: [${functionKey}]`);
99
+ }
79
100
  } catch (err) {
80
- console.log(`Failed to execute scheduled function: [${functionKey}] Error: ${err}`);
101
+ if (this.log) {
102
+ this.log.error(`Failed to execute scheduled function: [${functionKey}] Error: ${err}`);
103
+ } else {
104
+ console.log(`Failed to execute scheduled function: [${functionKey}] Error: ${err}`);
105
+ }
81
106
  }
82
107
  });
83
108
  });
@@ -107,7 +132,12 @@ class Schedule {
107
132
  return `0 0 */${number} * *`;
108
133
 
109
134
  default:
110
- console.log(`scheduler: Invalid rate syntax '${rate}', will not schedule`);
135
+ if (this.log) {
136
+ this.log.error(`scheduler: Invalid rate syntax '${rate}', will not schedule`);
137
+ } else {
138
+ console.log(`scheduler: Invalid rate syntax '${rate}', will not schedule`);
139
+ }
140
+
111
141
  return null;
112
142
  }
113
143
  }
@@ -116,14 +146,19 @@ class Schedule {
116
146
  const params = scheduleEvent.replace('rate(', '').replace('cron(', '').replace(')', '');
117
147
 
118
148
  if (scheduleEvent.startsWith('cron(')) {
119
- console.log('schedule rate "cron" not yet supported!'); // return this._convertCronSyntax(params)
149
+ if (!this.log) console.log('schedule rate "cron" not yet supported!'); // return this._convertCronSyntax(params)
120
150
  }
121
151
 
122
152
  if (scheduleEvent.startsWith('rate(')) {
123
153
  return this._convertRateToCron(params);
124
154
  }
125
155
 
126
- console.log('scheduler: invalid, schedule syntax');
156
+ if (this.log) {
157
+ this.log.error('scheduler: invalid, schedule syntax');
158
+ } else {
159
+ console.log('scheduler: invalid, schedule syntax');
160
+ }
161
+
127
162
  return undefined;
128
163
  }
129
164
 
@@ -19,14 +19,14 @@ var id = 0;
19
19
 
20
20
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
21
21
 
22
- var _options = _classPrivateFieldLooseKey("options");
22
+ var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
23
23
 
24
- var _server = _classPrivateFieldLooseKey("server");
24
+ var _server = /*#__PURE__*/_classPrivateFieldLooseKey("server");
25
25
 
26
- var _webSocketClients = _classPrivateFieldLooseKey("webSocketClients");
26
+ var _webSocketClients = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketClients");
27
27
 
28
28
  class HttpServer {
29
- constructor(options, webSocketClients) {
29
+ constructor(options, webSocketClients, v3Utils) {
30
30
  Object.defineProperty(this, _options, {
31
31
  writable: true,
32
32
  value: null
@@ -41,6 +41,14 @@ class HttpServer {
41
41
  });
42
42
  _classPrivateFieldLooseBase(this, _options)[_options] = options;
43
43
  _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients] = webSocketClients;
44
+
45
+ if (v3Utils) {
46
+ this.log = v3Utils.log;
47
+ this.progress = v3Utils.progress;
48
+ this.writeText = v3Utils.writeText;
49
+ this.v3Utils = v3Utils;
50
+ }
51
+
44
52
  const {
45
53
  host,
46
54
  websocketPort
@@ -59,7 +67,7 @@ class HttpServer {
59
67
 
60
68
  async start() {
61
69
  // add routes
62
- const routes = [...(0, _index.connectionsRoutes)(_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients]), (0, _index.catchAllRoute)()];
70
+ const routes = [...(0, _index.connectionsRoutes)(_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients], this.v3Utils), (0, _index.catchAllRoute)(this.v3Utils)];
63
71
 
64
72
  _classPrivateFieldLooseBase(this, _server)[_server].route(routes);
65
73
 
@@ -72,11 +80,20 @@ class HttpServer {
72
80
  try {
73
81
  await _classPrivateFieldLooseBase(this, _server)[_server].start();
74
82
  } catch (err) {
75
- console.error(`Unexpected error while starting serverless-offline websocket server on port ${websocketPort}:`, err);
83
+ if (this.log) {
84
+ this.log.error(`Unexpected error while starting serverless-offline websocket server on port ${websocketPort}:`, err);
85
+ } else {
86
+ console.error(`Unexpected error while starting serverless-offline websocket server on port ${websocketPort}:`, err);
87
+ }
88
+
76
89
  process.exit(1);
77
90
  }
78
91
 
79
- (0, _serverlessLog.default)(`Offline [http for websocket] listening on http${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
92
+ if (this.log) {
93
+ this.log.notice(`Offline [http for websocket] listening on http${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
94
+ } else {
95
+ (0, _serverlessLog.default)(`Offline [http for websocket] listening on http${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
96
+ }
80
97
  } // stops the server
81
98
 
82
99
 
@@ -21,12 +21,12 @@ var id = 0;
21
21
 
22
22
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
23
23
 
24
- var _httpServer = _classPrivateFieldLooseKey("httpServer");
24
+ var _httpServer = /*#__PURE__*/_classPrivateFieldLooseKey("httpServer");
25
25
 
26
- var _webSocketServer = _classPrivateFieldLooseKey("webSocketServer");
26
+ var _webSocketServer = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketServer");
27
27
 
28
28
  class WebSocket {
29
- constructor(serverless, options, lambda) {
29
+ constructor(serverless, options, lambda, v3Utils) {
30
30
  Object.defineProperty(this, _httpServer, {
31
31
  writable: true,
32
32
  value: null
@@ -35,10 +35,18 @@ class WebSocket {
35
35
  writable: true,
36
36
  value: null
37
37
  });
38
- const webSocketClients = new _WebSocketClients.default(serverless, options, lambda);
39
- _classPrivateFieldLooseBase(this, _httpServer)[_httpServer] = new _HttpServer.default(options, webSocketClients); // share server
38
+ const webSocketClients = new _WebSocketClients.default(serverless, options, lambda, v3Utils);
40
39
 
41
- _classPrivateFieldLooseBase(this, _webSocketServer)[_webSocketServer] = new _WebSocketServer.default(options, webSocketClients, _classPrivateFieldLooseBase(this, _httpServer)[_httpServer].server);
40
+ if (v3Utils) {
41
+ this.log = v3Utils.log;
42
+ this.progress = v3Utils.progress;
43
+ this.writeText = v3Utils.writeText;
44
+ this.v3Utils = v3Utils;
45
+ }
46
+
47
+ _classPrivateFieldLooseBase(this, _httpServer)[_httpServer] = new _HttpServer.default(options, webSocketClients, this.v3Utils); // share server
48
+
49
+ _classPrivateFieldLooseBase(this, _webSocketServer)[_webSocketServer] = new _WebSocketServer.default(options, webSocketClients, _classPrivateFieldLooseBase(this, _httpServer)[_httpServer].server, v3Utils);
42
50
  }
43
51
 
44
52
  start() {
@@ -30,22 +30,22 @@ const {
30
30
  stringify
31
31
  } = JSON;
32
32
 
33
- var _clients = _classPrivateFieldLooseKey("clients");
33
+ var _clients = /*#__PURE__*/_classPrivateFieldLooseKey("clients");
34
34
 
35
- var _lambda = _classPrivateFieldLooseKey("lambda");
35
+ var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
36
36
 
37
- var _options = _classPrivateFieldLooseKey("options");
37
+ var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
38
38
 
39
- var _webSocketRoutes = _classPrivateFieldLooseKey("webSocketRoutes");
39
+ var _webSocketRoutes = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketRoutes");
40
40
 
41
- var _websocketsApiRouteSelectionExpression = _classPrivateFieldLooseKey("websocketsApiRouteSelectionExpression");
41
+ var _websocketsApiRouteSelectionExpression = /*#__PURE__*/_classPrivateFieldLooseKey("websocketsApiRouteSelectionExpression");
42
42
 
43
- var _idleTimeouts = _classPrivateFieldLooseKey("idleTimeouts");
43
+ var _idleTimeouts = /*#__PURE__*/_classPrivateFieldLooseKey("idleTimeouts");
44
44
 
45
- var _hardTimeouts = _classPrivateFieldLooseKey("hardTimeouts");
45
+ var _hardTimeouts = /*#__PURE__*/_classPrivateFieldLooseKey("hardTimeouts");
46
46
 
47
47
  class WebSocketClients {
48
- constructor(serverless, options, lambda) {
48
+ constructor(serverless, options, lambda, v3Utils) {
49
49
  Object.defineProperty(this, _clients, {
50
50
  writable: true,
51
51
  value: new Map()
@@ -77,6 +77,13 @@ class WebSocketClients {
77
77
  _classPrivateFieldLooseBase(this, _lambda)[_lambda] = lambda;
78
78
  _classPrivateFieldLooseBase(this, _options)[_options] = options;
79
79
  _classPrivateFieldLooseBase(this, _websocketsApiRouteSelectionExpression)[_websocketsApiRouteSelectionExpression] = serverless.service.provider.websocketsApiRouteSelectionExpression || _index2.DEFAULT_WEBSOCKETS_API_ROUTE_SELECTION_EXPRESSION;
80
+
81
+ if (v3Utils) {
82
+ this.log = v3Utils.log;
83
+ this.progress = v3Utils.progress;
84
+ this.writeText = v3Utils.writeText;
85
+ this.v3Utils = v3Utils;
86
+ }
80
87
  }
81
88
 
82
89
  _addWebSocketClient(client, connectionId) {
@@ -105,7 +112,12 @@ class WebSocketClients {
105
112
 
106
113
  _addHardTimeout(client, connectionId) {
107
114
  const timeoutId = setTimeout(() => {
108
- (0, _debugLog.default)(`timeout:hard:${connectionId}`);
115
+ if (this.log) {
116
+ this.log.debug(`timeout:hard:${connectionId}`);
117
+ } else {
118
+ (0, _debugLog.default)(`timeout:hard:${connectionId}`);
119
+ }
120
+
109
121
  client.close(1001, 'Going away');
110
122
  }, _classPrivateFieldLooseBase(this, _options)[_options].webSocketHardTimeout * 1000);
111
123
 
@@ -123,9 +135,19 @@ class WebSocketClients {
123
135
 
124
136
  this._clearIdleTimeout(client);
125
137
 
126
- (0, _debugLog.default)(`timeout:idle:${connectionId}:reset`);
138
+ if (this.log) {
139
+ this.log.debug(`timeout:idle:${connectionId}:reset`);
140
+ } else {
141
+ (0, _debugLog.default)(`timeout:idle:${connectionId}:reset`);
142
+ }
143
+
127
144
  const timeoutId = setTimeout(() => {
128
- (0, _debugLog.default)(`timeout:idle:${connectionId}:trigger`);
145
+ if (this.log) {
146
+ this.log.debug(`timeout:idle:${connectionId}:trigger`);
147
+ } else {
148
+ (0, _debugLog.default)(`timeout:idle:${connectionId}:trigger`);
149
+ }
150
+
129
151
  client.close(1001, 'Going away');
130
152
  }, _classPrivateFieldLooseBase(this, _options)[_options].webSocketIdleTimeout * 1000);
131
153
 
@@ -138,14 +160,53 @@ class WebSocketClients {
138
160
  clearTimeout(timeoutId);
139
161
  }
140
162
 
141
- async _processEvent(websocketClient, connectionId, route, event) {
142
- let functionKey = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get(route);
163
+ async verifyClient(connectionId, request) {
164
+ const route = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get('$connect');
143
165
 
144
- if (!functionKey && route !== '$connect' && route !== '$disconnect') {
145
- functionKey = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get('$default');
166
+ if (!route) {
167
+ return {
168
+ verified: false,
169
+ statusCode: 502
170
+ };
146
171
  }
147
172
 
148
- if (!functionKey) {
173
+ const connectEvent = new _index.WebSocketConnectEvent(connectionId, request, _classPrivateFieldLooseBase(this, _options)[_options]).create();
174
+
175
+ const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(route.functionKey);
176
+
177
+ lambdaFunction.setEvent(connectEvent);
178
+
179
+ try {
180
+ const {
181
+ statusCode
182
+ } = await lambdaFunction.runHandler();
183
+ const verified = statusCode >= 200 && statusCode < 300;
184
+ return {
185
+ verified,
186
+ statusCode
187
+ };
188
+ } catch (err) {
189
+ if (this.log) {
190
+ this.log.debug(`Error in route handler '${route.functionKey}'`, err);
191
+ } else {
192
+ (0, _debugLog.default)(`Error in route handler '${route.functionKey}'`, err);
193
+ }
194
+
195
+ return {
196
+ verified: false,
197
+ statusCode: 502
198
+ };
199
+ }
200
+ }
201
+
202
+ async _processEvent(websocketClient, connectionId, routeKey, event) {
203
+ let route = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get(routeKey);
204
+
205
+ if (!route && routeKey !== '$disconnect') {
206
+ route = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get('$default');
207
+ }
208
+
209
+ if (!route) {
149
210
  return;
150
211
  }
151
212
 
@@ -156,25 +217,37 @@ class WebSocketClients {
156
217
  message: 'Internal server error',
157
218
  requestId: '1234567890'
158
219
  }));
159
- } // mimic AWS behaviour (close connection) when the $connect route handler throws
160
-
161
-
162
- if (route === '$connect') {
163
- websocketClient.close();
164
220
  }
165
221
 
166
- (0, _debugLog.default)(`Error in route handler '${functionKey}'`, err);
222
+ if (this.log) {
223
+ this.log.debug(`Error in route handler '${route.functionKey}'`, err);
224
+ } else {
225
+ (0, _debugLog.default)(`Error in route handler '${route.functionKey}'`, err);
226
+ }
167
227
  };
168
228
 
169
- const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(functionKey);
229
+ const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(route.functionKey);
170
230
 
171
- lambdaFunction.setEvent(event); // let result
231
+ lambdaFunction.setEvent(event);
172
232
 
173
233
  try {
174
- /* result = */
175
- await lambdaFunction.runHandler(); // TODO what to do with "result"?
234
+ const {
235
+ body
236
+ } = await lambdaFunction.runHandler();
237
+
238
+ if (body && routeKey !== '$disconnect' && route.definition.routeResponseSelectionExpression === '$default') {
239
+ // https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-selection-expressions.html#apigateway-websocket-api-route-response-selection-expressions
240
+ // TODO: Once API gateway supports RouteResponses, this will need to change to support that functionality
241
+ // For now, send body back to the client
242
+ this.send(connectionId, body);
243
+ }
176
244
  } catch (err) {
177
- console.log(err);
245
+ if (this.log) {
246
+ this.log.error(err);
247
+ } else {
248
+ console.log(err);
249
+ }
250
+
178
251
  sendError(err);
179
252
  }
180
253
  }
@@ -199,15 +272,15 @@ class WebSocketClients {
199
272
  return route || _index2.DEFAULT_WEBSOCKETS_ROUTE;
200
273
  }
201
274
 
202
- addClient(webSocketClient, request, connectionId) {
275
+ addClient(webSocketClient, connectionId) {
203
276
  this._addWebSocketClient(webSocketClient, connectionId);
204
277
 
205
- const connectEvent = new _index.WebSocketConnectEvent(connectionId, request, _classPrivateFieldLooseBase(this, _options)[_options]).create();
206
-
207
- this._processEvent(webSocketClient, connectionId, '$connect', connectEvent);
208
-
209
278
  webSocketClient.on('close', () => {
210
- (0, _debugLog.default)(`disconnect:${connectionId}`);
279
+ if (this.log) {
280
+ this.log.debug(`disconnect:${connectionId}`);
281
+ } else {
282
+ (0, _debugLog.default)(`disconnect:${connectionId}`);
283
+ }
211
284
 
212
285
  this._removeWebSocketClient(webSocketClient);
213
286
 
@@ -220,11 +293,20 @@ class WebSocketClients {
220
293
  this._processEvent(webSocketClient, connectionId, '$disconnect', disconnectEvent);
221
294
  });
222
295
  webSocketClient.on('message', message => {
223
- (0, _debugLog.default)(`message:${message}`);
296
+ if (this.log) {
297
+ this.log.debug(`message:${message}`);
298
+ } else {
299
+ (0, _debugLog.default)(`message:${message}`);
300
+ }
224
301
 
225
302
  const route = this._getRoute(message);
226
303
 
227
- (0, _debugLog.default)(`route:${route} on connection=${connectionId}`);
304
+ if (this.log) {
305
+ this.log.debug(`route:${route} on connection=${connectionId}`);
306
+ } else {
307
+ (0, _debugLog.default)(`route:${route} on connection=${connectionId}`);
308
+ }
309
+
228
310
  const event = new _index.WebSocketEvent(connectionId, route, message).create();
229
311
 
230
312
  this._onWebSocketUsed(connectionId);
@@ -233,11 +315,18 @@ class WebSocketClients {
233
315
  });
234
316
  }
235
317
 
236
- addRoute(functionKey, route) {
318
+ addRoute(functionKey, definition) {
237
319
  // set the route name
238
- _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].set(route, functionKey);
320
+ _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].set(definition.route, {
321
+ functionKey,
322
+ definition
323
+ });
239
324
 
240
- (0, _serverlessLog.default)(`route '${route}'`);
325
+ if (this.log) {
326
+ this.log.notice(`route '${definition}'`);
327
+ } else {
328
+ (0, _serverlessLog.default)(`route '${definition}'`);
329
+ }
241
330
  }
242
331
 
243
332
  close(connectionId) {
@@ -21,12 +21,14 @@ var id = 0;
21
21
 
22
22
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
23
23
 
24
- var _options = _classPrivateFieldLooseKey("options");
24
+ var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
25
25
 
26
- var _webSocketClients = _classPrivateFieldLooseKey("webSocketClients");
26
+ var _webSocketClients = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketClients");
27
+
28
+ var _connectionIds = /*#__PURE__*/_classPrivateFieldLooseKey("connectionIds");
27
29
 
28
30
  class WebSocketServer {
29
- constructor(options, webSocketClients, sharedServer) {
31
+ constructor(options, webSocketClients, sharedServer, v3Utils) {
30
32
  Object.defineProperty(this, _options, {
31
33
  writable: true,
32
34
  value: null
@@ -35,17 +37,79 @@ class WebSocketServer {
35
37
  writable: true,
36
38
  value: null
37
39
  });
40
+ Object.defineProperty(this, _connectionIds, {
41
+ writable: true,
42
+ value: new Map()
43
+ });
38
44
  _classPrivateFieldLooseBase(this, _options)[_options] = options;
39
45
  _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients] = webSocketClients;
46
+
47
+ if (v3Utils) {
48
+ this.log = v3Utils.log;
49
+ this.progress = v3Utils.progress;
50
+ this.writeText = v3Utils.writeText;
51
+ this.v3Utils = v3Utils;
52
+ }
53
+
40
54
  const server = new _ws.Server({
41
- server: sharedServer
55
+ server: sharedServer,
56
+ verifyClient: ({
57
+ req
58
+ }, cb) => {
59
+ const connectionId = (0, _index.createUniqueId)();
60
+ const {
61
+ headers
62
+ } = req;
63
+ const key = headers['sec-websocket-key'];
64
+
65
+ if (this.log) {
66
+ this.log.debug(`verifyClient:${key} ${connectionId}`);
67
+ } else {
68
+ (0, _debugLog.default)(`verifyClient:${key} ${connectionId}`);
69
+ } // Use the websocket key to coorelate connection IDs
70
+
71
+
72
+ _classPrivateFieldLooseBase(this, _connectionIds)[_connectionIds][key] = connectionId;
73
+
74
+ _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].verifyClient(connectionId, req).then(({
75
+ verified,
76
+ statusCode
77
+ }) => {
78
+ try {
79
+ if (!verified) {
80
+ cb(false, statusCode);
81
+ return;
82
+ }
83
+
84
+ cb(true);
85
+ } catch (e) {
86
+ (0, _debugLog.default)(`Error verifying`, e);
87
+ cb(false);
88
+ }
89
+ });
90
+ }
42
91
  });
43
92
  server.on('connection', (webSocketClient, request) => {
44
- console.log('received connection');
45
- const connectionId = (0, _index.createUniqueId)();
46
- (0, _debugLog.default)(`connect:${connectionId}`);
47
-
48
- _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addClient(webSocketClient, request, connectionId);
93
+ if (this.log) {
94
+ this.log.notice('received connection');
95
+ } else {
96
+ console.log('received connection');
97
+ }
98
+
99
+ const {
100
+ headers
101
+ } = request;
102
+ const key = headers['sec-websocket-key'];
103
+
104
+ const connectionId = _classPrivateFieldLooseBase(this, _connectionIds)[_connectionIds][key];
105
+
106
+ if (this.log) {
107
+ this.log.debug(`connect:${connectionId}`);
108
+ } else {
109
+ (0, _debugLog.default)(`connect:${connectionId}`);
110
+ }
111
+
112
+ _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addClient(webSocketClient, connectionId);
49
113
  });
50
114
  }
51
115
 
@@ -56,14 +120,18 @@ class WebSocketServer {
56
120
  websocketPort
57
121
  } = _classPrivateFieldLooseBase(this, _options)[_options];
58
122
 
59
- (0, _serverlessLog.default)(`Offline [websocket] listening on ws${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
123
+ if (this.log) {
124
+ this.log.notice(`Offline [websocket] listening on ws${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
125
+ } else {
126
+ (0, _serverlessLog.default)(`Offline [websocket] listening on ws${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
127
+ }
60
128
  } // no-op, we're re-using the http server
61
129
 
62
130
 
63
131
  stop() {}
64
132
 
65
133
  addRoute(functionKey, webSocketEvent) {
66
- _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addRoute(functionKey, webSocketEvent.route); // serverlessLog(`route '${route}'`)
134
+ _classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addRoute(functionKey, webSocketEvent); // serverlessLog(`route '${route}'`)
67
135
 
68
136
  }
69
137
 
@@ -9,7 +9,8 @@ var _debugLog = _interopRequireDefault(require("../../../../debugLog.js"));
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- function catchAllRoute() {
12
+ function catchAllRoute(v3Utils) {
13
+ const log = v3Utils && v3Utils.log;
13
14
  return {
14
15
  method: 'GET',
15
16
  path: '/{path*}',
@@ -18,7 +19,13 @@ function catchAllRoute() {
18
19
  const {
19
20
  url
20
21
  } = request;
21
- (0, _debugLog.default)(`got GET to ${url}`);
22
+
23
+ if (log) {
24
+ log.debug(`got GET to ${url}`);
25
+ } else {
26
+ (0, _debugLog.default)(`got GET to ${url}`);
27
+ }
28
+
22
29
  return h.response(null).code(426);
23
30
  }
24
31
 
@@ -11,7 +11,7 @@ var id = 0;
11
11
 
12
12
  function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
13
13
 
14
- var _webSocketClients = _classPrivateFieldLooseKey("webSocketClients");
14
+ var _webSocketClients = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketClients");
15
15
 
16
16
  class ConnectionsController {
17
17
  constructor(webSocketClients) {