fix(socket): update serialization for circular binary socket messages (#16311)

This commit is contained in:
Zach Bloomquist
2021-05-05 16:09:46 -04:00
committed by GitHub
parent 9b75852151
commit 8f68d4e662
9 changed files with 262 additions and 169 deletions
+1 -1
View File
@@ -254,7 +254,7 @@
"**/@types/react": "16.9.50",
"**/jquery": "3.1.1",
"**/pretty-format": "26.4.0",
"**/socket.io-parser": "4.0.2",
"**/socket.io-parser": "4.0.4",
"vue-template-compiler": "2.6.12"
}
}
@@ -64,6 +64,15 @@ describe('driver/src/cypress/utils', () => {
it('symbol', function () {
expect(this.str(Symbol.iterator)).to.eq('Symbol')
})
it('circular', function () {
const obj = {}
obj.obj = obj
// at this point, there is no special formatting for a circular object, we simply fall back to String() on recursion failure
expect(this.str(obj)).to.be.a.string
})
})
context('Arrays', () => {
+5 -1
View File
@@ -194,7 +194,11 @@ module.exports = {
return `Object{${len}}`
}
return this.stringifyActualObj(value)
try {
return this.stringifyActualObj(value)
} catch (err) {
return String(value)
}
}
if (_.isSymbol(value)) {
+1 -1
View File
@@ -1,7 +1,7 @@
import { client } from '@packages/socket/lib/browser'
export const connect = (host, path, extraOpts = {}) => {
return client.io(host, {
return client(host, {
path,
transports: ['websocket'],
...extraOpts,
+2 -2
View File
@@ -15,8 +15,8 @@
},
"dependencies": {
"circular-json": "0.5.9",
"socket.io": "3.0.4",
"socket.io-client": "3.0.4"
"socket.io": "4.0.1",
"socket.io-client": "4.0.1"
},
"devDependencies": {
"chai": "3.5.0",
@@ -1,122 +0,0 @@
diff --git a/node_modules/socket.io-parser/dist/binary.js b/node_modules/socket.io-parser/dist/binary.js
index a908023..708fd3c 100644
--- a/node_modules/socket.io-parser/dist/binary.js
+++ b/node_modules/socket.io-parser/dist/binary.js
@@ -36,7 +36,7 @@ function _deconstructPacket(data, buffers) {
else if (typeof data === "object" && !(data instanceof Date)) {
const newData = {};
for (const key in data) {
- if (data.hasOwnProperty(key)) {
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
newData[key] = _deconstructPacket(data[key], buffers);
}
}
@@ -71,7 +71,7 @@ function _reconstructPacket(data, buffers) {
}
else if (typeof data === "object") {
for (const key in data) {
- if (data.hasOwnProperty(key)) {
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
data[key] = _reconstructPacket(data[key], buffers);
}
}
diff --git a/node_modules/socket.io-parser/dist/index.js b/node_modules/socket.io-parser/dist/index.js
index cb7af17..1290ca2 100644
--- a/node_modules/socket.io-parser/dist/index.js
+++ b/node_modules/socket.io-parser/dist/index.js
@@ -1,6 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Decoder = exports.Encoder = exports.PacketType = exports.protocol = void 0;
+const CircularJSON = require('circular-json')
const Emitter = require("component-emitter");
const binary_1 = require("./binary");
const is_binary_1 = require("./is-binary");
@@ -66,7 +67,7 @@ class Encoder {
}
// json data
if (null != obj.data) {
- str += JSON.stringify(obj.data);
+ str += CircularJSON.stringify(obj.data);
}
debug("encoded %j as %s", obj, str);
return str;
@@ -232,7 +233,7 @@ class Decoder extends Emitter {
exports.Decoder = Decoder;
function tryParse(str) {
try {
- return JSON.parse(str);
+ return CircularJSON.parse(str);
}
catch (e) {
return false;
diff --git a/node_modules/socket.io-parser/dist/is-binary.js b/node_modules/socket.io-parser/dist/is-binary.js
index 4b7c234..88f36f2 100644
--- a/node_modules/socket.io-parser/dist/is-binary.js
+++ b/node_modules/socket.io-parser/dist/is-binary.js
@@ -1,12 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasBinary = exports.isBinary = void 0;
-const withNativeArrayBuffer = typeof ArrayBuffer === "function";
-const isView = (obj) => {
- return typeof ArrayBuffer.isView === "function"
- ? ArrayBuffer.isView(obj)
- : obj.buffer instanceof ArrayBuffer;
+var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function';
+var withNativeArrayBuffer = typeof ArrayBuffer === 'function';
+
+var isView = function (obj) {
+ return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : (obj.buffer instanceof ArrayBuffer);
};
+
const toString = Object.prototype.toString;
const withNativeBlob = typeof Blob === "function" ||
(typeof Blob !== "undefined" &&
@@ -21,17 +22,25 @@ const withNativeFile = typeof File === "function" ||
*/
function isBinary(obj) {
return ((withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))) ||
- (withNativeBlob && obj instanceof Blob) ||
- (withNativeFile && obj instanceof File));
+ (withNativeBlob && obj instanceof Blob) ||
+ (withNativeFile && obj instanceof File)) ||
+ (withNativeBuffer && Buffer.isBuffer(obj))
}
exports.isBinary = isBinary;
-function hasBinary(obj, toJSON) {
+function hasBinaryCircular(obj) {
+ return hasBinary(obj, [])
+}
+function hasBinary(obj, known) {
if (!obj || typeof obj !== "object") {
return false;
}
+ if (known.indexOf(obj) >= 0) {
+ return false
+ }
+ known.push(obj)
if (Array.isArray(obj)) {
for (let i = 0, l = obj.length; i < l; i++) {
- if (hasBinary(obj[i])) {
+ if (hasBinary(obj[i], known)) {
return true;
}
}
@@ -43,13 +52,13 @@ function hasBinary(obj, toJSON) {
if (obj.toJSON &&
typeof obj.toJSON === "function" &&
arguments.length === 1) {
- return hasBinary(obj.toJSON(), true);
+ return hasBinary(obj.toJSON(), known);
}
for (const key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {
+ if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key], known)) {
return true;
}
}
return false;
}
-exports.hasBinary = hasBinary;
+exports.hasBinary = hasBinaryCircular;
@@ -0,0 +1,162 @@
diff --git a/node_modules/socket.io-parser/dist/binary.js b/node_modules/socket.io-parser/dist/binary.js
index a908023..99e0215 100644
--- a/node_modules/socket.io-parser/dist/binary.js
+++ b/node_modules/socket.io-parser/dist/binary.js
@@ -13,12 +13,12 @@ function deconstructPacket(packet) {
const buffers = [];
const packetData = packet.data;
const pack = packet;
- pack.data = _deconstructPacket(packetData, buffers);
+ pack.data = _deconstructPacket(packetData, buffers, [], new WeakMap());
pack.attachments = buffers.length; // number of binary 'attachments'
return { packet: pack, buffers: buffers };
}
exports.deconstructPacket = deconstructPacket;
-function _deconstructPacket(data, buffers) {
+function _deconstructPacket(data, buffers, known, retvals) {
if (!data)
return data;
if (is_binary_1.isBinary(data)) {
@@ -26,18 +26,27 @@ function _deconstructPacket(data, buffers) {
buffers.push(data);
return placeholder;
}
- else if (Array.isArray(data)) {
+ else if (retvals.has(data)) {
+ return retvals.get(data)
+ }
+ else if (known.includes(data)) {
+ return data;
+ }
+ known.push(data)
+ if (Array.isArray(data)) {
const newData = new Array(data.length);
+ retvals.set(data, newData)
for (let i = 0; i < data.length; i++) {
- newData[i] = _deconstructPacket(data[i], buffers);
+ newData[i] = _deconstructPacket(data[i], buffers, known, retvals);
}
return newData;
}
else if (typeof data === "object" && !(data instanceof Date)) {
const newData = {};
+ retvals.set(data, newData)
for (const key in data) {
- if (data.hasOwnProperty(key)) {
- newData[key] = _deconstructPacket(data[key], buffers);
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
+ newData[key] = _deconstructPacket(data[key], buffers, known, retvals);
}
}
return newData;
@@ -53,26 +62,29 @@ function _deconstructPacket(data, buffers) {
* @public
*/
function reconstructPacket(packet, buffers) {
- packet.data = _reconstructPacket(packet.data, buffers);
+ packet.data = _reconstructPacket(packet.data, buffers, []);
packet.attachments = undefined; // no longer useful
return packet;
}
exports.reconstructPacket = reconstructPacket;
-function _reconstructPacket(data, buffers) {
+function _reconstructPacket(data, buffers, known) {
if (!data)
return data;
if (data && data._placeholder) {
return buffers[data.num]; // appropriate buffer (should be natural order anyway)
+ } else if (known.includes(data)) {
+ return data
}
- else if (Array.isArray(data)) {
+ known.push(data)
+ if (Array.isArray(data)) {
for (let i = 0; i < data.length; i++) {
- data[i] = _reconstructPacket(data[i], buffers);
+ data[i] = _reconstructPacket(data[i], buffers, known);
}
}
else if (typeof data === "object") {
for (const key in data) {
if (data.hasOwnProperty(key)) {
- data[key] = _reconstructPacket(data[key], buffers);
+ data[key] = _reconstructPacket(data[key], buffers, known);
}
}
}
diff --git a/node_modules/socket.io-parser/dist/index.js b/node_modules/socket.io-parser/dist/index.js
index 0ef9f80..4cd787e 100644
--- a/node_modules/socket.io-parser/dist/index.js
+++ b/node_modules/socket.io-parser/dist/index.js
@@ -5,6 +5,7 @@ const Emitter = require("component-emitter");
const binary_1 = require("./binary");
const is_binary_1 = require("./is-binary");
const debug = require("debug")("socket.io-parser");
+const CircularJSON = require('circular-json')
/**
* Protocol version.
*
@@ -66,7 +67,7 @@ class Encoder {
}
// json data
if (null != obj.data) {
- str += JSON.stringify(obj.data);
+ str += CircularJSON.stringify(obj.data);
}
debug("encoded %j as %s", obj, str);
return str;
@@ -232,7 +233,7 @@ class Decoder extends Emitter {
exports.Decoder = Decoder;
function tryParse(str) {
try {
- return JSON.parse(str);
+ return CircularJSON.parse(str);
}
catch (e) {
return false;
diff --git a/node_modules/socket.io-parser/dist/is-binary.js b/node_modules/socket.io-parser/dist/is-binary.js
index 4b7c234..95469f7 100644
--- a/node_modules/socket.io-parser/dist/is-binary.js
+++ b/node_modules/socket.io-parser/dist/is-binary.js
@@ -1,6 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasBinary = exports.isBinary = void 0;
+const withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function';
const withNativeArrayBuffer = typeof ArrayBuffer === "function";
const isView = (obj) => {
return typeof ArrayBuffer.isView === "function"
@@ -22,13 +23,18 @@ const withNativeFile = typeof File === "function" ||
function isBinary(obj) {
return ((withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))) ||
(withNativeBlob && obj instanceof Blob) ||
- (withNativeFile && obj instanceof File));
+ (withNativeFile && obj instanceof File)) ||
+ (withNativeBuffer && Buffer.isBuffer(obj));
}
exports.isBinary = isBinary;
-function hasBinary(obj, toJSON) {
+function hasBinary(obj, known = []) {
if (!obj || typeof obj !== "object") {
return false;
}
+ if (known.includes(obj)) {
+ return false
+ }
+ known.push(obj)
if (Array.isArray(obj)) {
for (let i = 0, l = obj.length; i < l; i++) {
if (hasBinary(obj[i])) {
@@ -43,10 +49,10 @@ function hasBinary(obj, toJSON) {
if (obj.toJSON &&
typeof obj.toJSON === "function" &&
arguments.length === 1) {
- return hasBinary(obj.toJSON(), true);
+ return hasBinary(obj.toJSON(), known);
}
for (const key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {
+ if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key], known)) {
return true;
}
}
+40 -3
View File
@@ -71,7 +71,7 @@ describe('Socket', function () {
decoder.on('decoded', (packet) => {
obj.data = originalData
obj.attachments = undefined
expect(obj).to.eql(packet)
expect(packet).to.eql(obj)
done()
})
@@ -104,7 +104,44 @@ describe('Socket', function () {
decoder.on('decoded', (packet) => {
obj.data = originalData
expect(obj).to.eql(packet)
expect(packet.data[1] === packet.data[1].foo.circularObj).to.be.true
expect(packet).to.eql(obj)
done()
})
for (let i = 0; i < encodedPackets.length; i++) {
decoder.add(encodedPackets[i])
}
})
it('correctly encodes and decodes circular data containing binary', (done) => {
const encoder = new parser.Encoder()
const circularObj = {
foo: {},
bin: Buffer.from('abc', 'utf8'),
}
circularObj.foo.circularObj = circularObj
const obj = {
type: PacketType.EVENT,
data: ['a', circularObj],
id: 23,
nsp: '/cool',
}
const originalData = obj.data
const encodedPackets = encoder.encode(obj)
const decoder = new parser.Decoder()
decoder.on('decoded', (packet) => {
obj.data = originalData
obj.attachments = undefined
expect(packet.data[1] === packet.data[1].foo.circularObj).to.be.true
expect(packet).to.eql(obj)
done()
})
@@ -136,7 +173,7 @@ describe('Socket', function () {
decoder.on('decoded', (packet) => {
obj.data = originalData
obj.attachments = undefined
expect(obj).to.eql(packet)
expect(packet).to.eql(obj)
done()
})
+42 -39
View File
@@ -2811,7 +2811,7 @@
"@jest/types@^26.3.0", "@jest/types@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
@@ -7197,7 +7197,12 @@
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*", "@types/node@14.14.31", "@types/node@>= 8", "@types/node@^14.0.10", "@types/node@^14.14.31", "@types/node@^14.14.7", "@types/node@^14.6.2":
"@types/node@*", "@types/node@>= 8", "@types/node@>=10.0.0":
version "15.0.1"
resolved "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz#ef34dea0881028d11398be5bf4e856743e3dc35a"
integrity sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==
"@types/node@14.14.31", "@types/node@^14.0.10", "@types/node@^14.14.31", "@types/node@^14.6.2":
version "14.14.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
@@ -10961,7 +10966,7 @@ backbone@1.4.0:
dependencies:
underscore ">=1.8.3"
backo2@1.0.2:
backo2@1.0.2, backo2@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
@@ -16129,10 +16134,10 @@ engine.io-client@~3.5.0:
xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
engine.io-client@~4.0.0:
version "4.0.6"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-4.0.6.tgz#ba6f97033dc2179dea79b982d516d13b50ab4d3b"
integrity sha512-5lPh8rrhxIruo5ZlgFt31KM626o5OCXrCHBweieWWuVicDtnYdz/iR93k6N9k0Xs61WrYxZKIWXzeSaJF6fpNA==
engine.io-client@~5.0.0:
version "5.0.1"
resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-5.0.1.tgz#9470fc6655c9789c5c0aa1a0e7e7d9ae9753a798"
integrity sha512-CQtGN3YwfvbxVwpPugcsHe5rHT4KgT49CEcQppNtu9N7WxbPN0MAG27lGaem7bvtCFtGNLSL+GEqXsFSz36jTg==
dependencies:
base64-arraybuffer "0.1.4"
component-emitter "~1.3.0"
@@ -16142,7 +16147,6 @@ engine.io-client@~4.0.0:
parseqs "0.0.6"
parseuri "0.0.6"
ws "~7.4.2"
xmlhttprequest-ssl "~1.5.4"
yeast "0.1.2"
engine.io-parser@~2.2.0:
@@ -16175,10 +16179,10 @@ engine.io@~3.5.0:
engine.io-parser "~2.2.0"
ws "~7.4.2"
engine.io@~4.0.0:
version "4.0.6"
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.0.6.tgz#7268635d64e2154ab5e7f9ef967ad1744a4c41a9"
integrity sha512-rf7HAVZpcRrcKEKddgIzYUnwg0g5HE1RvJaTLwkcfJmce4g+po8aMuE6vxzp6JwlK8FEq/vi0KWN6tA585DjaA==
engine.io@~5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/engine.io/-/engine.io-5.0.0.tgz#470dc94a8a4907fa4d2cd1fa6611426afcee61bf"
integrity sha512-BATIdDV3H1SrE9/u2BAotvsmjJg0t1P4+vGedImSs1lkFAtQdvk4Ev1y4LDiPF7BPWgXWEG+NDY+nLvW3UrMWw==
dependencies:
accepts "~1.3.4"
base64id "2.0.0"
@@ -33693,10 +33697,10 @@ socket.io-adapter@~1.1.0:
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9"
integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==
socket.io-adapter@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz#372b7cde7a535fc4f4f0d5ac7f73952a3062d438"
integrity sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ==
socket.io-adapter@~2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.2.0.tgz#43af9157c4609e74b8addc6867873ac7eb48fda2"
integrity sha512-rG49L+FwaVEwuAdeBRq49M97YI3ElVabJPzvHT9S6a2CWhDKnjSFasvwAwSYPRhQzfn4NtDIbCaGYgOCOU/rlg==
socket.io-client@2.4.0, socket.io-client@^2.2.0:
version "2.4.0"
@@ -33715,43 +33719,42 @@ socket.io-client@2.4.0, socket.io-client@^2.2.0:
socket.io-parser "~3.3.0"
to-array "0.1.4"
socket.io-client@3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-3.0.4.tgz#c0203419a9f71e1360ef92a31301e80260e94bb9"
integrity sha512-qMvBuS+W9JIN2mkfAWDCxuIt+jpIKDf8C0604zEqx1JrPaPSS6cN0F3B2GYWC83TqBeVJXW66GFxWV3KD88n0Q==
socket.io-client@4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.0.1.tgz#8f3bf4ce9282dda1741a4ed0f726b412944e012b"
integrity sha512-6AkaEG5zrVuSVW294cH1chioag9i1OqnCYjKwTc3EBGXbnyb98Lw7yMa40ifLjFj3y6fsFKsd0llbUZUCRf3Qw==
dependencies:
"@types/component-emitter" "^1.2.10"
backo2 "1.0.2"
component-bind "1.0.0"
backo2 "~1.0.2"
component-emitter "~1.3.0"
debug "~4.1.0"
engine.io-client "~4.0.0"
debug "~4.3.1"
engine.io-client "~5.0.0"
parseuri "0.0.6"
socket.io-parser "~4.0.1"
socket.io-parser "~4.0.4"
socket.io-parser@4.0.2, socket.io-parser@~3.3.0, socket.io-parser@~3.4.0, socket.io-parser@~4.0.1:
version "4.0.2"
resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.2.tgz#3d021a9c86671bb079e7c6c806db6a1d9b1bc780"
integrity sha512-Bs3IYHDivwf+bAAuW/8xwJgIiBNtlvnjYRc4PbXgniLmcP1BrakBoq/QhO24rgtgW7VZ7uAaswRGxutUnlAK7g==
socket.io-parser@4.0.4, socket.io-parser@~3.3.0, socket.io-parser@~3.4.0, socket.io-parser@~4.0.3, socket.io-parser@~4.0.4:
version "4.0.4"
resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0"
integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==
dependencies:
"@types/component-emitter" "^1.2.10"
component-emitter "~1.3.0"
debug "~4.1.0"
debug "~4.3.1"
socket.io@3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.0.4.tgz#20130a80b57e48dadb671f22e3776047cc7f9d53"
integrity sha512-Vj1jUoO75WGc9txWd311ZJJqS9Dr8QtNJJ7gk2r7dcM/yGe9sit7qOijQl3GAwhpBOz/W8CwkD7R6yob07nLbA==
socket.io@4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.0.1.tgz#d2e01cf3780d810b66182b3fbef08a04a4ccf924"
integrity sha512-g8eZB9lV0f4X4gndG0k7YZAywOg1VxYgCUspS4V+sDqsgI/duqd0AW84pKkbGj/wQwxrqrEq+VZrspRfTbHTAQ==
dependencies:
"@types/cookie" "^0.4.0"
"@types/cors" "^2.8.8"
"@types/node" "^14.14.7"
"@types/node" ">=10.0.0"
accepts "~1.3.4"
base64id "~2.0.0"
debug "~4.1.0"
engine.io "~4.0.0"
socket.io-adapter "~2.0.3"
socket.io-parser "~4.0.1"
debug "~4.3.1"
engine.io "~5.0.0"
socket.io-adapter "~2.2.0"
socket.io-parser "~4.0.3"
socket.io@^2.2.0:
version "2.4.1"