@tdengine/websocket 3.2.2 → 3.3.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 (275) hide show
  1. package/lib/package.json +64 -0
  2. package/lib/src/client/retryConfig.d.ts +10 -0
  3. package/lib/src/client/retryConfig.d.ts.map +1 -0
  4. package/lib/src/client/retryConfig.js +46 -0
  5. package/lib/src/client/wsClient.d.ts +24 -7
  6. package/lib/src/client/wsClient.d.ts.map +1 -1
  7. package/lib/src/client/wsClient.js +164 -137
  8. package/lib/src/client/wsConnector.d.ts +55 -9
  9. package/lib/src/client/wsConnector.d.ts.map +1 -1
  10. package/lib/src/client/wsConnector.js +522 -102
  11. package/lib/src/client/wsConnectorPool.d.ts +5 -1
  12. package/lib/src/client/wsConnectorPool.d.ts.map +1 -1
  13. package/lib/src/client/wsConnectorPool.js +67 -52
  14. package/lib/src/client/wsEventCallback.d.ts +3 -0
  15. package/lib/src/client/wsEventCallback.d.ts.map +1 -1
  16. package/lib/src/client/wsEventCallback.js +67 -8
  17. package/lib/src/client/wsResponse.d.ts +0 -3
  18. package/lib/src/client/wsResponse.d.ts.map +1 -1
  19. package/lib/src/client/wsResponse.js +0 -3
  20. package/lib/src/common/addressConnectionTracker.d.ts +11 -0
  21. package/lib/src/common/addressConnectionTracker.d.ts.map +1 -0
  22. package/lib/src/common/addressConnectionTracker.js +53 -0
  23. package/lib/src/common/config.d.ts +3 -0
  24. package/lib/src/common/config.d.ts.map +1 -1
  25. package/lib/src/common/config.js +6 -0
  26. package/lib/src/common/constant.d.ts +1 -0
  27. package/lib/src/common/constant.d.ts.map +1 -1
  28. package/lib/src/common/constant.js +6 -1
  29. package/lib/src/common/dsn.d.ts +30 -0
  30. package/lib/src/common/dsn.d.ts.map +1 -0
  31. package/lib/src/common/dsn.js +221 -0
  32. package/lib/src/common/taosResult.d.ts.map +1 -1
  33. package/lib/src/common/taosResult.js +0 -5
  34. package/lib/src/common/urlParser.d.ts +32 -0
  35. package/lib/src/common/urlParser.d.ts.map +1 -0
  36. package/lib/src/common/urlParser.js +201 -0
  37. package/lib/src/common/utils.d.ts +6 -1
  38. package/lib/src/common/utils.d.ts.map +1 -1
  39. package/lib/src/common/utils.js +74 -22
  40. package/lib/src/index.d.ts.map +1 -1
  41. package/lib/src/sql/wsSql.d.ts.map +1 -1
  42. package/lib/src/sql/wsSql.js +2 -2
  43. package/lib/src/stmt/FieldBindParams.d.ts.map +1 -1
  44. package/lib/src/stmt/wsColumnInfo.d.ts.map +1 -1
  45. package/lib/src/stmt/wsParams1.d.ts.map +1 -1
  46. package/lib/src/stmt/wsParams1.js +26 -26
  47. package/lib/src/stmt/wsParams2.d.ts.map +1 -1
  48. package/lib/src/stmt/wsParams2.js +0 -3
  49. package/lib/src/stmt/wsParamsBase.d.ts.map +1 -1
  50. package/lib/src/stmt/wsProto.d.ts.map +1 -1
  51. package/lib/src/stmt/wsProto.js +16 -16
  52. package/lib/src/stmt/wsStmt1.d.ts.map +1 -1
  53. package/lib/src/stmt/wsStmt2.d.ts +12 -4
  54. package/lib/src/stmt/wsStmt2.d.ts.map +1 -1
  55. package/lib/src/stmt/wsStmt2.js +182 -64
  56. package/lib/src/stmt/wsTableInfo.d.ts.map +1 -1
  57. package/lib/src/tmq/config.d.ts +4 -2
  58. package/lib/src/tmq/config.d.ts.map +1 -1
  59. package/lib/src/tmq/config.js +30 -13
  60. package/lib/src/tmq/constant.d.ts +4 -0
  61. package/lib/src/tmq/constant.d.ts.map +1 -1
  62. package/lib/src/tmq/constant.js +4 -0
  63. package/lib/src/tmq/tmqResponse.d.ts.map +1 -1
  64. package/lib/src/tmq/tmqResponse.js +1 -4
  65. package/lib/src/tmq/wsTmq.d.ts +4 -1
  66. package/lib/src/tmq/wsTmq.d.ts.map +1 -1
  67. package/lib/src/tmq/wsTmq.js +55 -27
  68. package/lib/test/bulkPulling/a.test.d.ts +2 -0
  69. package/lib/test/bulkPulling/a.test.d.ts.map +1 -0
  70. package/lib/test/bulkPulling/a.test.js +166 -0
  71. package/lib/test/bulkPulling/cloud.tmq.test.js +3 -2
  72. package/lib/test/bulkPulling/decimal.test.js +8 -8
  73. package/lib/test/bulkPulling/dsn.test.d.ts +2 -0
  74. package/lib/test/bulkPulling/dsn.test.d.ts.map +1 -0
  75. package/lib/test/bulkPulling/dsn.test.js +397 -0
  76. package/lib/test/bulkPulling/queryTables.test.js +1 -1
  77. package/lib/test/bulkPulling/retryConfig.test.d.ts +2 -0
  78. package/lib/test/bulkPulling/retryConfig.test.d.ts.map +1 -0
  79. package/lib/test/bulkPulling/retryConfig.test.js +34 -0
  80. package/lib/test/bulkPulling/schemaless.test.js +15 -14
  81. package/lib/test/bulkPulling/sql.failover.test.d.ts +2 -0
  82. package/lib/test/bulkPulling/sql.failover.test.d.ts.map +1 -0
  83. package/lib/test/bulkPulling/sql.failover.test.js +338 -0
  84. package/lib/test/bulkPulling/sql.test.js +116 -44
  85. package/lib/test/bulkPulling/stmt1.func.test.js +31 -30
  86. package/lib/test/bulkPulling/stmt1.type.test.js +1 -1
  87. package/lib/test/bulkPulling/stmt2.failover.test.d.ts +2 -0
  88. package/lib/test/bulkPulling/stmt2.failover.test.d.ts.map +1 -0
  89. package/lib/test/bulkPulling/stmt2.failover.test.js +313 -0
  90. package/lib/test/bulkPulling/stmt2.func.test.js +37 -36
  91. package/lib/test/bulkPulling/stmt2.init.failover.test.d.ts +2 -0
  92. package/lib/test/bulkPulling/stmt2.init.failover.test.d.ts.map +1 -0
  93. package/lib/test/bulkPulling/stmt2.init.failover.test.js +50 -0
  94. package/lib/test/bulkPulling/stmt2.type.test.js +1 -1
  95. package/lib/test/bulkPulling/tmq.config.test.d.ts +2 -0
  96. package/lib/test/bulkPulling/tmq.config.test.d.ts.map +1 -0
  97. package/lib/test/bulkPulling/tmq.config.test.js +77 -0
  98. package/lib/test/bulkPulling/tmq.failover.test.d.ts +2 -0
  99. package/lib/test/bulkPulling/tmq.failover.test.d.ts.map +1 -0
  100. package/lib/test/bulkPulling/tmq.failover.test.js +404 -0
  101. package/lib/test/bulkPulling/tmq.test.js +135 -14
  102. package/lib/test/bulkPulling/urlParser.test.d.ts +2 -0
  103. package/lib/test/bulkPulling/urlParser.test.d.ts.map +1 -0
  104. package/lib/test/bulkPulling/urlParser.test.js +452 -0
  105. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.d.ts +2 -0
  106. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.d.ts.map +1 -0
  107. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.js +184 -0
  108. package/lib/test/bulkPulling/wsClient.recovery.test.d.ts +2 -0
  109. package/lib/test/bulkPulling/wsClient.recovery.test.d.ts.map +1 -0
  110. package/lib/test/bulkPulling/wsClient.recovery.test.js +104 -0
  111. package/lib/test/bulkPulling/wsConfig.dsn.test.d.ts +2 -0
  112. package/lib/test/bulkPulling/wsConfig.dsn.test.d.ts.map +1 -0
  113. package/lib/test/bulkPulling/wsConfig.dsn.test.js +39 -0
  114. package/lib/test/bulkPulling/wsConnectPool.test.js +7 -7
  115. package/lib/test/bulkPulling/wsConnector.failover.test.d.ts +2 -0
  116. package/lib/test/bulkPulling/wsConnector.failover.test.d.ts.map +1 -0
  117. package/lib/test/bulkPulling/wsConnector.failover.test.js +497 -0
  118. package/lib/test/bulkPulling/wsConnectorPool.key.test.d.ts +2 -0
  119. package/lib/test/bulkPulling/wsConnectorPool.key.test.d.ts.map +1 -0
  120. package/lib/test/bulkPulling/wsConnectorPool.key.test.js +52 -0
  121. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.d.ts +2 -0
  122. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.d.ts.map +1 -0
  123. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.js +28 -0
  124. package/lib/test/bulkPulling/wsEventCallback.test.d.ts +2 -0
  125. package/lib/test/bulkPulling/wsEventCallback.test.d.ts.map +1 -0
  126. package/lib/test/bulkPulling/wsEventCallback.test.js +54 -0
  127. package/lib/test/bulkPulling/wsProxy.failover.integration.test.d.ts +2 -0
  128. package/lib/test/bulkPulling/wsProxy.failover.integration.test.d.ts.map +1 -0
  129. package/lib/test/bulkPulling/wsProxy.failover.integration.test.js +120 -0
  130. package/lib/test/bulkPulling/wsProxy.failover.test.d.ts +2 -0
  131. package/lib/test/bulkPulling/wsProxy.failover.test.d.ts.map +1 -0
  132. package/lib/test/bulkPulling/wsProxy.failover.test.js +465 -0
  133. package/lib/test/client/wsClient.recovery.test.d.ts +2 -0
  134. package/lib/test/client/wsClient.recovery.test.d.ts.map +1 -0
  135. package/lib/test/client/wsClient.recovery.test.js +122 -0
  136. package/lib/test/client/wsConnectPool.test.d.ts +2 -0
  137. package/lib/test/client/wsConnectPool.test.d.ts.map +1 -0
  138. package/lib/test/client/wsConnectPool.test.js +147 -0
  139. package/lib/test/client/wsConnector.failover.test.d.ts +2 -0
  140. package/lib/test/client/wsConnector.failover.test.d.ts.map +1 -0
  141. package/lib/test/client/wsConnector.failover.test.js +681 -0
  142. package/lib/test/client/wsConnector.leastConnections.test.d.ts +2 -0
  143. package/lib/test/client/wsConnector.leastConnections.test.d.ts.map +1 -0
  144. package/lib/test/client/wsConnector.leastConnections.test.js +71 -0
  145. package/lib/test/client/wsConnectorPool.key.test.d.ts +2 -0
  146. package/lib/test/client/wsConnectorPool.key.test.d.ts.map +1 -0
  147. package/lib/test/client/wsConnectorPool.key.test.js +127 -0
  148. package/lib/test/client/wsEventCallback.test.d.ts +2 -0
  149. package/lib/test/client/wsEventCallback.test.d.ts.map +1 -0
  150. package/lib/test/client/wsEventCallback.test.js +98 -0
  151. package/lib/test/common/addressConnectionTracker.test.d.ts +2 -0
  152. package/lib/test/common/addressConnectionTracker.test.d.ts.map +1 -0
  153. package/lib/test/common/addressConnectionTracker.test.js +74 -0
  154. package/lib/test/common/dsn.test.d.ts +2 -0
  155. package/lib/test/common/dsn.test.d.ts.map +1 -0
  156. package/lib/test/common/dsn.test.js +406 -0
  157. package/lib/test/common/log.test.d.ts +2 -0
  158. package/lib/test/common/log.test.d.ts.map +1 -0
  159. package/lib/test/common/log.test.js +54 -0
  160. package/lib/test/common/utils.test.d.ts +2 -0
  161. package/lib/test/common/utils.test.d.ts.map +1 -0
  162. package/lib/test/common/utils.test.js +13 -0
  163. package/lib/test/common/wsConfig.dsn.test.d.ts +2 -0
  164. package/lib/test/common/wsConfig.dsn.test.d.ts.map +1 -0
  165. package/lib/test/common/wsConfig.dsn.test.js +39 -0
  166. package/lib/test/helpers/utils.d.ts +27 -0
  167. package/lib/test/helpers/utils.d.ts.map +1 -0
  168. package/lib/test/helpers/utils.js +341 -0
  169. package/lib/test/helpers/wsFailoverProxy.d.ts +109 -0
  170. package/lib/test/helpers/wsFailoverProxy.d.ts.map +1 -0
  171. package/lib/test/helpers/wsFailoverProxy.js +420 -0
  172. package/lib/test/helpers/wsProxy.d.ts +110 -0
  173. package/lib/test/helpers/wsProxy.d.ts.map +1 -0
  174. package/lib/test/helpers/wsProxy.js +429 -0
  175. package/lib/test/sql/core/decimal.test.d.ts +2 -0
  176. package/lib/test/sql/core/decimal.test.d.ts.map +1 -0
  177. package/lib/test/sql/core/decimal.test.js +153 -0
  178. package/lib/test/sql/core/queryTables.test.d.ts +2 -0
  179. package/lib/test/sql/core/queryTables.test.d.ts.map +1 -0
  180. package/lib/test/sql/core/queryTables.test.js +506 -0
  181. package/lib/test/sql/core/schemaless.test.d.ts +2 -0
  182. package/lib/test/sql/core/schemaless.test.d.ts.map +1 -0
  183. package/lib/test/sql/core/schemaless.test.js +102 -0
  184. package/lib/test/sql/core/sql.test.d.ts +2 -0
  185. package/lib/test/sql/core/sql.test.d.ts.map +1 -0
  186. package/lib/test/sql/core/sql.test.js +324 -0
  187. package/lib/test/sql/decimal.test.d.ts +2 -0
  188. package/lib/test/sql/decimal.test.d.ts.map +1 -0
  189. package/lib/test/sql/decimal.test.js +153 -0
  190. package/lib/test/sql/failover/sql.failover.test.d.ts +2 -0
  191. package/lib/test/sql/failover/sql.failover.test.d.ts.map +1 -0
  192. package/lib/test/sql/failover/sql.failover.test.js +341 -0
  193. package/lib/test/sql/queryTables.test.d.ts +2 -0
  194. package/lib/test/sql/queryTables.test.d.ts.map +1 -0
  195. package/lib/test/sql/queryTables.test.js +506 -0
  196. package/lib/test/sql/schemaless.test.d.ts +2 -0
  197. package/lib/test/sql/schemaless.test.d.ts.map +1 -0
  198. package/lib/test/sql/schemaless.test.js +102 -0
  199. package/lib/test/sql/sql.failover.test.d.ts +2 -0
  200. package/lib/test/sql/sql.failover.test.d.ts.map +1 -0
  201. package/lib/test/sql/sql.failover.test.js +341 -0
  202. package/lib/test/sql/sql.test.d.ts +2 -0
  203. package/lib/test/sql/sql.test.d.ts.map +1 -0
  204. package/lib/test/sql/sql.test.js +324 -0
  205. package/lib/test/stmt/failover/stmt2.failover.mock.test.d.ts +2 -0
  206. package/lib/test/stmt/failover/stmt2.failover.mock.test.d.ts.map +1 -0
  207. package/lib/test/stmt/failover/stmt2.failover.mock.test.js +341 -0
  208. package/lib/test/stmt/failover/stmt2.failover.test.d.ts +2 -0
  209. package/lib/test/stmt/failover/stmt2.failover.test.d.ts.map +1 -0
  210. package/lib/test/stmt/failover/stmt2.failover.test.js +384 -0
  211. package/lib/test/stmt/stmt1.func.test.d.ts +2 -0
  212. package/lib/test/stmt/stmt1.func.test.d.ts.map +1 -0
  213. package/lib/test/stmt/stmt1.func.test.js +418 -0
  214. package/lib/test/stmt/stmt1.type.test.d.ts +2 -0
  215. package/lib/test/stmt/stmt1.type.test.d.ts.map +1 -0
  216. package/lib/test/stmt/stmt1.type.test.js +399 -0
  217. package/lib/test/stmt/stmt2.failover.mock.test.d.ts +2 -0
  218. package/lib/test/stmt/stmt2.failover.mock.test.d.ts.map +1 -0
  219. package/lib/test/stmt/stmt2.failover.mock.test.js +341 -0
  220. package/lib/test/stmt/stmt2.failover.test.d.ts +2 -0
  221. package/lib/test/stmt/stmt2.failover.test.d.ts.map +1 -0
  222. package/lib/test/stmt/stmt2.failover.test.js +384 -0
  223. package/lib/test/stmt/stmt2.func.test.d.ts +2 -0
  224. package/lib/test/stmt/stmt2.func.test.d.ts.map +1 -0
  225. package/lib/test/stmt/stmt2.func.test.js +537 -0
  226. package/lib/test/stmt/stmt2.type.test.d.ts +2 -0
  227. package/lib/test/stmt/stmt2.type.test.d.ts.map +1 -0
  228. package/lib/test/stmt/stmt2.type.test.js +401 -0
  229. package/lib/test/stmt/v1/stmt1.func.test.d.ts +2 -0
  230. package/lib/test/stmt/v1/stmt1.func.test.d.ts.map +1 -0
  231. package/lib/test/stmt/v1/stmt1.func.test.js +418 -0
  232. package/lib/test/stmt/v1/stmt1.type.test.d.ts +2 -0
  233. package/lib/test/stmt/v1/stmt1.type.test.d.ts.map +1 -0
  234. package/lib/test/stmt/v1/stmt1.type.test.js +399 -0
  235. package/lib/test/stmt/v2/stmt2.func.test.d.ts +2 -0
  236. package/lib/test/stmt/v2/stmt2.func.test.d.ts.map +1 -0
  237. package/lib/test/stmt/v2/stmt2.func.test.js +537 -0
  238. package/lib/test/stmt/v2/stmt2.type.test.d.ts +2 -0
  239. package/lib/test/stmt/v2/stmt2.type.test.d.ts.map +1 -0
  240. package/lib/test/stmt/v2/stmt2.type.test.js +401 -0
  241. package/lib/test/tmq/cloud/cloud.tmq.test.d.ts +2 -0
  242. package/lib/test/tmq/cloud/cloud.tmq.test.d.ts.map +1 -0
  243. package/lib/test/tmq/cloud/cloud.tmq.test.js +84 -0
  244. package/lib/test/tmq/cloud/tmq.cloud.test.d.ts +2 -0
  245. package/lib/test/tmq/cloud/tmq.cloud.test.d.ts.map +1 -0
  246. package/lib/test/tmq/cloud/tmq.cloud.test.js +82 -0
  247. package/lib/test/tmq/core/tmq.config.test.d.ts +2 -0
  248. package/lib/test/tmq/core/tmq.config.test.d.ts.map +1 -0
  249. package/lib/test/tmq/core/tmq.config.test.js +83 -0
  250. package/lib/test/tmq/core/tmq.test.d.ts +2 -0
  251. package/lib/test/tmq/core/tmq.test.d.ts.map +1 -0
  252. package/lib/test/tmq/core/tmq.test.js +513 -0
  253. package/lib/test/tmq/failover/tmq.failover.test.d.ts +2 -0
  254. package/lib/test/tmq/failover/tmq.failover.test.d.ts.map +1 -0
  255. package/lib/test/tmq/failover/tmq.failover.test.js +404 -0
  256. package/lib/test/tmq/tmq.cloud.test.d.ts +2 -0
  257. package/lib/test/tmq/tmq.cloud.test.d.ts.map +1 -0
  258. package/lib/test/tmq/tmq.cloud.test.js +82 -0
  259. package/lib/test/tmq/tmq.config.test.d.ts +2 -0
  260. package/lib/test/tmq/tmq.config.test.d.ts.map +1 -0
  261. package/lib/test/tmq/tmq.config.test.js +94 -0
  262. package/lib/test/tmq/tmq.failover.test.d.ts +2 -0
  263. package/lib/test/tmq/tmq.failover.test.d.ts.map +1 -0
  264. package/lib/test/tmq/tmq.failover.test.js +404 -0
  265. package/lib/test/tmq/tmq.test.d.ts +2 -0
  266. package/lib/test/tmq/tmq.test.d.ts.map +1 -0
  267. package/lib/test/tmq/tmq.test.js +513 -0
  268. package/lib/test/unit/connectionManager.test.d.ts +2 -0
  269. package/lib/test/unit/connectionManager.test.d.ts.map +1 -0
  270. package/lib/test/unit/connectionManager.test.js +91 -0
  271. package/lib/test/utils.d.ts +4 -0
  272. package/lib/test/utils.d.ts.map +1 -1
  273. package/lib/test/utils.js +11 -17
  274. package/package.json +1 -1
  275. package/readme.md +2 -2
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLOUD_DEFAULT_PORT = exports.DEFAULT_PORT = exports.Dsn = exports.Address = exports.WS_TMQ_ENDPOINT = exports.WS_SQL_ENDPOINT = void 0;
4
+ exports.parse = parse;
5
+ exports.isCloudServiceHost = isCloudServiceHost;
6
+ exports.getDefaultPortForHost = getDefaultPortForHost;
7
+ const wsError_1 = require("./wsError");
8
+ exports.WS_SQL_ENDPOINT = "sql";
9
+ exports.WS_TMQ_ENDPOINT = "tmq";
10
+ const WS_SQL_PATH = "ws";
11
+ const WS_TMQ_PATH = "rest/tmq";
12
+ class Address {
13
+ constructor(host, port) {
14
+ this.host = host;
15
+ this.port = port;
16
+ }
17
+ }
18
+ exports.Address = Address;
19
+ const REDACTED = "[REDACTED]";
20
+ const SENSITIVE_PARAM_KEYS = new Set([
21
+ "token",
22
+ "bearer_token",
23
+ "td.connect.token",
24
+ ]);
25
+ function shouldMaskParam(key) {
26
+ return SENSITIVE_PARAM_KEYS.has(key.toLowerCase());
27
+ }
28
+ class Dsn {
29
+ constructor(scheme, username, password, addresses, database, params, endpoint = exports.WS_SQL_ENDPOINT) {
30
+ this.scheme = scheme;
31
+ this.username = username;
32
+ this.password = password;
33
+ this.addresses = addresses.map((address) => new Address(address.host, address.port));
34
+ this.database = database;
35
+ this.params = new Map(params);
36
+ this.endpoint = endpoint;
37
+ }
38
+ toString() {
39
+ const params = {};
40
+ for (const [key, value] of this.params.entries()) {
41
+ params[key] = shouldMaskParam(key) ? REDACTED : value;
42
+ }
43
+ return JSON.stringify({
44
+ scheme: this.scheme,
45
+ username: this.username,
46
+ password: this.password.length > 0 ? REDACTED : this.password,
47
+ addresses: this.addresses,
48
+ database: this.database,
49
+ params,
50
+ endpoint: this.endpoint,
51
+ });
52
+ }
53
+ path() {
54
+ return this.endpoint === exports.WS_TMQ_ENDPOINT ? WS_TMQ_PATH : WS_SQL_PATH;
55
+ }
56
+ }
57
+ exports.Dsn = Dsn;
58
+ /**
59
+ * Parse a multi-host TDengine WebSocket URL.
60
+ * Format: ws://username:password@host1:port1,host2:port2,[::1]:port3/db?key=value
61
+ */
62
+ function parse(url) {
63
+ if (!url || url.trim().length === 0) {
64
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, "URL must not be empty");
65
+ }
66
+ // Extract scheme
67
+ const schemeMatch = url.match(/^(wss?):\/\//i);
68
+ if (!schemeMatch) {
69
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, "Invalid URL scheme, expected ws:// or wss://");
70
+ }
71
+ const scheme = schemeMatch[1].toLowerCase();
72
+ let remainder = url.slice(schemeMatch[0].length);
73
+ // Isolate authority from path/query before parsing userinfo.
74
+ const slashIndex = remainder.indexOf("/");
75
+ const queryMarkIndex = remainder.indexOf("?");
76
+ let authorityEndIndex = remainder.length;
77
+ if (slashIndex !== -1) {
78
+ authorityEndIndex = Math.min(authorityEndIndex, slashIndex);
79
+ }
80
+ if (queryMarkIndex !== -1) {
81
+ authorityEndIndex = Math.min(authorityEndIndex, queryMarkIndex);
82
+ }
83
+ const authority = remainder.slice(0, authorityEndIndex);
84
+ const suffix = remainder.slice(authorityEndIndex);
85
+ // Extract username:password@ from authority only.
86
+ let username = "";
87
+ let password = "";
88
+ const atIndex = authority.lastIndexOf("@");
89
+ let hostPort = authority;
90
+ if (atIndex !== -1) {
91
+ const userInfo = authority.slice(0, atIndex);
92
+ hostPort = authority.slice(atIndex + 1);
93
+ const colonIndex = userInfo.indexOf(":");
94
+ if (colonIndex !== -1) {
95
+ username = userInfo.slice(0, colonIndex);
96
+ password = userInfo.slice(colonIndex + 1);
97
+ }
98
+ else {
99
+ username = userInfo;
100
+ }
101
+ }
102
+ remainder = `${hostPort}${suffix}`;
103
+ // Extract query params (after ?)
104
+ let params = new Map();
105
+ const queryIndex = remainder.indexOf("?");
106
+ let queryString = "";
107
+ if (queryIndex !== -1) {
108
+ queryString = remainder.slice(queryIndex + 1);
109
+ remainder = remainder.slice(0, queryIndex);
110
+ const searchParams = new URLSearchParams(queryString);
111
+ searchParams.forEach((value, key) => {
112
+ params.set(key, value);
113
+ });
114
+ }
115
+ // Extract database (after /)
116
+ let database = "";
117
+ const pathIndex = remainder.indexOf("/");
118
+ if (pathIndex !== -1) {
119
+ database = remainder.slice(pathIndex + 1);
120
+ remainder = remainder.slice(0, pathIndex);
121
+ }
122
+ // remainder is now the host list: host1:port1,host2:port2,[::1]:port3
123
+ const hosts = parseHostList(remainder);
124
+ if (hosts.length === 0) {
125
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, "No hosts found in URL");
126
+ }
127
+ // Deduplicate hosts (preserve order, keep first occurrence)
128
+ const seen = new Set();
129
+ const dedupedHosts = [];
130
+ for (const h of hosts) {
131
+ const key = `${h.host}:${h.port}`;
132
+ if (!seen.has(key)) {
133
+ seen.add(key);
134
+ dedupedHosts.push(h);
135
+ }
136
+ }
137
+ return new Dsn(scheme, username, password, dedupedHosts, database, params);
138
+ }
139
+ exports.DEFAULT_PORT = 6041;
140
+ exports.CLOUD_DEFAULT_PORT = 443;
141
+ function isCloudServiceHost(host) {
142
+ const normalizedHost = host.toLowerCase();
143
+ return (normalizedHost.includes("cloud.tdengine.com") ||
144
+ normalizedHost.includes("cloud.taosdata.com"));
145
+ }
146
+ function getDefaultPortForHost(host) {
147
+ return isCloudServiceHost(host) ? exports.CLOUD_DEFAULT_PORT : exports.DEFAULT_PORT;
148
+ }
149
+ /**
150
+ * Parse comma-separated host list. Supports IPv6 in brackets.
151
+ * Examples: "host1:6041,host2:6042", "[::1]:6041,host2:6042"
152
+ */
153
+ function parseHostList(hostStr) {
154
+ if (!hostStr || hostStr.trim().length === 0) {
155
+ return [];
156
+ }
157
+ const hosts = [];
158
+ let i = 0;
159
+ while (i < hostStr.length) {
160
+ // Skip comma separator
161
+ if (hostStr[i] === ",") {
162
+ i++;
163
+ continue;
164
+ }
165
+ if (hostStr[i] === "[") {
166
+ // IPv6 address in brackets
167
+ const closeBracket = hostStr.indexOf("]", i);
168
+ if (closeBracket === -1) {
169
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Unclosed bracket in IPv6 address: ${hostStr.slice(i)}`);
170
+ }
171
+ const ipv6Host = hostStr.slice(i + 1, closeBracket);
172
+ let port = getDefaultPortForHost(ipv6Host);
173
+ let next = closeBracket + 1;
174
+ if (next < hostStr.length && hostStr[next] === ":") {
175
+ const portEnd = hostStr.indexOf(",", next);
176
+ const portStr = portEnd === -1
177
+ ? hostStr.slice(next + 1)
178
+ : hostStr.slice(next + 1, portEnd);
179
+ port = parsePort(portStr, hostStr, ipv6Host);
180
+ i = portEnd === -1 ? hostStr.length : portEnd;
181
+ }
182
+ else {
183
+ i = next;
184
+ }
185
+ hosts.push(new Address(`[${ipv6Host}]`, port));
186
+ }
187
+ else {
188
+ // Regular host or IPv4
189
+ const commaIndex = hostStr.indexOf(",", i);
190
+ const segment = commaIndex === -1
191
+ ? hostStr.slice(i)
192
+ : hostStr.slice(i, commaIndex);
193
+ const lastColon = segment.lastIndexOf(":");
194
+ if (lastColon !== -1) {
195
+ const host = segment.slice(0, lastColon);
196
+ const port = parsePort(segment.slice(lastColon + 1), hostStr, host);
197
+ hosts.push(new Address(host, port));
198
+ }
199
+ else {
200
+ hosts.push(new Address(segment, getDefaultPortForHost(segment)));
201
+ }
202
+ i = commaIndex === -1 ? hostStr.length : commaIndex;
203
+ }
204
+ }
205
+ return hosts;
206
+ }
207
+ function parsePort(portStr, context, host) {
208
+ // If port string is empty, use default port
209
+ if (portStr.length === 0) {
210
+ return getDefaultPortForHost(host);
211
+ }
212
+ // Validate that port string contains only digits
213
+ if (!/^\d+$/.test(portStr)) {
214
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Invalid port "${portStr}" in host string: ${context}`);
215
+ }
216
+ const port = parseInt(portStr, 10);
217
+ if (isNaN(port) || port < 1 || port > 65535) {
218
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Invalid port "${portStr}" in host string: ${context}`);
219
+ }
220
+ return port;
221
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"taosResult.d.ts","sourceRoot":"","sources":["../../../src/common/taosResult.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"taosResult.d.ts","sourceRoot":"","sources":["../../../src/common/taosResult.ts"],"names":[],"mappings":"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"}
@@ -449,7 +449,6 @@ function readSolidData(dataBuffer, colDataHead, meta, fields_scale) {
449
449
  }
450
450
  case constant_1.TDengineTypeCode.TIMESTAMP: {
451
451
  return dataBuffer.getBigInt64(colDataHead, true);
452
- // could change
453
452
  }
454
453
  case constant_1.TDengineTypeCode.DECIMAL: {
455
454
  let decimalHighPart = dataBuffer.getBigInt64(colDataHead + 8, true);
@@ -471,13 +470,11 @@ function readBinary(dataBuffer, colDataHead, length) {
471
470
  return buff;
472
471
  }
473
472
  function readVarchar(dataBuffer, colDataHead, length, textDecoder) {
474
- // let buff = dataBuffer.slice(colDataHead, colDataHead + length)
475
473
  let dataView = new DataView(dataBuffer, colDataHead, length);
476
474
  return textDecoder.decode(dataView);
477
475
  }
478
476
  function readNchar(dataBuffer, colDataHead, length) {
479
477
  let data = [];
480
- // let buff: ArrayBuffer = dataBuffer.slice(colDataHead, colDataHead + length);
481
478
  let dataView = new DataView(dataBuffer, colDataHead, length);
482
479
  for (let i = 0; i < length / 4; i++) {
483
480
  data.push((0, ut8Helper_1.appendRune)(dataView.getUint32(i * 4, true)));
@@ -485,7 +482,6 @@ function readNchar(dataBuffer, colDataHead, length) {
485
482
  return data.join("");
486
483
  }
487
484
  function getString(dataBuffer, colDataHead, length, textDecoder) {
488
- // let buff = dataBuffer.slice(colDataHead, colDataHead + length - 1)
489
485
  let dataView = new Uint8Array(dataBuffer.buffer, dataBuffer.byteOffset + colDataHead, length - 1);
490
486
  return textDecoder.decode(dataView);
491
487
  }
@@ -514,7 +510,6 @@ function bitmapLen(n) {
514
510
  return (n + ((1 << 3) - 1)) >> 3;
515
511
  }
516
512
  function getScaleFromRowBlock(buffer, colIndex, startOffset) {
517
- // for decimal: |___bytes___|__empty__|___prec___|__scale___|
518
513
  let backupPos = buffer.byteOffset + startOffset + 28 + colIndex * 5 + 1;
519
514
  let scaleBuffer = new DataView(buffer.buffer, backupPos);
520
515
  let scale = scaleBuffer.getInt32(0, true);
@@ -0,0 +1,32 @@
1
+ export interface HostInfo {
2
+ host: string;
3
+ port: number;
4
+ }
5
+ export interface ParsedUrl {
6
+ hosts: HostInfo[];
7
+ scheme: string;
8
+ username: string;
9
+ password: string;
10
+ database: string;
11
+ params: Map<string, string>;
12
+ }
13
+ /**
14
+ * Parse a multi-host TDengine WebSocket URL.
15
+ * Format: ws://username:password@host1:port1,host2:port2,[::1]:port3/db?key=value
16
+ */
17
+ export declare function parseMultiHostUrl(url: string): ParsedUrl;
18
+ /**
19
+ * Build a single-host URL from parsed components + a specific host.
20
+ * Used by ConnectionManager to create WebSocketConnector URLs.
21
+ */
22
+ export declare function buildHostUrl(parsed: ParsedUrl, host: HostInfo, extraParams?: Map<string, string>): URL;
23
+ /**
24
+ * Extract retry options from parsed URL params.
25
+ */
26
+ export declare function extractRetryOptions(params: Map<string, string>): {
27
+ retries?: number;
28
+ retryBackoffMs?: number;
29
+ retryBackoffMaxMs?: number;
30
+ resendWrite?: boolean;
31
+ };
32
+ //# sourceMappingURL=urlParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urlParser.d.ts","sourceRoot":"","sources":["../../../src/common/urlParser.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAqFxD;AA0FD;;;GAGG;AACH,wBAAgB,YAAY,CACxB,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,QAAQ,EACd,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,GAAG,CA0BL;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,CAgBA"}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseMultiHostUrl = parseMultiHostUrl;
4
+ exports.buildHostUrl = buildHostUrl;
5
+ exports.extractRetryOptions = extractRetryOptions;
6
+ const wsError_1 = require("./wsError");
7
+ /**
8
+ * Parse a multi-host TDengine WebSocket URL.
9
+ * Format: ws://username:password@host1:port1,host2:port2,[::1]:port3/db?key=value
10
+ */
11
+ function parseMultiHostUrl(url) {
12
+ if (!url || url.trim().length === 0) {
13
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, "URL must not be empty");
14
+ }
15
+ // Extract scheme
16
+ const schemeMatch = url.match(/^(wss?):\/\//i);
17
+ if (!schemeMatch) {
18
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Invalid URL scheme, expected ws:// or wss://, got: ${url}`);
19
+ }
20
+ const scheme = schemeMatch[1].toLowerCase();
21
+ let remainder = url.slice(schemeMatch[0].length);
22
+ // Extract username:password@ if present
23
+ let username = "";
24
+ let password = "";
25
+ const atIndex = remainder.indexOf("@");
26
+ if (atIndex !== -1) {
27
+ const userInfo = remainder.slice(0, atIndex);
28
+ remainder = remainder.slice(atIndex + 1);
29
+ const colonIndex = userInfo.indexOf(":");
30
+ if (colonIndex !== -1) {
31
+ username = userInfo.slice(0, colonIndex);
32
+ password = userInfo.slice(colonIndex + 1);
33
+ }
34
+ else {
35
+ username = userInfo;
36
+ }
37
+ }
38
+ // Extract query params (after ?)
39
+ let params = new Map();
40
+ const queryIndex = remainder.indexOf("?");
41
+ let queryString = "";
42
+ if (queryIndex !== -1) {
43
+ queryString = remainder.slice(queryIndex + 1);
44
+ remainder = remainder.slice(0, queryIndex);
45
+ const searchParams = new URLSearchParams(queryString);
46
+ searchParams.forEach((value, key) => {
47
+ params.set(key, value);
48
+ });
49
+ }
50
+ // Extract database (after /)
51
+ let database = "";
52
+ const pathIndex = remainder.indexOf("/");
53
+ if (pathIndex !== -1) {
54
+ database = remainder.slice(pathIndex + 1);
55
+ remainder = remainder.slice(0, pathIndex);
56
+ }
57
+ // remainder is now the host list: host1:port1,host2:port2,[::1]:port3
58
+ const hosts = parseHostList(remainder);
59
+ if (hosts.length === 0) {
60
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, "No hosts found in URL");
61
+ }
62
+ // Deduplicate hosts (preserve order, keep first occurrence)
63
+ const seen = new Set();
64
+ const dedupedHosts = [];
65
+ for (const h of hosts) {
66
+ const key = `${h.host}:${h.port}`;
67
+ if (!seen.has(key)) {
68
+ seen.add(key);
69
+ dedupedHosts.push(h);
70
+ }
71
+ }
72
+ return {
73
+ hosts: dedupedHosts,
74
+ scheme,
75
+ username,
76
+ password,
77
+ database,
78
+ params,
79
+ };
80
+ }
81
+ const DEFAULT_PORT = 6041;
82
+ /**
83
+ * Parse comma-separated host list. Supports IPv6 in brackets.
84
+ * Examples: "host1:6041,host2:6042", "[::1]:6041,host2:6042"
85
+ */
86
+ function parseHostList(hostStr) {
87
+ if (!hostStr || hostStr.trim().length === 0) {
88
+ return [];
89
+ }
90
+ const hosts = [];
91
+ let i = 0;
92
+ while (i < hostStr.length) {
93
+ // Skip comma separator
94
+ if (hostStr[i] === ",") {
95
+ i++;
96
+ continue;
97
+ }
98
+ if (hostStr[i] === "[") {
99
+ // IPv6 address in brackets
100
+ const closeBracket = hostStr.indexOf("]", i);
101
+ if (closeBracket === -1) {
102
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Unclosed bracket in IPv6 address: ${hostStr.slice(i)}`);
103
+ }
104
+ const ipv6Host = hostStr.slice(i + 1, closeBracket);
105
+ let port = DEFAULT_PORT;
106
+ let next = closeBracket + 1;
107
+ if (next < hostStr.length && hostStr[next] === ":") {
108
+ const portEnd = hostStr.indexOf(",", next);
109
+ const portStr = portEnd === -1
110
+ ? hostStr.slice(next + 1)
111
+ : hostStr.slice(next + 1, portEnd);
112
+ port = parsePort(portStr, hostStr);
113
+ i = portEnd === -1 ? hostStr.length : portEnd;
114
+ }
115
+ else {
116
+ i = next;
117
+ }
118
+ hosts.push({ host: `[${ipv6Host}]`, port });
119
+ }
120
+ else {
121
+ // Regular host or IPv4
122
+ const commaIndex = hostStr.indexOf(",", i);
123
+ const segment = commaIndex === -1
124
+ ? hostStr.slice(i)
125
+ : hostStr.slice(i, commaIndex);
126
+ const lastColon = segment.lastIndexOf(":");
127
+ if (lastColon !== -1) {
128
+ const host = segment.slice(0, lastColon);
129
+ const port = parsePort(segment.slice(lastColon + 1), hostStr);
130
+ hosts.push({ host, port });
131
+ }
132
+ else {
133
+ hosts.push({ host: segment, port: DEFAULT_PORT });
134
+ }
135
+ i = commaIndex === -1 ? hostStr.length : commaIndex;
136
+ }
137
+ }
138
+ return hosts;
139
+ }
140
+ function parsePort(portStr, context) {
141
+ // If port string is empty, use default port
142
+ if (portStr.length === 0) {
143
+ return DEFAULT_PORT;
144
+ }
145
+ // Validate that port string contains only digits
146
+ if (!/^\d+$/.test(portStr)) {
147
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Invalid port "${portStr}" in host string: ${context}`);
148
+ }
149
+ const port = parseInt(portStr, 10);
150
+ if (isNaN(port) || port < 1 || port > 65535) {
151
+ throw new wsError_1.TDWebSocketClientError(wsError_1.ErrorCode.ERR_INVALID_URL, `Invalid port "${portStr}" in host string: ${context}`);
152
+ }
153
+ return port;
154
+ }
155
+ /**
156
+ * Build a single-host URL from parsed components + a specific host.
157
+ * Used by ConnectionManager to create WebSocketConnector URLs.
158
+ */
159
+ function buildHostUrl(parsed, host, extraParams) {
160
+ const origin = `${parsed.scheme}://${host.host}:${host.port}`;
161
+ const url = new URL(origin + "/ws");
162
+ if (parsed.username) {
163
+ url.username = parsed.username;
164
+ }
165
+ if (parsed.password) {
166
+ url.password = parsed.password;
167
+ }
168
+ // Copy non-retry params
169
+ const retryParams = new Set(["retries", "retry_backoff_ms", "retry_backoff_max_ms", "resend_write"]);
170
+ parsed.params.forEach((value, key) => {
171
+ if (!retryParams.has(key)) {
172
+ url.searchParams.set(key, value);
173
+ }
174
+ });
175
+ if (extraParams) {
176
+ extraParams.forEach((value, key) => {
177
+ url.searchParams.set(key, value);
178
+ });
179
+ }
180
+ return url;
181
+ }
182
+ /**
183
+ * Extract retry options from parsed URL params.
184
+ */
185
+ function extractRetryOptions(params) {
186
+ const result = {};
187
+ if (params.has("retries")) {
188
+ result.retries = parseInt(params.get("retries"), 10);
189
+ }
190
+ if (params.has("retry_backoff_ms")) {
191
+ result.retryBackoffMs = parseInt(params.get("retry_backoff_ms"), 10);
192
+ }
193
+ if (params.has("retry_backoff_max_ms")) {
194
+ result.retryBackoffMaxMs = parseInt(params.get("retry_backoff_max_ms"), 10);
195
+ }
196
+ if (params.has("resend_write")) {
197
+ const val = params.get("resend_write").toLowerCase();
198
+ result.resendWrite = val === "true" || val === "1";
199
+ }
200
+ return result;
201
+ }
@@ -1,5 +1,7 @@
1
+ import { TmqConfig } from "../tmq/config";
1
2
  import { WSConfig } from "./config";
2
- export declare function getUrl(wsConfig: WSConfig): URL;
3
+ import { Dsn } from "./dsn";
4
+ export declare function getDsn(wsConfig: WSConfig): Dsn;
3
5
  export declare function isEmpty(value: any): boolean;
4
6
  export declare function getBinarySql(action: bigint, reqId: bigint, resultId: bigint, sql?: string): ArrayBuffer;
5
7
  export declare function zigzagDecode(n: number): number;
@@ -15,4 +17,7 @@ export declare function safeDecodeURIComponent(str: string): string;
15
17
  */
16
18
  export declare function compareVersions(v1: string, v2: string): number;
17
19
  export declare function decimalToString(valueStr: string, fields_scale: bigint | null): string;
20
+ export declare function maskSensitiveForLog(message: string): string;
21
+ export declare function maskUrlForLog(url: URL | null): string;
22
+ export declare function maskTmqConfigForLog(config: TmqConfig): string;
18
23
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,GAAG,CA6B9C;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAM3C;AAED,wBAAgB,YAAY,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACb,WAAW,CA6Bb;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,UAWjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAW9D;AAkDD,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,CAoBR"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/common/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,GAAG,EAAS,MAAM,OAAO,CAAC;AAGnC,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,GAAG,CA0C9C;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAI3C;AAED,wBAAgB,YAAY,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACb,WAAW,CA2Bb;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,UAWjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAW9D;AAkDD,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,CAkBR;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,MAAM,CAcrD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAmB7D"}
@@ -1,49 +1,65 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUrl = getUrl;
3
+ exports.getDsn = getDsn;
4
4
  exports.isEmpty = isEmpty;
