serverless-spy 2.2.2 → 2.2.4

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.
@@ -6,12 +6,19 @@ const { Duplex } = require('stream');
6
6
  const { randomFillSync } = require('crypto');
7
7
 
8
8
  const PerMessageDeflate = require('./permessage-deflate');
9
- const { EMPTY_BUFFER } = require('./constants');
10
- const { isValidStatusCode } = require('./validation');
9
+ const { EMPTY_BUFFER, kWebSocket, NOOP } = require('./constants');
10
+ const { isBlob, isValidStatusCode } = require('./validation');
11
11
  const { mask: applyMask, toBuffer } = require('./buffer-util');
12
12
 
13
13
  const kByteLength = Symbol('kByteLength');
14
14
  const maskBuffer = Buffer.alloc(4);
15
+ const RANDOM_POOL_SIZE = 8 * 1024;
16
+ let randomPool;
17
+ let randomPoolPointer = RANDOM_POOL_SIZE;
18
+
19
+ const DEFAULT = 0;
20
+ const DEFLATING = 1;
21
+ const GET_BLOB_DATA = 2;
15
22
 
16
23
  /**
17
24
  * HyBi Sender implementation.
@@ -39,8 +46,10 @@ class Sender {
39
46
  this._compress = false;
40
47
 
41
48
  this._bufferedBytes = 0;
42
- this._deflating = false;
43
49
  this._queue = [];
50
+ this._state = DEFAULT;
51
+ this.onerror = NOOP;
52
+ this[kWebSocket] = undefined;
44
53
  }
45
54
 
46
55
  /**
@@ -76,7 +85,24 @@ class Sender {
76
85
  if (options.generateMask) {
77
86
  options.generateMask(mask);
78
87
  } else {
79
- randomFillSync(mask, 0, 4);
88
+ if (randomPoolPointer === RANDOM_POOL_SIZE) {
89
+ /* istanbul ignore else */
90
+ if (randomPool === undefined) {
91
+ //
92
+ // This is lazily initialized because server-sent frames must not
93
+ // be masked so it may never be used.
94
+ //
95
+ randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
96
+ }
97
+
98
+ randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
99
+ randomPoolPointer = 0;
100
+ }
101
+
102
+ mask[0] = randomPool[randomPoolPointer++];
103
+ mask[1] = randomPool[randomPoolPointer++];
104
+ mask[2] = randomPool[randomPoolPointer++];
105
+ mask[3] = randomPool[randomPoolPointer++];
80
106
  }
81
107
 
82
108
  skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
@@ -190,7 +216,7 @@ class Sender {
190
216
  rsv1: false
191
217
  };
192
218
 
