nlcurl 0.7.0 → 0.9.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 (354) hide show
  1. package/README.md +149 -140
  2. package/dist/cache/groups.d.ts +75 -0
  3. package/dist/cache/groups.d.ts.map +1 -0
  4. package/dist/cache/groups.js +118 -0
  5. package/dist/cache/groups.js.map +1 -0
  6. package/dist/cache/no-vary-search.d.ts +33 -0
  7. package/dist/cache/no-vary-search.d.ts.map +1 -0
  8. package/dist/cache/no-vary-search.js +148 -0
  9. package/dist/cache/no-vary-search.js.map +1 -0
  10. package/dist/cache/range.d.ts +120 -0
  11. package/dist/cache/range.d.ts.map +1 -0
  12. package/dist/cache/range.js +193 -0
  13. package/dist/cache/range.js.map +1 -0
  14. package/dist/cache/store.d.ts +75 -37
  15. package/dist/cache/store.d.ts.map +1 -1
  16. package/dist/cache/store.js +217 -85
  17. package/dist/cache/store.js.map +1 -1
  18. package/dist/cache/types.d.ts +10 -39
  19. package/dist/cache/types.d.ts.map +1 -1
  20. package/dist/cli/args.d.ts +4 -37
  21. package/dist/cli/args.d.ts.map +1 -1
  22. package/dist/cli/args.js +3 -4
  23. package/dist/cli/args.js.map +1 -1
  24. package/dist/cli/index.d.ts +0 -5
  25. package/dist/cli/index.d.ts.map +1 -1
  26. package/dist/cli/index.js +1 -6
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/cli/output.d.ts +14 -20
  29. package/dist/cli/output.d.ts.map +1 -1
  30. package/dist/cli/output.js +14 -20
  31. package/dist/cli/output.js.map +1 -1
  32. package/dist/cookies/jar.d.ts +41 -40
  33. package/dist/cookies/jar.d.ts.map +1 -1
  34. package/dist/cookies/jar.js +65 -42
  35. package/dist/cookies/jar.js.map +1 -1
  36. package/dist/cookies/parser.d.ts +13 -17
  37. package/dist/cookies/parser.d.ts.map +1 -1
  38. package/dist/cookies/parser.js +23 -15
  39. package/dist/cookies/parser.js.map +1 -1
  40. package/dist/cookies/psl-data.d.ts +1 -1
  41. package/dist/cookies/psl-data.js +1 -1
  42. package/dist/cookies/public-suffix.d.ts +5 -27
  43. package/dist/cookies/public-suffix.d.ts.map +1 -1
  44. package/dist/cookies/public-suffix.js +5 -37
  45. package/dist/cookies/public-suffix.js.map +1 -1
  46. package/dist/core/auth.d.ts +61 -0
  47. package/dist/core/auth.d.ts.map +1 -0
  48. package/dist/core/auth.js +159 -0
  49. package/dist/core/auth.js.map +1 -0
  50. package/dist/core/client.d.ts +28 -40
  51. package/dist/core/client.d.ts.map +1 -1
  52. package/dist/core/client.js +31 -41
  53. package/dist/core/client.js.map +1 -1
  54. package/dist/core/errors.d.ts +64 -88
  55. package/dist/core/errors.d.ts.map +1 -1
  56. package/dist/core/errors.js +64 -88
  57. package/dist/core/errors.js.map +1 -1
  58. package/dist/core/request.d.ts +33 -113
  59. package/dist/core/request.d.ts.map +1 -1
  60. package/dist/core/response.d.ts +49 -66
  61. package/dist/core/response.d.ts.map +1 -1
  62. package/dist/core/response.js +45 -59
  63. package/dist/core/response.js.map +1 -1
  64. package/dist/core/session.d.ts +66 -78
  65. package/dist/core/session.d.ts.map +1 -1
  66. package/dist/core/session.js +136 -77
  67. package/dist/core/session.js.map +1 -1
  68. package/dist/core/validation.d.ts +58 -43
  69. package/dist/core/validation.d.ts.map +1 -1
  70. package/dist/core/validation.js +141 -56
  71. package/dist/core/validation.js.map +1 -1
  72. package/dist/dns/cache.d.ts +65 -0
  73. package/dist/dns/cache.d.ts.map +1 -0
  74. package/dist/dns/cache.js +119 -0
  75. package/dist/dns/cache.js.map +1 -0
  76. package/dist/dns/codec.d.ts +29 -19
  77. package/dist/dns/codec.d.ts.map +1 -1
  78. package/dist/dns/codec.js +73 -39
  79. package/dist/dns/codec.js.map +1 -1
  80. package/dist/dns/doh-resolver.d.ts +17 -31
  81. package/dist/dns/doh-resolver.d.ts.map +1 -1
  82. package/dist/dns/doh-resolver.js +47 -48
  83. package/dist/dns/doh-resolver.js.map +1 -1
  84. package/dist/dns/dot-resolver.d.ts +89 -0
  85. package/dist/dns/dot-resolver.d.ts.map +1 -0
  86. package/dist/dns/dot-resolver.js +166 -0
  87. package/dist/dns/dot-resolver.js.map +1 -0
  88. package/dist/dns/https-rr.d.ts +19 -30
  89. package/dist/dns/https-rr.d.ts.map +1 -1
  90. package/dist/dns/https-rr.js +22 -40
  91. package/dist/dns/https-rr.js.map +1 -1
  92. package/dist/dns/types.d.ts +31 -59
  93. package/dist/dns/types.d.ts.map +1 -1
  94. package/dist/dns/types.js +3 -14
  95. package/dist/dns/types.js.map +1 -1
  96. package/dist/fingerprints/akamai.d.ts +3 -11
  97. package/dist/fingerprints/akamai.d.ts.map +1 -1
  98. package/dist/fingerprints/akamai.js +3 -11
  99. package/dist/fingerprints/akamai.js.map +1 -1
  100. package/dist/fingerprints/database.d.ts +6 -14
  101. package/dist/fingerprints/database.d.ts.map +1 -1
  102. package/dist/fingerprints/database.js +6 -14
  103. package/dist/fingerprints/database.js.map +1 -1
  104. package/dist/fingerprints/extensions.d.ts +56 -71
  105. package/dist/fingerprints/extensions.d.ts.map +1 -1
  106. package/dist/fingerprints/extensions.js +58 -71
  107. package/dist/fingerprints/extensions.js.map +1 -1
  108. package/dist/fingerprints/ja3.d.ts +12 -30
  109. package/dist/fingerprints/ja3.d.ts.map +1 -1
  110. package/dist/fingerprints/ja3.js +12 -30
  111. package/dist/fingerprints/ja3.js.map +1 -1
  112. package/dist/fingerprints/ja4.d.ts +18 -0
  113. package/dist/fingerprints/ja4.d.ts.map +1 -0
  114. package/dist/fingerprints/ja4.js +81 -0
  115. package/dist/fingerprints/ja4.js.map +1 -0
  116. package/dist/fingerprints/profiles/chrome.d.ts +18 -21
  117. package/dist/fingerprints/profiles/chrome.d.ts.map +1 -1
  118. package/dist/fingerprints/profiles/chrome.js +35 -31
  119. package/dist/fingerprints/profiles/chrome.js.map +1 -1
  120. package/dist/fingerprints/profiles/edge.d.ts +7 -10
  121. package/dist/fingerprints/profiles/edge.d.ts.map +1 -1
  122. package/dist/fingerprints/profiles/edge.js +7 -10
  123. package/dist/fingerprints/profiles/edge.js.map +1 -1
  124. package/dist/fingerprints/profiles/firefox.d.ts +8 -11
  125. package/dist/fingerprints/profiles/firefox.d.ts.map +1 -1
  126. package/dist/fingerprints/profiles/firefox.js +8 -11
  127. package/dist/fingerprints/profiles/firefox.js.map +1 -1
  128. package/dist/fingerprints/profiles/safari.d.ts +11 -14
  129. package/dist/fingerprints/profiles/safari.d.ts.map +1 -1
  130. package/dist/fingerprints/profiles/safari.js +11 -14
  131. package/dist/fingerprints/profiles/safari.js.map +1 -1
  132. package/dist/fingerprints/profiles/tor.d.ts +5 -8
  133. package/dist/fingerprints/profiles/tor.d.ts.map +1 -1
  134. package/dist/fingerprints/profiles/tor.js +5 -8
  135. package/dist/fingerprints/profiles/tor.js.map +1 -1
  136. package/dist/fingerprints/types.d.ts +42 -73
  137. package/dist/fingerprints/types.d.ts.map +1 -1
  138. package/dist/hsts/store.d.ts +19 -21
  139. package/dist/hsts/store.d.ts.map +1 -1
  140. package/dist/hsts/store.js +20 -28
  141. package/dist/hsts/store.js.map +1 -1
  142. package/dist/hsts/types.d.ts +10 -14
  143. package/dist/hsts/types.d.ts.map +1 -1
  144. package/dist/http/alt-svc.d.ts +27 -52
  145. package/dist/http/alt-svc.d.ts.map +1 -1
  146. package/dist/http/alt-svc.js +17 -67
  147. package/dist/http/alt-svc.js.map +1 -1
  148. package/dist/http/early-hints.d.ts +23 -0
  149. package/dist/http/early-hints.d.ts.map +1 -0
  150. package/dist/http/early-hints.js +33 -0
  151. package/dist/http/early-hints.js.map +1 -0
  152. package/dist/http/form-data.d.ts +17 -35
  153. package/dist/http/form-data.d.ts.map +1 -1
  154. package/dist/http/form-data.js +12 -34
  155. package/dist/http/form-data.js.map +1 -1
  156. package/dist/http/h1/client.d.ts +14 -26
  157. package/dist/http/h1/client.d.ts.map +1 -1
  158. package/dist/http/h1/client.js +14 -23
  159. package/dist/http/h1/client.js.map +1 -1
  160. package/dist/http/h1/encoder.d.ts +21 -17
  161. package/dist/http/h1/encoder.d.ts.map +1 -1
  162. package/dist/http/h1/encoder.js +56 -20
  163. package/dist/http/h1/encoder.js.map +1 -1
  164. package/dist/http/h1/parser.d.ts +23 -59
  165. package/dist/http/h1/parser.d.ts.map +1 -1
  166. package/dist/http/h1/parser.js +61 -55
  167. package/dist/http/h1/parser.js.map +1 -1
  168. package/dist/http/h2/client.d.ts +23 -59
  169. package/dist/http/h2/client.d.ts.map +1 -1
  170. package/dist/http/h2/client.js +107 -64
  171. package/dist/http/h2/client.js.map +1 -1
  172. package/dist/http/h2/frames.d.ts +53 -84
  173. package/dist/http/h2/frames.d.ts.map +1 -1
  174. package/dist/http/h2/frames.js +48 -76
  175. package/dist/http/h2/frames.js.map +1 -1
  176. package/dist/http/h2/hpack.d.ts +20 -36
  177. package/dist/http/h2/hpack.d.ts.map +1 -1
  178. package/dist/http/h2/hpack.js +41 -36
  179. package/dist/http/h2/hpack.js.map +1 -1
  180. package/dist/http/negotiator.d.ts +25 -38
  181. package/dist/http/negotiator.d.ts.map +1 -1
  182. package/dist/http/negotiator.js +17 -38
  183. package/dist/http/negotiator.js.map +1 -1
  184. package/dist/http/pool.d.ts +34 -64
  185. package/dist/http/pool.d.ts.map +1 -1
  186. package/dist/http/pool.js +22 -41
  187. package/dist/http/pool.js.map +1 -1
  188. package/dist/http/resumable-upload.d.ts +76 -0
  189. package/dist/http/resumable-upload.d.ts.map +1 -0
  190. package/dist/http/resumable-upload.js +104 -0
  191. package/dist/http/resumable-upload.js.map +1 -0
  192. package/dist/http/trailers.d.ts +29 -0
  193. package/dist/http/trailers.d.ts.map +1 -0
  194. package/dist/http/trailers.js +57 -0
  195. package/dist/http/trailers.js.map +1 -0
  196. package/dist/index.d.ts +24 -9
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js +24 -3
  199. package/dist/index.js.map +1 -1
  200. package/dist/middleware/circuit-breaker.d.ts +44 -0
  201. package/dist/middleware/circuit-breaker.d.ts.map +1 -0
  202. package/dist/middleware/circuit-breaker.js +96 -0
  203. package/dist/middleware/circuit-breaker.js.map +1 -0
  204. package/dist/middleware/interceptor.d.ts +13 -32
  205. package/dist/middleware/interceptor.d.ts.map +1 -1
  206. package/dist/middleware/interceptor.js +11 -16
  207. package/dist/middleware/interceptor.js.map +1 -1
  208. package/dist/middleware/rate-limiter.d.ts +8 -17
  209. package/dist/middleware/rate-limiter.d.ts.map +1 -1
  210. package/dist/middleware/rate-limiter.js +11 -12
  211. package/dist/middleware/rate-limiter.js.map +1 -1
  212. package/dist/middleware/retry-after.d.ts +15 -0
  213. package/dist/middleware/retry-after.d.ts.map +1 -0
  214. package/dist/middleware/retry-after.js +36 -0
  215. package/dist/middleware/retry-after.js.map +1 -0
  216. package/dist/middleware/retry.d.ts +9 -18
  217. package/dist/middleware/retry.d.ts.map +1 -1
  218. package/dist/middleware/retry.js +12 -9
  219. package/dist/middleware/retry.js.map +1 -1
  220. package/dist/proxy/auth.d.ts +73 -0
  221. package/dist/proxy/auth.d.ts.map +1 -0
  222. package/dist/proxy/auth.js +129 -0
  223. package/dist/proxy/auth.js.map +1 -0
  224. package/dist/proxy/env-proxy.d.ts +5 -15
  225. package/dist/proxy/env-proxy.d.ts.map +1 -1
  226. package/dist/proxy/env-proxy.js +5 -23
  227. package/dist/proxy/env-proxy.js.map +1 -1
  228. package/dist/proxy/http-proxy.d.ts +12 -19
  229. package/dist/proxy/http-proxy.d.ts.map +1 -1
  230. package/dist/proxy/http-proxy.js +5 -8
  231. package/dist/proxy/http-proxy.js.map +1 -1
  232. package/dist/proxy/socks.d.ts +13 -20
  233. package/dist/proxy/socks.d.ts.map +1 -1
  234. package/dist/proxy/socks.js +8 -10
  235. package/dist/proxy/socks.js.map +1 -1
  236. package/dist/sse/parser.d.ts +16 -37
  237. package/dist/sse/parser.d.ts.map +1 -1
  238. package/dist/sse/parser.js +31 -28
  239. package/dist/sse/parser.js.map +1 -1
  240. package/dist/tls/constants.d.ts +21 -72
  241. package/dist/tls/constants.d.ts.map +1 -1
  242. package/dist/tls/constants.js +21 -72
  243. package/dist/tls/constants.js.map +1 -1
  244. package/dist/tls/ct.d.ts +78 -0
  245. package/dist/tls/ct.d.ts.map +1 -0
  246. package/dist/tls/ct.js +175 -0
  247. package/dist/tls/ct.js.map +1 -0
  248. package/dist/tls/early-data.d.ts +45 -0
  249. package/dist/tls/early-data.d.ts.map +1 -0
  250. package/dist/tls/early-data.js +46 -0
  251. package/dist/tls/early-data.js.map +1 -0
  252. package/dist/tls/ech.d.ts +68 -85
  253. package/dist/tls/ech.d.ts.map +1 -1
  254. package/dist/tls/ech.js +54 -102
  255. package/dist/tls/ech.js.map +1 -1
  256. package/dist/tls/keylog.d.ts +34 -0
  257. package/dist/tls/keylog.d.ts.map +1 -0
  258. package/dist/tls/keylog.js +64 -0
  259. package/dist/tls/keylog.js.map +1 -0
  260. package/dist/tls/node-engine.d.ts +10 -17
  261. package/dist/tls/node-engine.d.ts.map +1 -1
  262. package/dist/tls/node-engine.js +41 -18
  263. package/dist/tls/node-engine.js.map +1 -1
  264. package/dist/tls/ocsp.d.ts +55 -0
  265. package/dist/tls/ocsp.d.ts.map +1 -0
  266. package/dist/tls/ocsp.js +131 -0
  267. package/dist/tls/ocsp.js.map +1 -0
  268. package/dist/tls/pin-verification.d.ts +5 -4
  269. package/dist/tls/pin-verification.d.ts.map +1 -1
  270. package/dist/tls/pin-verification.js +5 -11
  271. package/dist/tls/pin-verification.js.map +1 -1
  272. package/dist/tls/session-cache.d.ts +27 -39
  273. package/dist/tls/session-cache.d.ts.map +1 -1
  274. package/dist/tls/session-cache.js +20 -24
  275. package/dist/tls/session-cache.js.map +1 -1
  276. package/dist/tls/stealth/client-hello.d.ts +26 -45
  277. package/dist/tls/stealth/client-hello.d.ts.map +1 -1
  278. package/dist/tls/stealth/client-hello.js +15 -31
  279. package/dist/tls/stealth/client-hello.js.map +1 -1
  280. package/dist/tls/stealth/engine.d.ts +10 -15
  281. package/dist/tls/stealth/engine.d.ts.map +1 -1
  282. package/dist/tls/stealth/engine.js +98 -18
  283. package/dist/tls/stealth/engine.js.map +1 -1
  284. package/dist/tls/stealth/handshake.d.ts +32 -31
  285. package/dist/tls/stealth/handshake.d.ts.map +1 -1
  286. package/dist/tls/stealth/handshake.js +74 -47
  287. package/dist/tls/stealth/handshake.js.map +1 -1
  288. package/dist/tls/stealth/key-schedule.d.ts +81 -86
  289. package/dist/tls/stealth/key-schedule.d.ts.map +1 -1
  290. package/dist/tls/stealth/key-schedule.js +70 -58
  291. package/dist/tls/stealth/key-schedule.js.map +1 -1
  292. package/dist/tls/stealth/record-layer.d.ts +52 -75
  293. package/dist/tls/stealth/record-layer.d.ts.map +1 -1
  294. package/dist/tls/stealth/record-layer.js +47 -63
  295. package/dist/tls/stealth/record-layer.js.map +1 -1
  296. package/dist/tls/stealth/tls12-handshake.d.ts +16 -0
  297. package/dist/tls/stealth/tls12-handshake.d.ts.map +1 -1
  298. package/dist/tls/stealth/tls12-handshake.js +10 -2
  299. package/dist/tls/stealth/tls12-handshake.js.map +1 -1
  300. package/dist/tls/types.d.ts +46 -60
  301. package/dist/tls/types.d.ts.map +1 -1
  302. package/dist/utils/buffer-reader.d.ts +26 -81
  303. package/dist/utils/buffer-reader.d.ts.map +1 -1
  304. package/dist/utils/buffer-reader.js +26 -81
  305. package/dist/utils/buffer-reader.js.map +1 -1
  306. package/dist/utils/buffer-writer.d.ts +30 -66
  307. package/dist/utils/buffer-writer.d.ts.map +1 -1
  308. package/dist/utils/buffer-writer.js +30 -66
  309. package/dist/utils/buffer-writer.js.map +1 -1
  310. package/dist/utils/compression.d.ts +18 -0
  311. package/dist/utils/compression.d.ts.map +1 -0
  312. package/dist/utils/compression.js +34 -0
  313. package/dist/utils/compression.js.map +1 -0
  314. package/dist/utils/dictionary-transport.d.ts +97 -0
  315. package/dist/utils/dictionary-transport.d.ts.map +1 -0
  316. package/dist/utils/dictionary-transport.js +171 -0
  317. package/dist/utils/dictionary-transport.js.map +1 -0
  318. package/dist/utils/encoding.d.ts +12 -30
  319. package/dist/utils/encoding.d.ts.map +1 -1
  320. package/dist/utils/encoding.js +15 -46
  321. package/dist/utils/encoding.js.map +1 -1
  322. package/dist/utils/happy-eyeballs.d.ts +18 -8
  323. package/dist/utils/happy-eyeballs.d.ts.map +1 -1
  324. package/dist/utils/happy-eyeballs.js +19 -27
  325. package/dist/utils/happy-eyeballs.js.map +1 -1
  326. package/dist/utils/logger.d.ts +54 -81
  327. package/dist/utils/logger.d.ts.map +1 -1
  328. package/dist/utils/logger.js +92 -64
  329. package/dist/utils/logger.js.map +1 -1
  330. package/dist/utils/tcp-fast-open.d.ts +30 -0
  331. package/dist/utils/tcp-fast-open.d.ts.map +1 -0
  332. package/dist/utils/tcp-fast-open.js +36 -0
  333. package/dist/utils/tcp-fast-open.js.map +1 -0
  334. package/dist/utils/url.d.ts +18 -25
  335. package/dist/utils/url.d.ts.map +1 -1
  336. package/dist/utils/url.js +18 -25
  337. package/dist/utils/url.js.map +1 -1
  338. package/dist/ws/client.d.ts +35 -53
  339. package/dist/ws/client.d.ts.map +1 -1
  340. package/dist/ws/client.js +96 -38
  341. package/dist/ws/client.js.map +1 -1
  342. package/dist/ws/frame.d.ts +24 -41
  343. package/dist/ws/frame.d.ts.map +1 -1
  344. package/dist/ws/frame.js +26 -33
  345. package/dist/ws/frame.js.map +1 -1
  346. package/dist/ws/permessage-deflate.d.ts +23 -28
  347. package/dist/ws/permessage-deflate.d.ts.map +1 -1
  348. package/dist/ws/permessage-deflate.js +18 -26
  349. package/dist/ws/permessage-deflate.js.map +1 -1
  350. package/package.json +2 -2
  351. package/dist/http/h3/detection.d.ts +0 -17
  352. package/dist/http/h3/detection.d.ts.map +0 -1
  353. package/dist/http/h3/detection.js +0 -59
  354. package/dist/http/h3/detection.js.map +0 -1
