@binance/common 1.2.0 → 1.2.2
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.
- package/dist/index.d.mts +29 -2
- package/dist/index.d.ts +29 -2
- package/dist/index.js +67 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -122,6 +122,39 @@ var setSearchParams = function(url, ...objects) {
|
|
|
122
122
|
var toPathString = function(url) {
|
|
123
123
|
return url.pathname + url.search + url.hash;
|
|
124
124
|
};
|
|
125
|
+
function normalizeScientificNumbers(obj) {
|
|
126
|
+
if (Array.isArray(obj)) {
|
|
127
|
+
return obj.map((item) => normalizeScientificNumbers(item));
|
|
128
|
+
} else if (typeof obj === "object" && obj !== null) {
|
|
129
|
+
const result = {};
|
|
130
|
+
for (const key of Object.keys(obj)) {
|
|
131
|
+
result[key] = normalizeScientificNumbers(obj[key]);
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
} else if (typeof obj === "number") {
|
|
135
|
+
if (!Number.isFinite(obj)) return obj;
|
|
136
|
+
const abs = Math.abs(obj);
|
|
137
|
+
if (abs === 0 || abs >= 1e-6 && abs < 1e21) return String(obj);
|
|
138
|
+
const isNegative = obj < 0;
|
|
139
|
+
const [rawMantissa, rawExponent] = abs.toExponential().split("e");
|
|
140
|
+
const exponent = +rawExponent;
|
|
141
|
+
const digits = rawMantissa.replace(".", "");
|
|
142
|
+
if (exponent < 0) {
|
|
143
|
+
const zeros = "0".repeat(Math.abs(exponent) - 1);
|
|
144
|
+
return (isNegative ? "-" : "") + "0." + zeros + digits;
|
|
145
|
+
} else {
|
|
146
|
+
const pad = exponent - (digits.length - 1);
|
|
147
|
+
if (pad >= 0) {
|
|
148
|
+
return (isNegative ? "-" : "") + digits + "0".repeat(pad);
|
|
149
|
+
} else {
|
|
150
|
+
const point = digits.length + pad;
|
|
151
|
+
return (isNegative ? "-" : "") + digits.slice(0, point) + "." + digits.slice(point);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
return obj;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
125
158
|
var shouldRetryRequest = function(error, method, retriesLeft) {
|
|
126
159
|
const isRetriableMethod = ["GET", "DELETE"].includes(method ?? "");
|
|
127
160
|
const isRetriableStatus = [500, 502, 503, 504].includes(
|
|
@@ -283,7 +316,7 @@ var sendRequest = function(configuration, endpoint, method, params = {}, timeUni
|
|
|
283
316
|
method,
|
|
284
317
|
...configuration?.baseOptions
|
|
285
318
|
};
|
|
286
|
-
const localVarQueryParameter = { ...params };
|
|
319
|
+
const localVarQueryParameter = { ...normalizeScientificNumbers(params) };
|
|
287
320
|
if (options.isSigned) {
|
|
288
321
|
const timestamp = getTimestamp();
|
|
289
322
|
localVarQueryParameter["timestamp"] = timestamp;
|
|
@@ -354,7 +387,7 @@ function buildUserAgent(packageName, packageVersion) {
|
|
|
354
387
|
function buildWebsocketAPIMessage(configuration, method, payload, options, skipAuth = false) {
|
|
355
388
|
const id = payload.id && /^[0-9a-f]{32}$/.test(payload.id) ? payload.id : randomString();
|
|
356
389
|
delete payload.id;
|
|
357
|
-
let params = removeEmptyValue(payload);
|
|
390
|
+
let params = normalizeScientificNumbers(removeEmptyValue(payload));
|
|
358
391
|
if ((options.withApiKey || options.isSigned) && !skipAuth) params.apiKey = configuration.apiKey;
|
|
359
392
|
if (options.isSigned) {
|
|
360
393
|
params.timestamp = getTimestamp();
|
|
@@ -377,7 +410,7 @@ function parseCustomHeaders(headers) {
|
|
|
377
410
|
for (const [rawName, rawValue] of Object.entries(headers || {})) {
|
|
378
411
|
const name = rawName.trim();
|
|
379
412
|
if (forbidden.has(name.toLowerCase())) {
|
|
380
|
-
|
|
413
|
+
Logger.getInstance().warn(`Dropping forbidden header: ${name}`);
|
|
381
414
|
continue;
|
|
382
415
|
}
|
|
383
416
|
try {
|
|
@@ -597,33 +630,27 @@ var Logger = class _Logger {
|
|
|
597
630
|
"warn" /* WARN */,
|
|
598
631
|
"error" /* ERROR */
|
|
599
632
|
];
|
|
633
|
+
const envLevel = process.env.LOG_LEVEL?.toLowerCase();
|
|
634
|
+
this.minLogLevel = envLevel && this.isValidLogLevel(envLevel) ? envLevel : "info" /* INFO */;
|
|
600
635
|
}
|
|
601
636
|
static getInstance() {
|
|
602
|
-
if (!_Logger.instance)
|
|
603
|
-
_Logger.instance = new _Logger();
|
|
604
|
-
}
|
|
637
|
+
if (!_Logger.instance) _Logger.instance = new _Logger();
|
|
605
638
|
return _Logger.instance;
|
|
606
639
|
}
|
|
607
640
|
setMinLogLevel(level) {
|
|
608
|
-
if (!this.isValidLogLevel(level)) {
|
|
609
|
-
throw new Error(`Invalid log level: ${level}`);
|
|
610
|
-
}
|
|
641
|
+
if (!this.isValidLogLevel(level)) throw new Error(`Invalid log level: ${level}`);
|
|
611
642
|
this.minLogLevel = level;
|
|
612
643
|
}
|
|
613
644
|
isValidLogLevel(level) {
|
|
614
645
|
return this.levelsOrder.includes(level);
|
|
615
646
|
}
|
|
616
647
|
log(level, ...message) {
|
|
617
|
-
if (level === "" /* NONE */ || !this.allowLevelLog(level))
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
648
|
+
if (level === "" /* NONE */ || !this.allowLevelLog(level)) return;
|
|
620
649
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
621
650
|
console[level](`[${timestamp}] [${level.toLowerCase()}]`, ...message);
|
|
622
651
|
}
|
|
623
652
|
allowLevelLog(level) {
|
|
624
|
-
if (!this.isValidLogLevel(level)) {
|
|
625
|
-
throw new Error(`Invalid log level: ${level}`);
|
|
626
|
-
}
|
|
653
|
+
if (!this.isValidLogLevel(level)) throw new Error(`Invalid log level: ${level}`);
|
|
627
654
|
const currentLevelIndex = this.levelsOrder.indexOf(level);
|
|
628
655
|
const minLevelIndex = this.levelsOrder.indexOf(this.minLogLevel);
|
|
629
656
|
return currentLevelIndex >= minLevelIndex;
|
|
@@ -816,12 +843,16 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
|
|
|
816
843
|
*/
|
|
817
844
|
async closeConnectionGracefully(WebsocketConnectionToClose, connection) {
|
|
818
845
|
if (!WebsocketConnectionToClose || !connection) return;
|
|
819
|
-
this.logger.debug(
|
|
846
|
+
this.logger.debug(
|
|
847
|
+
`Waiting for pending requests to complete before disconnecting websocket on connection ${connection.id}.`
|
|
848
|
+
);
|
|
820
849
|
const closePromise = new Promise((resolve) => {
|
|
821
850
|
this.scheduleTimer(
|
|
822
851
|
WebsocketConnectionToClose,
|
|
823
852
|
() => {
|
|
824
|
-
this.logger.warn(
|
|
853
|
+
this.logger.warn(
|
|
854
|
+
`Force-closing websocket connection after 30 seconds on connection ${connection.id}.`
|
|
855
|
+
);
|
|
825
856
|
resolve();
|
|
826
857
|
},
|
|
827
858
|
3e4
|
|
@@ -830,7 +861,9 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
|
|
|
830
861
|
WebsocketConnectionToClose,
|
|
831
862
|
() => {
|
|
832
863
|
if (connection.pendingRequests.size === 0) {
|
|
833
|
-
this.logger.debug(
|
|
864
|
+
this.logger.debug(
|
|
865
|
+
`All pending requests completed, closing websocket connection on connection ${connection.id}.`
|
|
866
|
+
);
|
|
834
867
|
resolve();
|
|
835
868
|
}
|
|
836
869
|
},
|
|
@@ -839,7 +872,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
|
|
|
839
872
|
);
|
|
840
873
|
});
|
|
841
874
|
await closePromise;
|
|
842
|
-
this.logger.info(
|
|
875
|
+
this.logger.info(`Closing Websocket connection on connection ${connection.id}.`);
|
|
843
876
|
WebsocketConnectionToClose.close();
|
|
844
877
|
this.cleanup(WebsocketConnectionToClose);
|
|
845
878
|
}
|
|
@@ -859,7 +892,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
|
|
|
859
892
|
req.payload,
|
|
860
893
|
req.options
|
|
861
894
|
);
|
|
862
|
-
this.logger.debug(`Session re-logon
|
|
895
|
+
this.logger.debug(`Session re-logon on connection ${connection.id}`, data);
|
|
863
896
|
try {
|
|
864
897
|
await this.send(
|
|
865
898
|
JSON.stringify(data),
|
|
@@ -868,12 +901,12 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
|
|
|
868
901
|
this.configuration.timeout,
|
|
869
902
|
connection
|
|
870
903
|
);
|
|
904
|
+
this.logger.debug(
|
|
905
|
+
`Session re-logon on connection ${connection.id} was successful.`
|
|
906
|
+
);
|
|
871
907
|
connection.isSessionLoggedOn = true;
|
|
872
908
|
} catch (err) {
|
|
873
|
-
this.logger.error(
|
|
874
|
-
`Session re-logon with connection id ${connection.id} failed:`,
|
|
875
|
-
err
|
|
876
|
-
);
|
|
909
|
+
this.logger.error(`Session re-logon on connection ${connection.id} failed:`, err);
|
|
877
910
|
}
|
|
878
911
|
}
|
|
879
912
|
}
|
|
@@ -1237,8 +1270,9 @@ var WebsocketAPIBase = class extends WebsocketCommon {
|
|
|
1237
1270
|
if (!this.isConnected()) {
|
|
1238
1271
|
throw new Error("Not connected");
|
|
1239
1272
|
}
|
|
1240
|
-
const
|
|
1241
|
-
const
|
|
1273
|
+
const isSessionReq = options.isSessionLogon || options.isSessionLogout;
|
|
1274
|
+
const connections = isSessionReq ? this.getAvailableConnections() : [this.getConnection()];
|
|
1275
|
+
const skipAuth = isSessionReq ? false : this.configuration.autoSessionReLogon && connections[0].isSessionLoggedOn;
|
|
1242
1276
|
const data = buildWebsocketAPIMessage(
|
|
1243
1277
|
this.configuration,
|
|
1244
1278
|
method,
|
|
@@ -1258,7 +1292,7 @@ var WebsocketAPIBase = class extends WebsocketCommon {
|
|
|
1258
1292
|
)
|
|
1259
1293
|
)
|
|
1260
1294
|
);
|
|
1261
|
-
if (
|
|
1295
|
+
if (isSessionReq && this.configuration.autoSessionReLogon) {
|
|
1262
1296
|
connections.forEach((connection) => {
|
|
1263
1297
|
if (options.isSessionLogon) {
|
|
1264
1298
|
connection.isSessionLoggedOn = true;
|
|
@@ -1269,7 +1303,7 @@ var WebsocketAPIBase = class extends WebsocketCommon {
|
|
|
1269
1303
|
}
|
|
1270
1304
|
});
|
|
1271
1305
|
}
|
|
1272
|
-
return connections.length === 1 ? responses[0] : responses;
|
|
1306
|
+
return connections.length === 1 && !isSessionReq ? responses[0] : responses;
|
|
1273
1307
|
}
|
|
1274
1308
|
};
|
|
1275
1309
|
var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
@@ -1341,7 +1375,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1341
1375
|
params: streams,
|
|
1342
1376
|
id: id && /^[0-9a-f]{32}$/.test(id) ? id : randomString()
|
|
1343
1377
|
};
|
|
1344
|
-
this.logger.
|
|
1378
|
+
this.logger.debug("SUBSCRIBE", payload);
|
|
1345
1379
|
this.send(JSON.stringify(payload), void 0, false, 0, connection);
|
|
1346
1380
|
}
|
|
1347
1381
|
/**
|
|
@@ -1432,7 +1466,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1432
1466
|
connectionStreamMap.forEach((streams2, connection) => {
|
|
1433
1467
|
if (!this.isConnected(connection)) {
|
|
1434
1468
|
this.logger.info(
|
|
1435
|
-
`Connection is not ready. Queuing subscription for streams: ${streams2}`
|
|
1469
|
+
`Connection ${connection.id} is not ready. Queuing subscription for streams: ${streams2}`
|
|
1436
1470
|
);
|
|
1437
1471
|
connection.pendingSubscriptions?.push(...streams2);
|
|
1438
1472
|
return;
|
|
@@ -1461,7 +1495,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1461
1495
|
params: [stream2],
|
|
1462
1496
|
id: id && /^[0-9a-f]{32}$/.test(id) ? id : randomString()
|
|
1463
1497
|
};
|
|
1464
|
-
this.logger.
|
|
1498
|
+
this.logger.debug("UNSUBSCRIBE", payload);
|
|
1465
1499
|
this.send(JSON.stringify(payload), void 0, false, 0, connection);
|
|
1466
1500
|
this.streamConnectionMap.delete(stream2);
|
|
1467
1501
|
this.streamCallbackMap.delete(stream2);
|
|
@@ -1581,6 +1615,7 @@ export {
|
|
|
1581
1615
|
getSignature,
|
|
1582
1616
|
getTimestamp,
|
|
1583
1617
|
httpRequestFunction,
|
|
1618
|
+
normalizeScientificNumbers,
|
|
1584
1619
|
parseCustomHeaders,
|
|
1585
1620
|
parseRateLimitHeaders,
|
|
1586
1621
|
randomString,
|