193
- if (this._deflating) {
219
+ if (this._state !== DEFAULT) {
194
220
  this.enqueue([this.dispatch, buf, false, options, cb]);
195
221
  } else {
196
222
  this.sendFrame(Sender.frame(buf, options), cb);
@@ -212,6 +238,9 @@ class Sender {
212
238
  if (typeof data === 'string') {
213
239
  byteLength = Buffer.byteLength(data);
214
240
  readOnly = false;
241
+ } else if (isBlob(data)) {
242
+ byteLength = data.size;
243
+ readOnly = false;
215
244
  } else {
216
245
  data = toBuffer(data);
217
246
  byteLength = data.length;
@@ -233,7 +262,13 @@ class Sender {
233
262
  rsv1: false
234
263
  };
235
264
 
236
- if (this._deflating) {
265
+ if (isBlob(data)) {
266
+ if (this._state !== DEFAULT) {
267
+ this.enqueue([this.getBlobData, data, false, options, cb]);
268
+ } else {
269
+ this.getBlobData(data, false, options, cb);
270
+ }
271
+ } else if (this._state !== DEFAULT) {
237
272
  this.enqueue([this.dispatch, data, false, options, cb]);
238
273
  } else {
239
274
  this.sendFrame(Sender.frame(data, options), cb);
@@ -255,6 +290,9 @@ class Sender {
255
290
  if (typeof data === 'string') {
256
291
  byteLength = Buffer.byteLength(data);
257
292
  readOnly = false;
293
+ } else if (isBlob(data)) {
294
+ byteLength = data.size;
295
+ readOnly = false;
258
296
  } else {
259
297
  data = toBuffer(data);
260
298
  byteLength = data.length;
@@ -276,7 +314,13 @@ class Sender {
276
314
  rsv1: false
277
315
  };
278
316
 
279
- if (this._deflating) {
317
+ if (isBlob(data)) {
318
+ if (this._state !== DEFAULT) {
319
+ this.enqueue([this.getBlobData, data, false, options, cb]);
320
+ } else {
321
+ this.getBlobData(data, false, options, cb);
322
+ }
323
+ } else if (this._state !== DEFAULT) {
280
324
  this.enqueue([this.dispatch, data, false, options, cb]);
281
325
  } else {
282
326
  this.sendFrame(Sender.frame(data, options), cb);
@@ -310,6 +354,9 @@ class Sender {
310
354
  if (typeof data === 'string') {
311
355
  byteLength = Buffer.byteLength(data);
312
356
  readOnly = false;
357
+ } else if (isBlob(data)) {
358
+ byteLength = data.size;
359
+ readOnly = false;
313
360
  } else {
314
361
  data = toBuffer(data);
315
362
  byteLength = data.length;
@@ -337,40 +384,94 @@ class Sender {
337
384
 
338
385
  if (options.fin) this._firstFragment = true;
339
386
 
340
- if (perMessageDeflate) {
341
- const opts = {
342
- [kByteLength]: byteLength,
343
- fin: options.fin,
344
- generateMask: this._generateMask,
345
- mask: options.mask,
346
- maskBuffer: this._maskBuffer,
347
- opcode,
348
- readOnly,
349
- rsv1
350
- };
351
-
352
- if (this._deflating) {
353
- this.enqueue([this.dispatch, data, this._compress, opts, cb]);
387
+ const opts = {
388
+ [kByteLength]: byteLength,
389
+ fin: options.fin,
390
+ generateMask: this._generateMask,
391
+ mask: options.mask,
392
+ maskBuffer: this._maskBuffer,
393
+ opcode,
394
+ readOnly,
395
+ rsv1
396
+ };
397
+
398
+ if (isBlob(data)) {
399
+ if (this._state !== DEFAULT) {
400
+ this.enqueue([this.getBlobData, data, this._compress, opts, cb]);
354
401
  } else {
355
- this.dispatch(data, this._compress, opts, cb);
402
+ this.getBlobData(data, this._compress, opts, cb);
356
403
  }
404
+ } else if (this._state !== DEFAULT) {
405
+ this.enqueue([this.dispatch, data, this._compress, opts, cb]);
357
406
  } else {
358
- this.sendFrame(
359
- Sender.frame(data, {
360
- [kByteLength]: byteLength,
361
- fin: options.fin,
362
- generateMask: this._generateMask,
363
- mask: options.mask,
364
- maskBuffer: this._maskBuffer,
365
- opcode,
366
- readOnly,
367
- rsv1: false
368
- }),
369
- cb
370
- );
407
+ this.dispatch(data, this._compress, opts, cb);
371
408
  }
372
409
  }
373
410
 
411
+ /**
412
+ * Gets the contents of a blob as binary data.
413
+ *
414
+ * @param {Blob} blob The blob
415
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
416
+ * the data
417
+ * @param {Object} options Options object
418
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
419
+ * FIN bit
420
+ * @param {Function} [options.generateMask] The function used to generate the
421
+ * masking key
422
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
423
+ * `data`
424
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
425
+ * key
426
+ * @param {Number} options.opcode The opcode
427
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
428
+ * modified
429
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
430
+ * RSV1 bit
431
+ * @param {Function} [cb] Callback
432
+ * @private
433
+ */
434
+ getBlobData(blob, compress, options, cb) {
435
+ this._bufferedBytes += options[kByteLength];
436
+ this._state = GET_BLOB_DATA;
437
+
438
+ blob
439
+ .arrayBuffer()
440
+ .then((arrayBuffer) => {
441
+ if (this._socket.destroyed) {
442
+ const err = new Error(
443
+ 'The socket was closed while the blob was being read'
444
+ );
445
+
446
+ //
447
+ // `callCallbacks` is called in the next tick to ensure that errors
448
+ // that might be thrown in the callbacks behave like errors thrown
449
+ // outside the promise chain.
450
+ //
451
+ process.nextTick(callCallbacks, this, err, cb);
452
+ return;
453
+ }
454
+
455
+ this._bufferedBytes -= options[kByteLength];
456
+ const data = toBuffer(arrayBuffer);
457
+
458
+ if (!compress) {
459
+ this._state = DEFAULT;
460
+ this.sendFrame(Sender.frame(data, options), cb);
461
+ this.dequeue();
462
+ } else {
463
+ this.dispatch(data, compress, options, cb);
464
+ }
465
+ })
466
+ .catch((err) => {
467
+ //
468
+ // `onError` is called in the next tick for the same reason that
469
+ // `callCallbacks` above is.
470
+ //
471
+ process.nextTick(onError, this, err, cb);
472
+ });
473
+ }
474
+
374
475
  /**
375
476
  * Dispatches a message.
376
477
  *
@@ -403,27 +504,19 @@ class Sender {
403
504
  const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
404
505
 
405
506
  this._bufferedBytes += options[kByteLength];
406
- this._deflating = true;
507
+ this._state = DEFLATING;
407
508
  perMessageDeflate.compress(data, options.fin, (_, buf) => {
408
509
  if (this._socket.destroyed) {
409
510
  const err = new Error(
410
511
  'The socket was closed while data was being compressed'
411
512
  );
412
513
 
413
- if (typeof cb === 'function') cb(err);
414
-
415
- for (let i = 0; i < this._queue.length; i++) {
416
- const params = this._queue[i];
417
- const callback = params[params.length - 1];
418
-
419
- if (typeof callback === 'function') callback(err);
420
- }
421
-
514
+ callCallbacks(this, err, cb);
422
515
  return;
423
516
  }
424
517
 
425
518
  this._bufferedBytes -= options[kByteLength];
426
- this._deflating = false;
519
+ this._state = DEFAULT;
427
520
  options.readOnly = false;
428
521
  this.sendFrame(Sender.frame(buf, options), cb);
429
522
  this.dequeue();
@@ -436,7 +529,7 @@ class Sender {
436
529
  * @private
437
530
  */
438
531
  dequeue() {
439
- while (!this._deflating && this._queue.length) {
532
+ while (this._state === DEFAULT && this._queue.length) {
440
533
  const params = this._queue.shift();
441
534
 
442
535
  this._bufferedBytes -= params[3][kByteLength];
@@ -475,3 +568,35 @@ class Sender {
475
568
  }
476
569
 
477
570
  module.exports = Sender;
571
+
572
+ /**
573
+ * Calls queued callbacks with an error.
574
+ *
575
+ * @param {Sender} sender The `Sender` instance
576
+ * @param {Error} err The error to call the callbacks with
577
+ * @param {Function} [cb] The first callback
578
+ * @private
579
+ */
580
+ function callCallbacks(sender, err, cb) {
581
+ if (typeof cb === 'function') cb(err);
582
+
583
+ for (let i = 0; i < sender._queue.length; i++) {
584
+ const params = sender._queue[i];
585
+ const callback = params[params.length - 1];
586
+
587
+ if (typeof callback === 'function') callback(err);
588
+ }
589
+ }
590
+
591
+ /**
592
+ * Handles a `Sender` error.
593
+ *
594
+ * @param {Sender} sender The `Sender` instance
595
+ * @param {Error} err The error
596
+ * @param {Function} [cb] The first pending callback
597
+ * @private
598
+ */
599
+ function onError(sender, err, cb) {
600
+ callCallbacks(sender, err, cb);
601
+ sender.onerror(err);
602
+ }
@@ -2,6 +2,8 @@
2
2
 
3
3
  const { isUtf8 } = require('buffer');
4
4
 
5
+ const { hasBlob } = require('./constants');
6
+
5
7
  //
6
8
  // Allowed token characters:
7
9
  //
@@ -107,7 +109,27 @@ function _isValidUTF8(buf) {
107
109
  return true;
108
110
  }
109
111
 
112
+ /**
113
+ * Determines whether a value is a `Blob`.
114
+ *
115
+ * @param {*} value The value to be tested
116
+ * @return {Boolean} `true` if `value` is a `Blob`, else `false`
117
+ * @private
118
+ */
119
+ function isBlob(value) {
120
+ return (
121
+ hasBlob &&
122
+ typeof value === 'object' &&
123
+ typeof value.arrayBuffer === 'function' &&
124
+ typeof value.type === 'string' &&
125
+ typeof value.stream === 'function' &&
126
+ (value[Symbol.toStringTag] === 'Blob' ||
127
+ value[Symbol.toStringTag] === 'File')
128
+ );
129
+ }
130
+
110
131
  module.exports = {
132
+ isBlob,
111
133
  isValidStatusCode,
112
134
  isValidUTF8: _isValidUTF8,
113
135
  tokenChars
@@ -1,4 +1,4 @@
1
- /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$" }] */
1
+ /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$", "caughtErrors": "none" }] */
2
2
 
3
3
  'use strict';
4
4
 
@@ -29,7 +29,7 @@ class WebSocketServer extends EventEmitter {
29
29
  * Create a `WebSocketServer` instance.
30
30
  *
31
31
  * @param {Object} options Configuration options
32
- * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
32
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
33
33
  * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
34
34
  * multiple times in the same tick
35
35
  * @param {Boolean} [options.autoPong=true] Specifies whether or not to
@@ -60,7 +60,7 @@ class WebSocketServer extends EventEmitter {
60
60
  super();
61
61
 
62
62
  options = {
63
- allowSynchronousEvents: false,
63
+ allowSynchronousEvents: true,
64
64
  autoPong: true,
65
65
  maxPayload: 100 * 1024 * 1024,
66
66
  skipUTF8Validation: false,
@@ -235,6 +235,7 @@ class WebSocketServer extends EventEmitter {
235
235
  socket.on('error', socketOnError);
236
236
 
237
237
  const key = req.headers['sec-websocket-key'];
238
+ const upgrade = req.headers.upgrade;
238
239
  const version = +req.headers['sec-websocket-version'];
239
240
 
240
241
  if (req.method !== 'GET') {
@@ -243,13 +244,13 @@ class WebSocketServer extends EventEmitter {
243
244
  return;
244
245
  }
245
246
 
246
- if (req.headers.upgrade.toLowerCase() !== 'websocket') {
247
+ if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {
247
248
  const message = 'Invalid Upgrade header';
248
249
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
249
250
  return;
250
251
  }
251
252
 
252
- if (!key || !keyRegex.test(key)) {
253
+ if (key === undefined || !keyRegex.test(key)) {
253
254
  const message = 'Missing or invalid Sec-WebSocket-Key header';
254
255
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
255
256
  return;
@@ -1,4 +1,4 @@
1
- /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$" }] */
1
+ /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$", "caughtErrors": "none" }] */
2
2
 
3
3
  'use strict';
4
4
 
@@ -14,6 +14,8 @@ const { URL } = require('url');
14
14
  const PerMessageDeflate = require('./permessage-deflate');
15
15
  const Receiver = require('./receiver');
16
16
  const Sender = require('./sender');
17
+ const { isBlob } = require('./validation');
18
+
17
19
  const {
18
20
  BINARY_TYPES,
19
21
  EMPTY_BUFFER,
@@ -58,6 +60,7 @@ class WebSocket extends EventEmitter {
58
60
  this._closeFrameSent = false;
59
61
  this._closeMessage = EMPTY_BUFFER;
60
62
  this._closeTimer = null;
63
+ this._errorEmitted = false;
61
64
  this._extensions = {};
62
65
  this._paused = false;
63
66
  this._protocol = '';
@@ -90,9 +93,8 @@ class WebSocket extends EventEmitter {
90
93
  }
91
94
 
92
95
  /**
93
- * This deviates from the WHATWG interface since ws doesn't support the
94
- * required default "blob" type (instead we define a custom "nodebuffer"
95
- * type).
96
+ * For historical reasons, the custom "nodebuffer" type is used by the default
97
+ * instead of "blob".
96
98
  *
97
99
  * @type {String}
98
100
  */
@@ -213,11 +215,14 @@ class WebSocket extends EventEmitter {
213
215
  skipUTF8Validation: options.skipUTF8Validation
214
216
  });
215
217
 
216
- this._sender = new Sender(socket, this._extensions, options.generateMask);
218
+ const sender = new Sender(socket, this._extensions, options.generateMask);
219
+
217
220
  this._receiver = receiver;
221
+ this._sender = sender;
218
222
  this._socket = socket;
219
223
 
220
224
  receiver[kWebSocket] = this;
225
+ sender[kWebSocket] = this;
221
226
  socket[kWebSocket] = this;
222
227
 
223
228
  receiver.on('conclude', receiverOnConclude);
@@ -227,6 +232,8 @@ class WebSocket extends EventEmitter {
227
232
  receiver.on('ping', receiverOnPing);
228
233
  receiver.on('pong', receiverOnPong);
229
234
 
235
+ sender.onerror = senderOnError;
236
+
230
237
  //
231
238
  // These methods may not be available if `socket` is just a `Duplex`.
232
239
  //
@@ -322,13 +329,7 @@ class WebSocket extends EventEmitter {
322
329
  }
323
330
  });
324
331
 
325
- //
326
- // Specify a timeout for the closing handshake to complete.
327
- //
328
- this._closeTimer = setTimeout(
329
- this._socket.destroy.bind(this._socket),
330
- closeTimeout
331
- );
332
+ setCloseTimer(this);
332
333
  }
333
334
 
334
335
  /**
@@ -623,7 +624,7 @@ module.exports = WebSocket;
623
624
  * @param {(String|URL)} address The URL to which to connect
624
625
  * @param {Array} protocols The subprotocols
625
626
  * @param {Object} [options] Connection options
626
- * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether any
627
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether any
627
628
  * of the `'message'`, `'ping'`, and `'pong'` events can be emitted multiple
628
629
  * times in the same tick
629
630
  * @param {Boolean} [options.autoPong=true] Specifies whether or not to
@@ -652,7 +653,7 @@ module.exports = WebSocket;
652
653
  */
653
654
  function initAsClient(websocket, address, protocols, options) {
654
655
  const opts = {
655
- allowSynchronousEvents: false,
656
+ allowSynchronousEvents: true,
656
657
  autoPong: true,
657
658
  protocolVersion: protocolVersions[1],
658
659
  maxPayload: 100 * 1024 * 1024,
@@ -661,7 +662,6 @@ function initAsClient(websocket, address, protocols, options) {
661
662
  followRedirects: false,
662
663
  maxRedirects: 10,
663
664
  ...options,
664
- createConnection: undefined,
665
665
  socketPath: undefined,
666
666
  hostname: undefined,
667
667
  protocol: undefined,
@@ -732,7 +732,8 @@ function initAsClient(websocket, address, protocols, options) {
732
732
  const protocolSet = new Set();
733
733
  let perMessageDeflate;
734
734
 
735
- opts.createConnection = isSecure ? tlsConnect : netConnect;
735
+ opts.createConnection =
736
+ opts.createConnection || (isSecure ? tlsConnect : netConnect);
736
737
  opts.defaultPort = opts.defaultPort || defaultPort;
737
738
  opts.port = parsedUrl.port || defaultPort;
738
739
  opts.host = parsedUrl.hostname.startsWith('[')
@@ -928,7 +929,9 @@ function initAsClient(websocket, address, protocols, options) {
928
929
 
929
930
  req = websocket._req = null;
930
931
 
931
- if (res.headers.upgrade.toLowerCase() !== 'websocket') {
932
+ const upgrade = res.headers.upgrade;
933
+
934
+ if (upgrade === undefined || upgrade.toLowerCase() !== 'websocket') {
932
935
  abortHandshake(websocket, socket, 'Invalid Upgrade header');
933
936
  return;
934
937
  }
@@ -1030,6 +1033,11 @@ function initAsClient(websocket, address, protocols, options) {
1030
1033
  */
1031
1034
  function emitErrorAndClose(websocket, err) {
1032
1035
  websocket._readyState = WebSocket.CLOSING;
1036
+ //
1037
+ // The following assignment is practically useless and is done only for
1038
+ // consistency.
1039
+ //
1040
+ websocket._errorEmitted = true;
1033
1041
  websocket.emit('error', err);
1034
1042
  websocket.emitClose();
1035
1043
  }
@@ -1110,7 +1118,7 @@ function abortHandshake(websocket, stream, message) {
1110
1118
  */
1111
1119
  function sendAfterClose(websocket, data, cb) {
1112
1120
  if (data) {
1113
- const length = toBuffer(data).length;
1121
+ const length = isBlob(data) ? data.size : toBuffer(data).length;
1114
1122
 
1115
1123
  //
1116
1124
  // The `_bufferedAmount` property is used only when the peer is a client and
@@ -1186,7 +1194,10 @@ function receiverOnError(err) {
1186
1194
  websocket.close(err[kStatusCode]);
1187
1195
  }
1188
1196
 
1189
- websocket.emit('error', err);
1197
+ if (!websocket._errorEmitted) {
1198
+ websocket._errorEmitted = true;
1199
+ websocket.emit('error', err);
1200
+ }
1190
1201
  }
1191
1202
 
1192
1203
  /**
@@ -1242,6 +1253,47 @@ function resume(stream) {
1242
1253
  stream.resume();
1243
1254
  }
1244
1255
 
1256
+ /**
1257
+ * The `Sender` error event handler.
1258
+ *
1259
+ * @param {Error} The error
1260
+ * @private
1261
+ */
1262
+ function senderOnError(err) {
1263
+ const websocket = this[kWebSocket];
1264
+
1265
+ if (websocket.readyState === WebSocket.CLOSED) return;
1266
+ if (websocket.readyState === WebSocket.OPEN) {
1267
+ websocket._readyState = WebSocket.CLOSING;
1268
+ setCloseTimer(websocket);
1269
+ }
1270
+
1271
+ //
1272
+ // `socket.end()` is used instead of `socket.destroy()` to allow the other
1273
+ // peer to finish sending queued data. There is no need to set a timer here
1274
+ // because `CLOSING` means that it is already set or not needed.
1275
+ //
1276
+ this._socket.end();
1277
+
1278
+ if (!websocket._errorEmitted) {
1279
+ websocket._errorEmitted = true;
1280
+ websocket.emit('error', err);
1281
+ }
1282
+ }
1283
+
1284
+ /**
1285
+ * Set a timer to destroy the underlying raw socket of a WebSocket.
1286
+ *
1287
+ * @param {WebSocket} websocket The WebSocket instance
1288
+ * @private
1289
+ */
1290
+ function setCloseTimer(websocket) {
1291
+ websocket._closeTimer = setTimeout(
1292
+ websocket._socket.destroy.bind(websocket._socket),
1293
+ closeTimeout
1294
+ );
1295
+ }
1296
+
1245
1297
  /**
1246
1298
  * The listener of the socket `'close'` event.
1247
1299
  *
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ws",
3
- "version": "8.16.0",
3
+ "version": "8.18.0",
4
4
  "description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
5
5
  "keywords": [
6
6
  "HyBi",
@@ -40,7 +40,7 @@
40
40
  "scripts": {
41
41
  "test": "nyc --reporter=lcov --reporter=text mocha --throw-deprecation test/*.test.js",
42
42
  "integration": "mocha --throw-deprecation test/*.integration.js",
43
- "lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yaml,yml}\""
43
+ "lint": "eslint . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yaml,yml}\""
44
44
  },
45
45
  "peerDependencies": {
46
46
  "bufferutil": "^4.0.1",
@@ -57,9 +57,10 @@
57
57
  "devDependencies": {
58
58
  "benchmark": "^2.1.4",
59
59
  "bufferutil": "^4.0.1",
60
- "eslint": "^8.0.0",
60
+ "eslint": "^9.0.0",
61
61
  "eslint-config-prettier": "^9.0.0",
62
62
  "eslint-plugin-prettier": "^5.0.0",
63
+ "globals": "^15.0.0",
63
64
  "mocha": "^8.4.0",
64
65
  "nyc": "^15.0.0",
65
66
  "prettier": "^3.0.0",
package/package.json CHANGED
@@ -50,7 +50,7 @@
50
50
  "@types/jest": "^29.5.11",
51
51
  "@types/node": "^20.10.4",
52
52
  "@types/uuid": "^9.0.7",
53
- "@types/ws": "^8.5.10",
53
+ "@types/ws": "^8.5.12",
54
54
  "@typescript-eslint/eslint-plugin": "^6.12.0",
55
55
  "@typescript-eslint/parser": "^6.12.0",
56
56
  "aws-cdk-lib": "^2.124",
@@ -111,7 +111,7 @@
111
111
  "json-format-highlight": "^1.0.4",
112
112
  "open": "^9.1.0",
113
113
  "serialize-error": "^11.0.3",
114
- "ws": "^8.15.1"
114
+ "ws": "^8.17.1"
115
115
  },
116
116
  "keywords": [
117
117
  "cdk",
@@ -136,7 +136,7 @@
136
136
  "require": "./lib/index.js"
137
137
  },
138
138
  "license": "MPL-2.0",
139
- "version": "2.2.2",
139
+ "version": "2.2.4",
140
140
  "types": "lib/index.d.ts",
141
141
  "stability": "stable",
142
142
  "jsii": {