@@ -1,62 +1,55 @@
1
1
  /**
2
- * Resolves `relative` against `base`. When `base` is `undefined` or the
3
- * resolution fails, `relative` is returned as-is.
2
+ * Resolve a relative URL against an optional base.
4
3
  *
5
- * @param {string | undefined} base - Base URL string.
6
- * @param {string} relative - Relative or absolute URL to resolve.
7
- * @returns {string} The resolved absolute URL, or `relative` if resolution fails.
4
+ * @param {string | undefined} base - Base URL string.
5
+ * @param {string} relative - Relative or absolute URL string.
6
+ * @returns {string} Resolved absolute URL string.
8
7
  */
9
8
  export declare function resolveURL(base: string | undefined, relative: string): string;
10
9
  /**
11
- * Appends `params` as query-string parameters to `url`. Existing parameters in
12
- * the URL are preserved. `undefined` and `null` values are omitted.
10
+ * Append query parameters to a URL string.
13
11
  *
14
- * @param {string} url - Base URL.
15
- * @param {Record<string, string | number | boolean>} [params] - Key-value pairs to append.
16
- * @returns {string} URL with appended query parameters.
12
+ * @param {string} url - Base URL string.
13
+ * @param {Record<string, string | number | boolean>} [params] - Key-value pairs to append.
14
+ * @returns {string} URL string with appended query parameters.
17
15
  */
