@binance/common 1.2.1 → 1.2.3

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.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
- console.warn(`Dropping forbidden header: ${name}`);
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;
@@ -750,10 +777,24 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
750
777
  * @returns Timer handle
751
778
  */
752
779
  scheduleTimer(connection, callback, delay2, type = "timeout") {
753
- const timer = type === "timeout" ? setTimeout(callback, delay2) : setInterval(callback, delay2);
754
- if (!this.connectionTimers.has(connection))
755
- this.connectionTimers.set(connection, /* @__PURE__ */ new Set());
756
- this.connectionTimers.get(connection)?.add({ timer, type });
780
+ let timers = this.connectionTimers.get(connection);
781
+ if (!timers) {
782
+ timers = /* @__PURE__ */ new Set();
783
+ this.connectionTimers.set(connection, timers);
784
+ }
785
+ const timerRecord = { type };
786
+ const wrappedTimeout = () => {
787
+ try {
788
+ callback();
789
+ } finally {
790
+ timers.delete(timerRecord);
791
+ }
792
+ };
793
+ let timer;
794
+ if (type === "timeout") timer = setTimeout(wrappedTimeout, delay2);
795
+ else timer = setInterval(callback, delay2);
796
+ timerRecord.timer = timer;
797
+ timers.add(timerRecord);
757
798
  return timer;
758
799
  }
759
800
  /**
@@ -1015,13 +1056,13 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
1015
1056
  this.onMessage(data.toString(), targetConnection);
1016
1057
  });
1017
1058
  ws.on("ping", () => {
1018
- this.logger.info("Received PING from server");
1059
+ this.logger.debug("Received PING from server");
1019
1060
  this.emit("ping");
1020
1061
  ws.pong();
1021
- this.logger.info("Responded PONG to server's PING message");
1062
+ this.logger.debug("Responded PONG to server's PING message");
1022
1063
  });
1023
1064
  ws.on("pong", () => {
1024
- this.logger.info("Received PONG from server");
1065
+ this.logger.debug("Received PONG from server");
1025
1066
  this.emit("pong");
1026
1067
  });
1027
1068
  ws.on("error", (err) => {
@@ -1101,7 +1142,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
1101
1142
  this.logger.warn("Ping only can be sent when connection is ready.");
1102
1143
  return;
1103
1144
  }
1104
- this.logger.info("Sending PING to all connected Websocket servers.");
1145
+ this.logger.debug("Sending PING to all connected Websocket servers.");
1105
1146
  connectedConnections.forEach((connection) => {
1106
1147
  if (connection.ws) {
1107
1148
  connection.ws.ping();
@@ -1123,7 +1164,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
1123
1164
  */
1124
1165
  send(payload, id, promiseBased = true, timeout = 5e3, connection) {
1125
1166
  if (!this.isConnected(connection)) {
1126
- const errorMsg = "Send can only be sent when connection is ready.";
1167
+ const errorMsg = "Unable to send message \u2014 connection is not available.";
1127
1168
  this.logger.warn(errorMsg);
1128
1169
  if (promiseBased) return Promise.reject(new Error(errorMsg));
1129
1170
  else throw new Error(errorMsg);
@@ -1139,17 +1180,22 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
1139
1180
  if (promiseBased) {
1140
1181
  return new Promise((resolve, reject) => {
1141
1182
  if (!id) return reject(new Error("id is required for promise-based sending."));
1142
- connectionToUse.pendingRequests.set(id, { resolve, reject });
1143
- this.scheduleTimer(
1144
- connectionToUse.ws,
1145
- () => {
1146
- if (connectionToUse.pendingRequests.has(id)) {
1147
- connectionToUse.pendingRequests.delete(id);
1148
- reject(new Error(`Request timeout for id: ${id}`));
1149
- }
1183
+ const timeoutHandle = setTimeout(() => {
1184
+ if (connectionToUse.pendingRequests.has(id)) {
1185
+ connectionToUse.pendingRequests.delete(id);
1186
+ reject(new Error(`Request timeout for id: ${id}`));
1187
+ }
1188
+ }, timeout);
1189
+ connectionToUse.pendingRequests.set(id, {
1190
+ resolve: (v) => {
1191
+ clearTimeout(timeoutHandle);
1192
+ resolve(v);
1150
1193
  },
1151
- timeout
1152
- );
1194
+ reject: (e) => {
1195
+ clearTimeout(timeoutHandle);
1196
+ reject(e);
1197
+ }
1198
+ });
1153
1199
  });
1154
1200
  }
1155
1201
  }
@@ -1229,13 +1275,13 @@ var WebsocketAPIBase = class extends WebsocketCommon {
1229
1275
  reject(new Error("Websocket connection timed out"));
1230
1276
  }, 1e4);
1231
1277
  this.connectPool(this.prepareURL(this.configuration.wsURL)).then(() => {
1232
- clearTimeout(timeout);
1233
1278
  this.isConnecting = false;
1234
1279
  resolve();
1235
1280
  }).catch((error) => {
1236
- clearTimeout(timeout);
1237
1281
  this.isConnecting = false;
1238
1282
  reject(error);
1283
+ }).finally(() => {
1284
+ clearTimeout(timeout);
1239
1285
  });
1240
1286
  });
1241
1287
  }
@@ -1348,7 +1394,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1348
1394
  params: streams,
1349
1395
  id: id && /^[0-9a-f]{32}$/.test(id) ? id : randomString()
1350
1396
  };
1351
- this.logger.info("SUBSCRIBE", payload);
1397
+ this.logger.debug("SUBSCRIBE", payload);
1352
1398
  this.send(JSON.stringify(payload), void 0, false, 0, connection);
1353
1399
  }
1354
1400
  /**
@@ -1406,13 +1452,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1406
1452
  const timeout = setTimeout(() => {
1407
1453
  reject(new Error("Websocket connection timed out"));
1408
1454
  }, 1e4);
1409
- this.connectPool(this.prepareURL(streams)).then(() => {
1410
- clearTimeout(timeout);
1411
- resolve();
1412
- }).catch((error) => {
1413
- clearTimeout(timeout);
1414
- reject(error);
1415
- });
1455
+ this.connectPool(this.prepareURL(streams)).then(() => resolve()).catch((error) => reject(error)).finally(() => clearTimeout(timeout));
1416
1456
  });
1417
1457
  }
1418
1458
  /**
@@ -1468,7 +1508,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1468
1508
  params: [stream2],
1469
1509
  id: id && /^[0-9a-f]{32}$/.test(id) ? id : randomString()
1470
1510
  };
1471
- this.logger.info("UNSUBSCRIBE", payload);
1511
+ this.logger.debug("UNSUBSCRIBE", payload);
1472
1512
  this.send(JSON.stringify(payload), void 0, false, 0, connection);
1473
1513
  this.streamConnectionMap.delete(stream2);
1474
1514
  this.streamCallbackMap.delete(stream2);
@@ -1588,6 +1628,7 @@ export {
1588
1628
  getSignature,
1589
1629
  getTimestamp,
1590
1630
  httpRequestFunction,
1631
+ normalizeScientificNumbers,
1591
1632
  parseCustomHeaders,
1592
1633
  parseRateLimitHeaders,
1593
1634
  randomString,