5
5
  exports.getBinarySql = getBinarySql;
6
6
  exports.zigzagDecode = zigzagDecode;
7
7
  exports.safeDecodeURIComponent = safeDecodeURIComponent;
8
8
  exports.compareVersions = compareVersions;
9
9
  exports.decimalToString = decimalToString;
10
+ exports.maskSensitiveForLog = maskSensitiveForLog;
11
+ exports.maskUrlForLog = maskUrlForLog;
12
+ exports.maskTmqConfigForLog = maskTmqConfigForLog;
13
+ const dsn_1 = require("./dsn");
10
14
  const wsError_1 = require("./wsError");
11
- function getUrl(wsConfig) {
12
- let url = new URL(wsConfig.getUrl());
13
- if (wsConfig.getUser()) {
14
- url.username = wsConfig.getUser() || "";
15
+ function getDsn(wsConfig) {
16
+ const dsn = (0, dsn_1.parse)(wsConfig.getUrl());
17
+ const user = wsConfig.getUser();
18
+ if (user) {
19
+ dsn.username = user;
15
20
  }
16
- if (wsConfig.getPwd()) {
17
- url.password = wsConfig.getPwd() || "";
21
+ const password = wsConfig.getPwd();
22
+ if (password) {
23
+ dsn.password = password;
18
24
  }
19
- let token = wsConfig.getToken();
25
+ const token = wsConfig.getToken();
20
26
  if (token) {
21
- url.searchParams.set("token", token);
27
+ dsn.params.set("token", token);
22
28
  }
23
- let timezone = wsConfig.getTimezone();
29
+ else if (dsn.params.has("token")) {
30
+ wsConfig.setToken(dsn.params.get("token") || "");
31
+ }
32
+ const bearerToken = wsConfig.getBearerToken();
33
+ if (bearerToken) {
34
+ dsn.params.set("bearer_token", bearerToken);
35
+ }
36
+ else if (dsn.params.has("bearer_token")) {
37
+ wsConfig.setBearerToken(dsn.params.get("bearer_token") || "");
38
+ }
39
+ const timezone = wsConfig.getTimezone();
24
40
  if (timezone) {
25
- url.searchParams.set("timezone", timezone);
41
+ dsn.params.set("timezone", timezone);
26
42
  }
27
- if (url.pathname && url.pathname !== "/") {
28
- wsConfig.setDb(url.pathname.slice(1));
43
+ else if (dsn.params.has("timezone")) {
44
+ wsConfig.setTimezone(dsn.params.get("timezone") || "");
29
45
  }
30
- if (url.searchParams.has("timezone")) {
31
- wsConfig.setTimezone(url.searchParams.get("timezone") || "");
46
+ const db = wsConfig.getDb();
47
+ if (db && db.length > 0) {
48
+ dsn.database = db;
32
49
  }
33
- url.pathname = "/ws";
34
- return url;
50
+ else if (dsn.database.length > 0) {
51
+ wsConfig.setDb(dsn.database);
52
+ }
53
+ return dsn;
35
54
  }
36
55
  function isEmpty(value) {
37
56
  if (value === null || value === undefined)
38
57
  return true;
39
- // if (typeof value === 'string' && value.trim() === '') return true;
40
58
  if (Array.isArray(value) && value.length === 0)
41
59
  return true;
42
- // if (typeof value === 'object' && Object.keys(value).length === 0) return true;
43
60
  return false;
44
61
  }
45
62
  function getBinarySql(action, reqId, resultId, sql) {
46
- // construct msg
47
63
  if (sql) {
48
64
  const encoder = new TextEncoder();
49
65
  const buffer = encoder.encode(sql);
@@ -153,12 +169,10 @@ function decimalToString(valueStr, fields_scale) {
153
169
  const isNegative = decimalStr.startsWith("-");
154
170
  const absStr = isNegative ? decimalStr.slice(1) : decimalStr;
155
171
  if (absStr.length <= scale) {
156
- // If the length of the number is less than or equal to the precision, add 0 before it.
157
172
  const paddedStr = absStr.padStart(scale + 1, "0");
158
173
  decimalStr = (isNegative ? "-" : "") + "0." + paddedStr.slice(1);
159
174
  }
160
175
  else {
161
- // 在指定位置插入小数点
162
176
  const integerPart = absStr.slice(0, absStr.length - scale);
163
177
  const decimalPart = absStr.slice(absStr.length - scale);
164
178
  decimalStr =
@@ -167,3 +181,41 @@ function decimalToString(valueStr, fields_scale) {
167
181
  }
168
182
  return decimalStr;
169
183
  }
184
+ const SENSITIVE_FIELD_REGEX = /("(?:password|token|bearer_token|td\.connect\.token)"\s*:\s*)"([^"\\]*(?:\\.[^"\\]*)*)"/g;
185
+ function maskSensitiveForLog(message) {
186
+ return message.replace(SENSITIVE_FIELD_REGEX, '$1"[REDACTED]"');
187
+ }
188
+ function maskUrlForLog(url) {
189
+ if (!url) {
190
+ return "";
191
+ }
192
+ const masked = new URL(url.toString());
193
+ masked.password = "[REDACTED]";
194
+ if (masked.searchParams.has("token")) {
195
+ masked.searchParams.set("token", "[REDACTED]");
196
+ }
197
+ if (masked.searchParams.has("bearer_token")) {
198
+ masked.searchParams.set("bearer_token", "[REDACTED]");
199
+ }
200
+ return masked.toString().replace(/%5BREDACTED%5D/g, "[REDACTED]");
201
+ }
202
+ function maskTmqConfigForLog(config) {
203
+ const masked = {
204
+ ...config,
205
+ otherConfigs: Object.fromEntries(config.otherConfigs)
206
+ };
207
+ return JSON.stringify(masked, (key, value) => {
208
+ switch (key) {
209
+ case 'dsn':
210
+ case 'sqlDsn':
211
+ return value ? value.toString() : value;
212
+ case 'token':
213
+ case 'password':
214
+ case 'bearer_token':
215
+ case 'td.connect.token':
216
+ return value ? '[REDACTED]' : value;
217
+ default:
218
+ return value;
219
+ }
220
+ });
221
+ }