18
16
  export declare function appendParams(url: string, params?: Record<string, string | number | boolean>): string;
19
17
  /**
20
- * Parses `raw` into a `URL` object.
18
+ * Parse a URL string into a `URL` object.
21
19
  *
22
- * @param {string} raw - Absolute URL string to parse.
23
- * @returns {URL} Parsed URL.
24
- * @throws {TypeError} If `raw` is not a valid absolute URL.
20
+ * @param {string} raw - Raw URL string.
21
+ * @returns {URL} Parsed `URL` instance.
25
22
  */
26
23
  export declare function parseURL(raw: string): URL;
27
24
  /**
28
- * Returns the origin of `url` in `scheme://hostname:port` form. The port is
29
- * always included explicitly, defaulting to `443` for `https:` and `80` for
30
- * `http:`.
25
+ * Extract the origin (scheme + hostname + port) from a URL.
31
26
  *
32
27
  * @param {string} url - Absolute URL string.
33
28
  * @returns {string} Origin string (e.g. `"https://example.com:443"`).
34
29
  */
35
30
  export declare function originOf(url: string): string;
36
31
  /**
37
- * Extracts the hostname from `url` for use as the TLS SNI server-name value.
32
+ * Extract the hostname for TLS SNI from a URL.
38
33
  *
39
34
  * @param {string} url - Absolute URL string.
40
- * @returns {string} Hostname without port (e.g. `"example.com"`).
35
+ * @returns {string} Hostname string.
41
36
  */
42
37
  export declare function sniHost(url: string): string;
43
38
  /**
44
- * Extracts the host and port from `url`. The port defaults to `443` for
45
- * `https:` and `80` for `http:` when not explicitly specified in the URL.
39
+ * Extract the hostname and port from a URL.
46
40
  *
47
41
  * @param {string} url - Absolute URL string.
48
- * @returns {{ host: string; port: number }} Hostname and numeric port.
42
+ * @returns {{ host: string; port: number }} Object with `host` and numeric `port`.
49
43
  */
50
44
  export declare function hostPort(url: string): {
51
45
  host: string;
52
46
  port: number;
53
47
  };
54
48
  /**
55
- * Returns the path and query string of `url` suitable for use as the
56
- * request-target in an HTTP/1.1 request line.
49
+ * Extract the request path (pathname + search) from a URL.
57
50
  *
58
51
  * @param {string} url - Absolute URL string.
59
- * @returns {string} Path + query string (e.g. `"/search?q=hello"`).
52
+ * @returns {string} Path string suitable for an HTTP request line.
60
53
  */
61
54
  export declare function requestPath(url: string): string;
62
55
  //# sourceMappingURL=url.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO7E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CASpG;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAEzC;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAOpE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG/C"}
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO7E;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CASpG;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAOpE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG/C"}
package/dist/utils/url.js CHANGED
@@ -1,10 +1,9 @@
1
1
  /**
2
- * Resolves `relative` against `base`. When `base` is `undefined` or the
3
- * resolution fails, `relative` is returned as-is.
2
+ * Resolve a relative URL against an optional base.
4
3
  *
5
- * @param {string | undefined} base - Base URL string.
6
- * @param {string} relative - Relative or absolute URL to resolve.
7
- * @returns {string} The resolved absolute URL, or `relative` if resolution fails.
4
+ * @param {string | undefined} base - Base URL string.
5
+ * @param {string} relative - Relative or absolute URL string.
6
+ * @returns {string} Resolved absolute URL string.
8
7
  */
9
8
  export function resolveURL(base, relative) {
10
9
  if (!base)
@@ -17,12 +16,11 @@ export function resolveURL(base, relative) {
17
16
  }
18
17
  }
19
18
  /**
20
- * Appends `params` as query-string parameters to `url`. Existing parameters in
21
- * the URL are preserved. `undefined` and `null` values are omitted.
19
+ * Append query parameters to a URL string.
22
20
  *
23
- * @param {string} url - Base URL.
24
- * @param {Record<string, string | number | boolean>} [params] - Key-value pairs to append.
25
- * @returns {string} URL with appended query parameters.
21
+ * @param {string} url - Base URL string.
22
+ * @param {Record<string, string | number | boolean>} [params] - Key-value pairs to append.
23
+ * @returns {string} URL string with appended query parameters.
26
24
  */
27
25
  export function appendParams(url, params) {
28
26
  if (!params || Object.keys(params).length === 0)
@@ -36,19 +34,16 @@ export function appendParams(url, params) {
36
34
  return parsed.toString();
37
35
  }
38
36
  /**
39
- * Parses `raw` into a `URL` object.
37
+ * Parse a URL string into a `URL` object.
40
38
  *
41
- * @param {string} raw - Absolute URL string to parse.
42
- * @returns {URL} Parsed URL.
43
- * @throws {TypeError} If `raw` is not a valid absolute URL.
39
+ * @param {string} raw - Raw URL string.
40
+ * @returns {URL} Parsed `URL` instance.
44
41
  */
45
42
  export function parseURL(raw) {
46
43
  return new URL(raw);
47
44
  }
48
45
  /**
49
- * Returns the origin of `url` in `scheme://hostname:port` form. The port is
50
- * always included explicitly, defaulting to `443` for `https:` and `80` for
51
- * `http:`.
46
+ * Extract the origin (scheme + hostname + port) from a URL.
52
47
  *
53
48
  * @param {string} url - Absolute URL string.
54
49
  * @returns {string} Origin string (e.g. `"https://example.com:443"`).
@@ -59,20 +54,19 @@ export function originOf(url) {
59
54
  return `${u.protocol}//${u.hostname}:${port}`;
60
55
  }
61
56
  /**
62
- * Extracts the hostname from `url` for use as the TLS SNI server-name value.
57
+ * Extract the hostname for TLS SNI from a URL.
63
58
  *
64
59
  * @param {string} url - Absolute URL string.
65
- * @returns {string} Hostname without port (e.g. `"example.com"`).
60
+ * @returns {string} Hostname string.
66
61
  */
67
62
  export function sniHost(url) {
68
63
  return new URL(url).hostname;
69
64
  }
70
65
  /**
71
- * Extracts the host and port from `url`. The port defaults to `443` for
72
- * `https:` and `80` for `http:` when not explicitly specified in the URL.
66
+ * Extract the hostname and port from a URL.
73
67
  *
74
68
  * @param {string} url - Absolute URL string.
75
- * @returns {{ host: string; port: number }} Hostname and numeric port.
69
+ * @returns {{ host: string; port: number }} Object with `host` and numeric `port`.
76
70
  */
77
71
  export function hostPort(url) {
78
72
  const u = new URL(url);
@@ -83,11 +77,10 @@ export function hostPort(url) {
83
77
  };
84
78
  }
85
79
  /**
86
- * Returns the path and query string of `url` suitable for use as the
87
- * request-target in an HTTP/1.1 request line.
80
+ * Extract the request path (pathname + search) from a URL.
88
81
  *
89
82
  * @param {string} url - Absolute URL string.
90
- * @returns {string} Path + query string (e.g. `"/search?q=hello"`).
83
+ * @returns {string} Path string suitable for an HTTP request line.
91
84
  */
92
85
  export function requestPath(url) {
93
86
  const u = new URL(url);
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,IAAwB,EAAE,QAAgB;IACnE,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAkD;IAC1F,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AAC/B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,WAAW,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,QAAQ;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW;KAClD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAwB,EAAE,QAAgB;IACnE,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAkD;IAC1F,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,WAAW,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,QAAQ;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW;KAClD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;AAC/B,CAAC"}
@@ -1,104 +1,86 @@
1
1
  import { EventEmitter } from "node:events";
2
- /**
3
- * Options for creating a {@link WebSocketClient} connection.
4
- *
5
- * @typedef {Object} WebSocketOptions
6
- * @property {string} [impersonate] - Browser profile name for fingerprint impersonation.
7
- * @property {boolean} [stealth] - Use the stealth TLS engine for byte-level fingerprinting.
8
- * @property {Record<string, string>} [headers] - Additional HTTP upgrade request headers.
9
- * @property {string[]} [protocols] - Sub-protocol names to negotiate.
10
- * @property {boolean} [insecure] - Skip TLS certificate validation for `wss:` connections.
11
- * @property {number} [timeout] - Connection timeout in milliseconds.
12
- */
2
+ /** Configuration options for a WebSocket connection. */
13
3
  export interface WebSocketOptions {
4
+ /** Browser profile name to impersonate for TLS fingerprinting. */
14
5
  impersonate?: string;
6
+ /** Use the stealth TLS engine for fingerprint impersonation. */
15
7
  stealth?: boolean;
8
+ /** Additional HTTP headers to include in the upgrade request. */
16
9
  headers?: Record<string, string>;
10
+ /** Subprotocols to offer during the upgrade handshake. */
17
11
  protocols?: string[];
12
+ /** Skip TLS certificate verification. */
18
13
  insecure?: boolean;
14
+ /** Connection timeout in milliseconds. */
19
15
  timeout?: number;
20
- /** Enable `permessage-deflate` compression (RFC 7692). Default: `false`. */
16
+ /** Enable per-message deflate compression. */
21
17
  compress?: boolean;
22
18
  }
23
- /**
24
- * WebSocket connection state.
25
- *
26
- * @typedef {'connecting' | 'open' | 'closing' | 'closed'} WebSocketState
27
- */
19
+ /** Current lifecycle state of the WebSocket connection. */
28
20
  export type WebSocketState = "connecting" | "open" | "closing" | "closed";
29
- /**
30
- * Typed event map for {@link WebSocketClient}.
31
- *
32
- * @typedef {Object} WebSocketEvents
33
- * @property {[]} open - Emitted when the connection is established.
34
- * @property {[data: string | Buffer, isBinary: boolean]} message - Emitted for each incoming message.
35
- * @property {[code: number, reason: string]} close - Emitted when the connection closes.
36
- * @property {[error: Error]} error - Emitted on connection or protocol errors.
37
- * @property {[data: Buffer]} ping - Emitted when a PING frame is received.
38
- * @property {[data: Buffer]} pong - Emitted when a PONG frame is received.
39
- */
21
+ /** Event map for {@link WebSocketClient} emitter. */
40
22
  export interface WebSocketEvents {
23
+ /** Fired when the connection has been established. */
41
24
  open: [];
25
+ /** Fired when a text or binary message is received. */
42
26
  message: [data: string | Buffer, isBinary: boolean];
27
+ /** Fired when the connection has been cleanly closed. */
43
28
  close: [code: number, reason: string];
29
+ /** Fired on transport or protocol errors. */
44
30
  error: [error: Error];
31
+ /** Fired when a ping frame is received. */
45
32
  ping: [data: Buffer];
33
+ /** Fired when a pong frame is received. */
46
34
  pong: [data: Buffer];
47
35
  }
48
36
  /**
49
- * WebSocket client with optional browser fingerprint impersonation. Emits
50
- * typed lifecycle events (`open`, `message`, `close`, `error`, `ping`, `pong`).
51
- * The connection is initiated asynchronously in the constructor; listen for
52
- * the `'open'` event before sending frames.
53
- *
54
- * @example
55
- * const ws = new WebSocketClient('wss://echo.example.com', { impersonate: 'chrome136' });
56
- * ws.on('open', () => ws.sendText('hello'));
57
- * ws.on('message', (data) => console.log(data));
37
+ * RFC 6455 WebSocket client with optional TLS fingerprinting
38
+ * and per-message deflate compression.
58
39
  */
59
40
  export declare class WebSocketClient extends EventEmitter {
41
+ /** Current connection lifecycle state. */
60
42
  state: WebSocketState;
43
+ /** Negotiated subprotocol, or empty string if none. */
61
44
  protocol: string;
45
+ /** Original WebSocket URL. */
62
46
  readonly url: string;
63
47
  private socket;
64
48
  private parser;
65
49
  private fragments;
66
50
  private fragmentOpcode;
51
+ private fragmentSize;
52
+ private static readonly MAX_FRAGMENT_SIZE;
67
53
  private deflate;
68
54
  /**
69
- * Creates a new WebSocketClient and begins connecting to `url`.
55
+ * Create a new WebSocket connection.
70
56
  *
71
- * @param {string} url - WebSocket URL (`ws:` or `wss:`).
72
- * @param {WebSocketOptions} [options={}] - Connection and impersonation options.
57
+ * @param {string} url - `ws://` or `wss://` URL to connect to.
58
+ * @param {WebSocketOptions} [options] - Connection and TLS options.
73
59
  */
74
60
  constructor(url: string, options?: WebSocketOptions);
75
61
  /**
76
- * Sends a UTF-8 text message.
62
+ * Send a UTF-8 text message.
77
63
  *
78
- * @param {string} data - Text to send.
79
- * @throws {NLcURLError} If the WebSocket is not in the `'open'` state.
64
+ * @param {string} data - Text payload to send.
80
65
  */
81
66
  sendText(data: string): void;
82
67
  /**
83
- * Sends a binary message.
68
+ * Send a binary message.
84
69
  *
85
- * @param {Buffer} data - Binary data to send.
86
- * @throws {NLcURLError} If the WebSocket is not in the `'open'` state.
70
+ * @param {Buffer} data - Binary payload to send.
87
71
  */
88
72
  sendBinary(data: Buffer): void;
89
73
  /**
90
- * Sends a PING control frame.
74
+ * Send a WebSocket ping frame.
91
75
  *
92
- * @param {Buffer} [data=Buffer.alloc(0)] - Optional ping payload (up to 125 bytes).
93
- * @throws {NLcURLError} If the WebSocket is not in the `'open'` state.
76
+ * @param {Buffer} [data] - Optional payload (up to 125 bytes).
94
77
  */
95
78
  ping(data?: Buffer): void;
96
79
  /**
97
- * Initiates a graceful close handshake by sending a CLOSE frame with the
98
- * given status code and reason. Does nothing if the connection is not open.
80
+ * Initiate a graceful close handshake.
99
81
  *
100
- * @param {number} [code=1000] - WebSocket close status code.
101
- * @param {string} [reason=''] - Human-readable close reason (UTF-8, max 123 bytes).
82
+ * @param {number} [code] - Close status code (default `1000`).
83
+ * @param {string} [reason] - Human-readable close reason.
102
84
  */
103
85
  close(code?: number, reason?: string): void;
104
86
  private assertOpen;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/ws/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,EAAE,CAAC;IACT,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IACxC,KAAK,EAAE,cAAc,CAAgB;IACrC,QAAQ,SAAM;IACrB,SAAgB,GAAG,EAAE,MAAM,CAAC;IAE5B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,OAAO,CAAkC;IAEjD;;;;;OAKG;gBACS,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAWvD;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAe5B;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAc9B;;;;;OAKG;IACH,IAAI,CAAC,IAAI,GAAE,MAAwB,GAAG,IAAI;IAK1C;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,SAAO,EAAE,MAAM,SAAK,GAAG,IAAI;IAarC,OAAO,CAAC,UAAU;YAMJ,OAAO;IA4DrB,OAAO,CAAC,cAAc;IAiHtB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,WAAW;CA6EpB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/ws/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1E,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,IAAI,EAAE,EAAE,CAAC;IACT,uDAAuD;IACvD,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpD,yDAAyD;IACzD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,6CAA6C;IAC7C,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtB,2CAA2C;IAC3C,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrB,2CAA2C;IAC3C,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;CACtB;AAiBD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,0CAA0C;IACnC,KAAK,EAAE,cAAc,CAAgB;IAC5C,uDAAuD;IAChD,QAAQ,SAAM;IACrB,8BAA8B;IAC9B,SAAgB,GAAG,EAAE,MAAM,CAAC;IAE5B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IAC7D,OAAO,CAAC,OAAO,CAAkC;IAEjD;;;;;OAKG;gBACS,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAWvD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAe5B;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAc9B;;;;OAIG;IACH,IAAI,CAAC,IAAI,GAAE,MAAwB,GAAG,IAAI;IAK1C;;;;;OAKG;IACH,KAAK,CAAC,IAAI,SAAO,EAAE,MAAM,SAAK,GAAG,IAAI;IAarC,OAAO,CAAC,UAAU;YAMJ,OAAO;IAgErB,OAAO,CAAC,cAAc;IAoHtB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,WAAW;CAoHpB"}
package/dist/ws/client.js CHANGED
@@ -6,31 +6,43 @@ import { NLcURLError, ConnectionError } from "../core/errors.js";
6
6
  import { validateWebSocketUrl } from "../core/validation.js";
7
7
  import { encodeFrame, FrameParser, Opcode, generateWebSocketKey, computeAcceptKey } from "./frame.js";
8
8
  import { buildDeflateOffer, parseDeflateResponse, PerMessageDeflate } from "./permessage-deflate.js";
9
+ /** Strict UTF-8 text decoder that throws on invalid sequences (RFC 6455 §8.1). */
10
+ const strictUtf8Decoder = new TextDecoder("utf-8", { fatal: true });
9
11
  /**
10
- * WebSocket client with optional browser fingerprint impersonation. Emits
11
- * typed lifecycle events (`open`, `message`, `close`, `error`, `ping`, `pong`).
12
- * The connection is initiated asynchronously in the constructor; listen for
13
- * the `'open'` event before sending frames.
14
- *
15
- * @example
16
- * const ws = new WebSocketClient('wss://echo.example.com', { impersonate: 'chrome136' });
17
- * ws.on('open', () => ws.sendText('hello'));
18
- * ws.on('message', (data) => console.log(data));
12
+ * Validate and decode a buffer as UTF-8 text.
13
+ * Returns the decoded string, or null if the buffer contains invalid UTF-8.
14
+ */
15
+ function decodeUtf8Strict(buf) {
16
+ try {
17
+ return strictUtf8Decoder.decode(buf);
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ /**
24
+ * RFC 6455 WebSocket client with optional TLS fingerprinting
25
+ * and per-message deflate compression.
19
26
  */
20
27
  export class WebSocketClient extends EventEmitter {
28
+ /** Current connection lifecycle state. */
21
29
  state = "connecting";
30
+ /** Negotiated subprotocol, or empty string if none. */
22
31
  protocol = "";
32
+ /** Original WebSocket URL. */
23
33
  url;
24
34
  socket = null;
25
35
  parser = new FrameParser();
26
36
  fragments = [];
27
37
  fragmentOpcode = Opcode.TEXT;
38
+ fragmentSize = 0;
39
+ static MAX_FRAGMENT_SIZE = 64 * 1024 * 1024;
28
40
  deflate = null;
29
41
  /**
30
- * Creates a new WebSocketClient and begins connecting to `url`.
42
+ * Create a new WebSocket connection.
31
43
  *
32
- * @param {string} url - WebSocket URL (`ws:` or `wss:`).
33
- * @param {WebSocketOptions} [options={}] - Connection and impersonation options.
44
+ * @param {string} url - `ws://` or `wss://` URL to connect to.
45
+ * @param {WebSocketOptions} [options] - Connection and TLS options.
34
46
  */
35
47
  constructor(url, options = {}) {
36
48
  super();
@@ -42,10 +54,9 @@ export class WebSocketClient extends EventEmitter {
42
54
  });
43
55
  }
44
56
  /**
45
- * Sends a UTF-8 text message.
57
+ * Send a UTF-8 text message.
46
58
  *
47
- * @param {string} data - Text to send.
48
- * @throws {NLcURLError} If the WebSocket is not in the `'open'` state.
59
+ * @param {string} data - Text payload to send.
49
60
  */
50
61
  sendText(data) {
51
62
  this.assertOpen();
@@ -63,10 +74,9 @@ export class WebSocketClient extends EventEmitter {
63
74
  }
64
75
  }
65
76
  /**
66
- * Sends a binary message.
77
+ * Send a binary message.
67
78
  *
68
- * @param {Buffer} data - Binary data to send.
69
- * @throws {NLcURLError} If the WebSocket is not in the `'open'` state.
79
+ * @param {Buffer} data - Binary payload to send.
70
80
  */
71
81
  sendBinary(data) {
72
82
  this.assertOpen();
@@ -83,21 +93,19 @@ export class WebSocketClient extends EventEmitter {
83
93
  }
84
94
  }
85
95
  /**
86
- * Sends a PING control frame.
96
+ * Send a WebSocket ping frame.
87
97
  *
88
- * @param {Buffer} [data=Buffer.alloc(0)] - Optional ping payload (up to 125 bytes).
89
- * @throws {NLcURLError} If the WebSocket is not in the `'open'` state.
98
+ * @param {Buffer} [data] - Optional payload (up to 125 bytes).
90
99
  */
91
100
  ping(data = Buffer.alloc(0)) {
92
101
  this.assertOpen();
93
102
  this.socket.write(encodeFrame(Opcode.PING, data));
94
103
  }
95
104
  /**
96
- * Initiates a graceful close handshake by sending a CLOSE frame with the
97
- * given status code and reason. Does nothing if the connection is not open.
105
+ * Initiate a graceful close handshake.
98
106
  *
99
- * @param {number} [code=1000] - WebSocket close status code.
100
- * @param {string} [reason=''] - Human-readable close reason (UTF-8, max 123 bytes).
107
+ * @param {number} [code] - Close status code (default `1000`).
108
+ * @param {string} [reason] - Human-readable close reason.
101
109
  */
102
110
  close(code = 1000, reason = "") {
103
111
  if (this.state !== "open")
@@ -138,7 +146,9 @@ export class WebSocketClient extends EventEmitter {
138
146
  else {
139
147
  const net = await import("node:net");
140
148
  transport = await new Promise((resolve, reject) => {
141
- const sock = net.createConnection({ host, port }, () => resolve(sock));
149
+ const sock = net.createConnection({ host, port }, () => {
150
+ resolve(sock);
151
+ });
142
152
  sock.once("error", reject);
143
153
  if (options.timeout) {
144
154
  sock.setTimeout(options.timeout, () => {
@@ -152,7 +162,9 @@ export class WebSocketClient extends EventEmitter {
152
162
  await this.performUpgrade(transport, parsed, options);
153
163
  this.state = "open";
154
164
  this.emit("open");
155
- transport.on("data", (chunk) => this.onData(chunk));
165
+ transport.on("data", (chunk) => {
166
+ this.onData(chunk);
167
+ });
156
168
  transport.on("error", (err) => {
157
169
  this.state = "closed";
158
170
  this.emit("error", err);
@@ -212,11 +224,13 @@ export class WebSocketClient extends EventEmitter {
212
224
  const headerStr = text.substring(0, headerEnd);
213
225
  const [statusLine, ...headerLines] = headerStr.split("\r\n");
214
226
  if (!statusLine) {
215
- return reject(new NLcURLError("Empty upgrade response", "ERR_WS_UPGRADE"));
227
+ reject(new NLcURLError("Empty upgrade response", "ERR_WS_UPGRADE"));
228
+ return;
216
229
  }
217
230
  const statusMatch = statusLine.match(/^HTTP\/\d\.\d (\d{3})/);
218
231
  if (!statusMatch || statusMatch[1] !== "101") {
219
- return reject(new NLcURLError(`WebSocket upgrade failed: ${statusLine}`, "ERR_WS_UPGRADE"));
232
+ reject(new NLcURLError(`WebSocket upgrade failed: ${statusLine}`, "ERR_WS_UPGRADE"));
233
+ return;
220
234
  }
221
235
  const headers = new Map();
222
236
  for (const line of headerLines) {
@@ -227,7 +241,8 @@ export class WebSocketClient extends EventEmitter {
227
241
  }
228
242
  const accept = headers.get("sec-websocket-accept");
229
243
  if (accept !== expectedAccept) {
230
- return reject(new NLcURLError("Invalid Sec-WebSocket-Accept header", "ERR_WS_UPGRADE"));
244
+ reject(new NLcURLError("Invalid Sec-WebSocket-Accept header", "ERR_WS_UPGRADE"));
245
+ return;
231
246
  }
232
247
  this.protocol = headers.get("sec-websocket-protocol") ?? "";
233
248
  const extHeader = headers.get("sec-websocket-extensions");
@@ -277,39 +292,82 @@ export class WebSocketClient extends EventEmitter {
277
292
  this.deflate
278
293
  .decompress(frame.payload)
279
294
  .then((decompressed) => {
280
- const data = isBinary ? decompressed : decompressed.toString("utf8");
281
- this.emit("message", data, isBinary);
295
+ if (isBinary) {
296
+ this.emit("message", decompressed, true);
297
+ }
298
+ else {
299
+ const text = decodeUtf8Strict(decompressed);
300
+ if (text === null) {
301
+ this.close(1007, "Invalid UTF-8");
302
+ return;
303
+ }
304
+ this.emit("message", text, false);
305
+ }
282
306
  })
283
307
  .catch((err) => this.emit("error", err));
284
308
  }
285
309
  else {
286
- const data = isBinary ? frame.payload : frame.payload.toString("utf8");
287
- this.emit("message", data, isBinary);
310
+ if (isBinary) {
311
+ this.emit("message", frame.payload, true);
312
+ }
313
+ else {
314
+ const text = decodeUtf8Strict(frame.payload);
315
+ if (text === null) {
316
+ this.close(1007, "Invalid UTF-8");
317
+ return;
318
+ }
319
+ this.emit("message", text, false);
320
+ }
288
321
  }
289
322
  }
290
323
  else {
291
324
  this.fragmentOpcode = frame.opcode;
292
325
  this.fragments = [frame.payload];
326
+ this.fragmentSize = frame.payload.length;
293
327
  }
294
328
  break;
295
329
  case Opcode.CONTINUATION:
330
+ this.fragmentSize += frame.payload.length;
331
+ if (this.fragmentSize > WebSocketClient.MAX_FRAGMENT_SIZE) {
332
+ this.close(1009, "Message too big");
333
+ return;
334
+ }
296
335
  this.fragments.push(frame.payload);
297
336
  if (frame.fin) {
298
337
  const assembled = Buffer.concat(this.fragments);
299
338
  this.fragments = [];
339
+ this.fragmentSize = 0;
300
340
  const isBinary = this.fragmentOpcode === Opcode.BINARY;
301
341
  if (this.deflate) {
302
342
  this.deflate
303
343
  .decompress(assembled)
304
344
  .then((decompressed) => {
305
- const data = isBinary ? decompressed : decompressed.toString("utf8");
306
- this.emit("message", data, isBinary);
345
+ if (isBinary) {
346
+ this.emit("message", decompressed, true);
347
+ }
348
+ else {
349
+ const text = decodeUtf8Strict(decompressed);
350
+ if (text === null) {
351
+ this.close(1007, "Invalid UTF-8");
352
+ return;
353
+ }
354
+ this.emit("message", text, false);
355
+ }
307
356
  })
308
357
  .catch((err) => this.emit("error", err));
309
358
  }
310
359
  else {
311
- const data = isBinary ? assembled : assembled.toString("utf8");
312
- this.emit("message", data, isBinary);
360
+ if (isBinary) {
361
+ this.emit("message", assembled, true);
362
+ }
363
+ else {
364
+ const text = decodeUtf8Strict(assembled);
365
+ if (text === null) {
366
+ this.close(1007, "Invalid UTF-8");
367
+ return;
368
+ }
369
+ this.emit("message", text, false);
370
+ }
313
371
  }
314
372
  }
315
373
  break;