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
package/README.md CHANGED
@@ -1,31 +1,40 @@
1
1
  # NLcURL
2
2
 
3
- Pure TypeScript HTTP client with browser fingerprint impersonation.
4
-
5
- NLcURL provides session-based and one-shot HTTP APIs, browser profile impersonation, HTTP/2 support, cookie management, and a CLI. The project has zero runtime dependencies and uses only Node.js built-in modules.
6
-
7
- ## Highlights
8
-
9
- - Zero runtime dependencies
10
- - Session API with connection pooling
11
- - HTTP/1.1 and HTTP/2 (ALPN negotiated) with RFC 9113 flow control
12
- - Browser profile impersonation (Chrome, Firefox, Safari, Edge, Tor)
13
- - Optional custom JA3 and Akamai H2 fingerprint values in request model
14
- - Cookie jar with RFC 6265 behavior, Public Suffix List enforcement, `SameSite=Lax` default, and `__Host-`/`__Secure-` prefix validation
15
- - `FormData` class for `multipart/form-data` uploads (RFC 7578)
16
- - mTLS and custom CA trust via `TLSOptions` (`cert`, `key`, `pfx`, `ca`, `passphrase`)
17
- - `ReadableStream<Uint8Array>` upload bodies (auto-drained before encoding)
18
- - Header validation per RFC 7230 (rejects CR/LF/NUL injection)
19
- - Streaming response support (`stream: true`) with automatic decompression
20
- - Automatic dual-stack connectivity via Happy Eyeballs (RFC 8305) — falls back to IPv4 instantly when IPv6 is unreachable, with optional `dnsFamily` pin
21
- - Automatic retry on H2 RST_STREAM protocol errors (codes 1, 2, 7, 8, 11, 13) with capped exponential backoff
22
- - CLI (`nlcurl`) for scripted and interactive use
23
- - WebSocket client with optional impersonated TLS handshake
24
-
25
- ## Requirements
26
-
27
- - Node.js `>= 18.17.0`
28
- - npm (or compatible package manager)
3
+ A pure TypeScript HTTP client with native TLS fingerprint impersonation. Zero runtime dependencies.
4
+
5
+ NLcURL provides HTTP/1.1 and HTTP/2 request capabilities with a custom stealth TLS engine that reproduces browser-grade TLS and HTTP/2 fingerprints. It is designed for environments where accurate browser impersonation, advanced protocol control, and strict standards compliance are required.
6
+
7
+ > **Note:** HTTP/3 (QUIC) is not supported. NLcURL supports HTTP/1.1 and HTTP/2 only.
8
+
9
+ ## Features
10
+
11
+ - **TLS Fingerprint Impersonation** — Reproduce the exact TLS ClientHello of Chrome, Firefox, Safari, Edge, and Tor across 49 resolvable browser profiles, covering JA3, JA4, and Akamai HTTP/2 fingerprints.
12
+ - **Custom Stealth TLS Engine** — A from-scratch TLS 1.2/1.3 implementation with GREASE injection (RFC 8701), configurable cipher suites, extension ordering, Encrypted Client Hello (ECH) support, HelloRetryRequest handling, KeyUpdate post-handshake rekeying, and session resumption via PSK.
13
+ - **HTTP/1.1 & HTTP/2** — Full HTTP/1.1 with chunked transfer encoding, obs-fold header handling, and TE/CL conflict detection. HTTP/2 with HPACK compression, stream multiplexing, configurable flow control, MAX_CONCURRENT_STREAMS enforcement, PUSH_PROMISE rejection, and CONTINUATION size limits.
14
+ - **Connection Pooling** Per-origin connection reuse with idle eviction, configurable pool limits, and automatic HTTP/2 multiplexing.
15
+ - **RFC 6265 Cookie Jar** — Persistent cookie storage with Public Suffix List validation, `__Host-`/`__Secure-` prefix enforcement, `SameSite` enforcement (Strict/Lax/None with Secure requirement per RFC 6265bis), CHIPS partitioned cookies, and Netscape file format import/export.
16
+ - **HTTP Caching (RFC 9111)** In-memory cache with multi-variant `Vary` support, `s-maxage`/`max-age` freshness, `ETag`/`Last-Modified` conditional revalidation, `Age` header, request-side `Cache-Control`, unsafe method invalidation, `stale-while-revalidate`, heuristic freshness, and five cache modes.
17
+ - **HSTS (RFC 6797)** — Automatic `http://` to `https://` upgrading with `includeSubDomains` support and configurable preload lists.
18
+ - **DNS-over-HTTPS (RFC 8484)** Wire-format DoH with GET/POST methods, EDNS(0) with padding (RFC 6891/7830), bootstrap resolution, and integrated DNS caching.
19
+ - **DNS-over-TLS (RFC 7858)** — Secure DNS resolution over TLS port 853 with persistent connection support and pre-configured public resolvers.
20
+ - **HTTPS Resource Records (RFC 9460)**SVCB/HTTPS DNS record resolution for ALPN hints, ECH config delivery, and address hints.
21
+ - **Proxy Support** HTTP CONNECT tunneling, HTTPS proxies, SOCKS4/4a, and SOCKS5 with optional username/password authentication. Environment variable resolution (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`).
22
+ - **WebSocket (RFC 6455)** Full WebSocket client with TLS fingerprinting, per-message deflate compression (RFC 7692), control frame validation (≤125 bytes), ping/pong, and binary/text framing.
23
+ - **Server-Sent Events** — W3C EventSource-compliant SSE parser with streaming async generator interface, UTF-8 BOM stripping, and cross-chunk CRLF handling.
24
+ - **Request/Response Interceptors** — Middleware pipeline for modifying requests before send and responses after receipt.
25
+ - **Retry with Backoff** — Configurable automatic retry with linear or exponential backoff, jitter, `Retry-After` header respect, and custom retry predicates.
26
+ - **Rate Limiting** — Token-bucket rate limiter with configurable request quotas and automatic queuing.
27
+ - **Circuit Breaker** — Per-origin circuit breaker with configurable failure thresholds, half-open probing, and automatic recovery.
28
+ - **Request Body Compression** Outgoing body compression with gzip, deflate, and Brotli.
29
+ - **Response Decompression** — Automatic decompression of gzip, deflate, Brotli, and zstd (Node.js 20.10+) with multi-layer encoding support.
30
+ - **Happy Eyeballs v2 (RFC 8305)** — Dual-stack connection racing with 250ms stagger for optimal latency.
31
+ - **Alt-Svc (RFC 7838)** — HTTP Alternative Services tracking with automatic protocol upgrade preference.
32
+ - **FormData (RFC 7578)** — Multipart form-data encoding with file upload support.
33
+ - **Authentication** — Built-in Basic, Bearer, Digest (RFC 7616), and AWS Signature V4 authentication, plus Digest proxy authentication.
34
+ - **Progress Callbacks** — Upload and download progress events with byte counts and percentages.
35
+ - **Structured Logging** — Console and JSON logger implementations with child logger support and configurable log levels.
36
+ - **CLI Tool** — `nlcurl` command-line interface with curl-compatible flags for scripting and interactive use.
37
+ - **Zero Dependencies** — Pure TypeScript with no runtime dependencies. Requires only Node.js ≥ 18.17.0.
29
38
 
30
39
  ## Installation
31
40
 
@@ -33,155 +42,155 @@ NLcURL provides session-based and one-shot HTTP APIs, browser profile impersonat
33
42
  npm install nlcurl
34
43
  ```
35
44
 
36
- For local development:
37
-
38
- ```bash
39
- npm install
40
- npm run build
41
- ```
45
+ **Requirements:** Node.js ≥ 18.17.0
42
46
 
43
47
  ## Quick Start
44
48
 
45
- ### One-shot request
49
+ ### One-Shot Requests
46
50
 
47
- ```ts
48
- import { request } from "nlcurl";
51
+ ```typescript
52
+ import { get, post } from "nlcurl";
49
53
 
50
- const response = await request({
51
- url: "https://httpbin.org/get",
52
- impersonate: "chrome136",
53
- });
54
+ // Simple GET
55
+ const response = await get("https://httpbin.org/get");
56
+ console.log(response.status); // 200
57
+ console.log(response.json()); // parsed JSON body
54
58
 
55
- console.log(response.status);
56
- console.log(response.json());
59
+ // POST with JSON body
60
+ const res = await post("https://httpbin.org/post", { key: "value" });
61
+ console.log(res.text());
57
62
  ```
58
63
 
59
- ### Multipart form upload
60
-
61
- ```ts
62
- import { post, FormData } from "nlcurl";
63
-
64
- const form = new FormData();
65
- form.append("username", "alice");
66
- form.append("avatar", { data: Buffer.from("..."), filename: "avatar.png", contentType: "image/png" });
67
-
68
- const res = await post("https://httpbin.org/post", form);
69
- console.log(res.json());
70
- ```
64
+ ### Browser Impersonation
71
65
 
72
- ### mTLS / custom CA
66
+ ```typescript
67
+ import { get } from "nlcurl";
73
68
 
74
- ```ts
75
- import { request } from "nlcurl";
76
-
77
- const res = await request({
78
- url: "https://internal-api.example.com/data",
79
- tls: {
80
- cert: fs.readFileSync("client.pem"),
81
- key: fs.readFileSync("client-key.pem"),
82
- ca: fs.readFileSync("ca.pem"),
83
- },
69
+ const response = await get("https://example.com", {
70
+ impersonate: "chrome136",
84
71
  });
85
72
  ```
86
73
 
87
- ### Session-based usage
74
+ ### Session with Connection Reuse
88
75
 
89
- ```ts
76
+ ```typescript
90
77
  import { createSession } from "nlcurl";
91
78
 
92
79
  const session = createSession({
93
- baseURL: "https://httpbin.org",
94
- impersonate: "firefox138",
95
- followRedirects: true,
80
+ baseURL: "https://api.example.com",
81
+ impersonate: "chrome136",
82
+ headers: { "authorization": "Bearer token" },
83
+ retry: { count: 3, backoff: "exponential" },
96
84
  });
97
85
 
98
- const res = await session.get("/headers");
99
- console.log(res.json());
86
+ const users = await session.get("/users");
87
+ const user = await session.post("/users", { name: "Alice" });
100
88
 
101
89
  session.close();
102
90
  ```
103
91
 
104
- ### CLI usage
92
+ ### Stealth TLS
105
93
 
106
- ```bash
107
- nlcurl --impersonate chrome136 https://tls.browserleaks.com/json
94
+ ```typescript
95
+ import { get } from "nlcurl";
96
+
97
+ // Uses the custom stealth TLS engine (bypasses Node.js TLS)
98
+ const response = await get("https://example.com", {
99
+ stealth: true,
100
+ impersonate: "chrome136",
101
+ });
108
102
  ```
109
103
 
110
- ## CLI Reference
104
+ ### WebSocket
111
105
 
112
- ```text
113
- nlcurl [OPTIONS] <URL>
106
+ ```typescript
107
+ import { WebSocketClient } from "nlcurl";
108
+
109
+ const ws = new WebSocketClient("wss://echo.websocket.events", {
110
+ impersonate: "chrome136",
111
+ compress: true,
112
+ });
113
+
114
+ ws.on("open", () => ws.sendText("Hello"));
115
+ ws.on("message", (data) => console.log(data));
116
+ ws.on("close", (code, reason) => console.log("Closed:", code));
114
117
  ```
115
118
 
116
- Key options:
117
-
118
- - `-X, --request <METHOD>` HTTP method
119
- - `-H, --header <Name: Value>` add request header
120
- - `-d, --data <DATA>` request body
121
- - `--data-raw <DATA>` raw request body
122
- - `-A, --user-agent <AGENT>` custom User-Agent
123
- - `-o, --output <FILE>` write response body to file
124
- - `-I, --head` send HEAD request
125
- - `-i, --include` include response headers
126
- - `-v, --verbose` verbose request/response output
127
- - `-s, --silent` suppress error output
128
- - `--compressed` request compressed response
129
- - `--impersonate <PROFILE>` browser profile
130
- - `--stealth` use stealth TLS engine
131
- - `--ja3 <FINGERPRINT>` custom JA3 fingerprint string
132
- - `--akamai <FINGERPRINT>` custom Akamai HTTP/2 fingerprint string
133
- - `--list-profiles` list available profiles
134
- - `-x, --proxy <URL>` proxy URL (request model supports it)
135
- - `-U, --proxy-user <USER:PASS>` proxy auth pair
136
- - `-k, --insecure` disable TLS verification
137
- - `-L, --location` follow redirects (default behavior)
138
- - `--no-location` disable redirect following
139
- - `--max-redirs <NUM>` max redirects (default `20`)
140
- - `-m, --max-time <SECONDS>` total timeout
141
- - `--http1.1` force HTTP/1.1
142
- - `--http2` force HTTP/2
143
- - `-b, --cookie <DATA>` send cookie header
144
- - `-c, --cookie-jar <FILE>` capture cookie jar target file
145
- - `-h, --help` show help
146
- - `-V, --version` show version
147
-
148
- For examples, see `docs/SETUP.md` and `docs/API.md`.
149
-
150
- ## Supported Browser Families
151
-
152
- - Chrome (`chrome99` through `chrome136`, plus `chrome_latest` and `chrome` alias)
153
- - Firefox (`firefox133` through `firefox138`, plus `firefox_latest` and `firefox` alias)
154
- - Safari (`safari153` through `safari182`, plus `safari_latest` and `safari` alias)
155
- - Edge (`edge99`, `edge101`, `edge126`, `edge131`, `edge136`, `edge_latest`, `edge` alias)
156
- - Tor (`tor133`, `tor140`, `tor145`, `tor_latest`, `tor` alias)
157
-
158
- Run `nlcurl --list-profiles` to view the exact runtime list.
159
-
160
- ## Development
119
+ ### CLI
161
120
 
162
121
  ```bash
163
- npm install
164
- npm run lint
165
- npm run test
166
- npm run test:integration
167
- npm run build
168
- ```
122
+ # Simple GET
123
+ nlcurl https://httpbin.org/get
169
124
 
170
- Additional commands:
125
+ # Impersonate Chrome with verbose output
126
+ nlcurl -v --impersonate chrome136 https://example.com
171
127
 
172
- - `npm run clean` remove `dist`
173
- - `npm run test:all` run all tests
128
+ # POST with data
129
+ nlcurl -X POST -d '{"key":"value"}' -H "Content-Type: application/json" https://httpbin.org/post
174
130
 
175
- ## Documentation Index
131
+ # Through a proxy
132
+ nlcurl -x socks5://127.0.0.1:1080 https://example.com
133
+ ```
176
134
 
177
- - `docs/API.md` — exported API reference
178
- - `docs/MODULES.md` — module-by-module usage guide
179
- - `docs/ARCHITECTURE.md` system architecture and request flow
180
- - `docs/SETUP.md` — setup, build, and test instructions
181
- - `docs/CONFIGURATION.md` request/session/CLI configuration
182
- - `docs/EXAMPLES.md` comprehensive usage examples (API + CLI)
183
- - `docs/ONBOARDING.md` contributor onboarding guide
135
+ ## Documentation
136
+
137
+ | Document | Description |
138
+ |----------|-------------|
139
+ | [API Reference](docs/API.md) | Complete API for all exported classes, functions, types, and interfaces |
140
+ | [Configuration](docs/CONFIGURATION.md) | All configuration options for requests, sessions, TLS, DNS, caching, and proxies |
141
+ | [Examples](docs/EXAMPLES.md) | Practical usage patterns covering common and advanced scenarios |
142
+ | [Modules](docs/MODULES.md) | Architecture overview and detailed breakdown of every module |
143
+ | [Onboarding](docs/ONBOARDING.md) | Getting started guide for new contributors and integrators |
144
+ | [Setup](docs/SETUP.md) | Build, test, and development environment instructions |
145
+
146
+ ## Browser Profiles
147
+
148
+ 49 resolvable browser profile names across 5 browser families:
149
+
150
+ | Browser | Profiles |
151
+ |---------|----------|
152
+ | Chrome | `chrome99` through `chrome136`, `chrome_latest`, `chrome` |
153
+ | Firefox | `firefox133` through `firefox138`, `firefox_latest`, `firefox` |
154
+ | Safari | `safari153` through `safari182`, `safari_latest`, `safari` |
155
+ | Edge | `edge99` through `edge136`, `edge_latest`, `edge` |
156
+ | Tor | `tor133` through `tor145`, `tor_latest`, `tor` |
157
+
158
+ Each profile includes a complete TLS fingerprint (cipher suites, extensions, supported groups, signature algorithms), HTTP/2 settings fingerprint (SETTINGS frame, WINDOW_UPDATE, pseudo-header order, priority frames), and default HTTP headers with an accurate User-Agent string.
159
+
160
+ ## Standards Compliance
161
+
162
+ NLcURL implements or references the following RFCs and standards:
163
+
164
+ | Standard | Coverage |
165
+ |----------|----------|
166
+ | RFC 8446 | TLS 1.3 — full handshake, key schedule, AEAD record encryption |
167
+ | RFC 5246 | TLS 1.2 — ECDHE key exchange, GCM/ChaCha20 cipher suites |
168
+ | RFC 8701 | GREASE — randomized TLS extension values for anti-fingerprinting |
169
+ | RFC 9113 | HTTP/2 — frames, HPACK, flow control, GOAWAY, stream multiplexing |
170
+ | RFC 7541 | HPACK — header compression with Huffman encoding |
171
+ | RFC 9112 | HTTP/1.1 — message syntax, chunked transfer encoding |
172
+ | RFC 9111 | HTTP Caching — freshness, conditional requests, cache modes |
173
+ | RFC 9110 | HTTP Semantics — methods, status codes, range requests |
174
+ | RFC 6265 | HTTP Cookies — Set-Cookie parsing, domain/path scoping, prefixes |
175
+ | RFC 6797 | HSTS — Strict-Transport-Security header processing |
176
+ | RFC 8484 | DNS-over-HTTPS — wire-format queries, GET/POST methods |
177
+ | RFC 7858 | DNS-over-TLS — encrypted DNS over port 853 |
178
+ | RFC 9460 | SVCB/HTTPS DNS Records — service binding, ALPN, ECH delivery |
179
+ | RFC 8305 | Happy Eyeballs v2 — dual-stack connection racing |
180
+ | RFC 6455 | WebSocket — upgrade handshake, framing, close protocol |
181
+ | RFC 7692 | WebSocket Compression — permessage-deflate negotiation |
182
+ | RFC 7838 | HTTP Alt-Svc — alternative service advertisement |
183
+ | RFC 7578 | Multipart Form Data — multipart/form-data encoding |
184
+ | RFC 7616 | HTTP Digest Authentication — MD5/SHA-256, qop=auth |
185
+ | RFC 1928 | SOCKS5 — proxy protocol with auth negotiation |
186
+ | RFC 5869 | HKDF — key derivation for TLS key schedule |
187
+ | RFC 9180 | HPKE — Hybrid Public Key Encryption for ECH |
188
+ | RFC 7413 | TCP Fast Open — platform-aware TFO support |
189
+ | RFC 8297 | 103 Early Hints — Link header parsing |
190
+ | RFC 6891 | EDNS(0) — Extension Mechanisms for DNS OPT records |
191
+ | RFC 7830 | DNS Padding — query size obfuscation for privacy |
192
+ | RFC 6265bis | Cookie SameSite — Strict/Lax/None enforcement, Secure requirement |
184
193
 
185
194
  ## License
186
195
 
187
- MIT. See `LICENSE`.
196
+ MIT
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Represents a named group of cache keys for batch invalidation.
3
+ */
4
+ export interface CacheGroup {
5
+ name: string;
6
+ keys: Set<string>;
7
+ lastInvalidated: number;
8
+ }
9
+ /**
10
+ * Parses a comma-separated Cache-Groups header into an array of group names.
11
+ *
12
+ * @param {string} header - The raw Cache-Groups header value.
13
+ * @returns {string[]} Parsed group names.
14
+ */
15
+ export declare function parseCacheGroups(header: string): string[];
16
+ /**
17
+ * Manages cache key groupings for targeted invalidation of related cache entries.
18
+ *
19
+ * @class
20
+ */
21
+ export declare class CacheGroupStore {
22
+ private readonly groups;
23
+ /**
24
+ * Associates a cache key with one or more named groups.
25
+ *
26
+ * @param {string} cacheKey - The cache key to associate.
27
+ * @param {string[]} groupNames - The groups to add the key to.
28
+ */
29
+ addToGroups(cacheKey: string, groupNames: string[]): void;
30
+ /**
31
+ * Removes a cache key from all groups.
32
+ *
33
+ * @param {string} cacheKey - The cache key to remove.
34
+ */
35
+ removeFromAll(cacheKey: string): void;
36
+ /**
37
+ * Returns the set of cache keys belonging to a specific group.
38
+ *
39
+ * @param {string} groupName - The group name.
40
+ * @returns {Set<string>} The cache keys in the group.
41
+ */
42
+ getGroupKeys(groupName: string): Set<string>;
43
+ /**
44
+ * Invalidates a single group, clearing its keys and recording the timestamp.
45
+ *
46
+ * @param {string} groupName - The group name to invalidate.
47
+ * @returns {string[]} The cache keys that were in the invalidated group.
48
+ */
49
+ invalidate(groupName: string): string[];
50
+ /**
51
+ * Invalidates all groups, clearing their keys and recording the timestamp.
52
+ *
53
+ * @returns {string[]} All unique cache keys that were invalidated.
54
+ */
55
+ invalidateAll(): string[];
56
+ /**
57
+ * Checks whether a cache key has been invalidated since a given timestamp.
58
+ *
59
+ * @param {string} cacheKey - The cache key to check.
60
+ * @param {number} storedAt - The timestamp when the entry was stored.
61
+ * @returns {boolean} `true` if the key was invalidated after `storedAt`.
62
+ */
63
+ isInvalidatedSince(cacheKey: string, storedAt: number): boolean;
64
+ /**
65
+ * Returns the number of tracked groups.
66
+ *
67
+ * @returns {number} The group count.
68
+ */
69
+ get size(): number;
70
+ /**
71
+ * Removes all groups and their key associations.
72
+ */
73
+ clear(): void;
74
+ }
75
+ //# sourceMappingURL=groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../src/cache/groups.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAMzD;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IAExD;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAWzD;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMrC;;;;;OAKG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAI5C;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAUvC;;;;OAIG;IACH,aAAa,IAAI,MAAM,EAAE;IAYzB;;;;;;OAMG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAS/D;;;;OAIG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Parses a comma-separated Cache-Groups header into an array of group names.
3
+ *
4
+ * @param {string} header - The raw Cache-Groups header value.
5
+ * @returns {string[]} Parsed group names.
6
+ */
7
+ export function parseCacheGroups(header) {
8
+ if (!header)
9
+ return [];
10
+ return header
11
+ .split(",")
12
+ .map((s) => s.trim().replace(/"/g, ""))
13
+ .filter(Boolean);
14
+ }
15
+ /**
16
+ * Manages cache key groupings for targeted invalidation of related cache entries.
17
+ *
18
+ * @class
19
+ */
20
+ export class CacheGroupStore {
21
+ groups = new Map();
22
+ /**
23
+ * Associates a cache key with one or more named groups.
24
+ *
25
+ * @param {string} cacheKey - The cache key to associate.
26
+ * @param {string[]} groupNames - The groups to add the key to.
27
+ */
28
+ addToGroups(cacheKey, groupNames) {
29
+ for (const name of groupNames) {
30
+ let group = this.groups.get(name);
31
+ if (!group) {
32
+ group = { name, keys: new Set(), lastInvalidated: 0 };
33
+ this.groups.set(name, group);
34
+ }
35
+ group.keys.add(cacheKey);
36
+ }
37
+ }
38
+ /**
39
+ * Removes a cache key from all groups.
40
+ *
41
+ * @param {string} cacheKey - The cache key to remove.
42
+ */
43
+ removeFromAll(cacheKey) {
44
+ for (const group of this.groups.values()) {
45
+ group.keys.delete(cacheKey);
46
+ }
47
+ }
48
+ /**
49
+ * Returns the set of cache keys belonging to a specific group.
50
+ *
51
+ * @param {string} groupName - The group name.
52
+ * @returns {Set<string>} The cache keys in the group.
53
+ */
54
+ getGroupKeys(groupName) {
55
+ return this.groups.get(groupName)?.keys ?? new Set();
56
+ }
57
+ /**
58
+ * Invalidates a single group, clearing its keys and recording the timestamp.
59
+ *
60
+ * @param {string} groupName - The group name to invalidate.
61
+ * @returns {string[]} The cache keys that were in the invalidated group.
62
+ */
63
+ invalidate(groupName) {
64
+ const group = this.groups.get(groupName);
65
+ if (!group)
66
+ return [];
67
+ const keys = [...group.keys];
68
+ group.keys.clear();
69
+ group.lastInvalidated = Date.now();
70
+ return keys;
71
+ }
72
+ /**
73
+ * Invalidates all groups, clearing their keys and recording the timestamp.
74
+ *
75
+ * @returns {string[]} All unique cache keys that were invalidated.
76
+ */
77
+ invalidateAll() {
78
+ const allKeys = new Set();
79
+ for (const group of this.groups.values()) {
80
+ for (const key of group.keys) {
81
+ allKeys.add(key);
82
+ }
83
+ group.keys.clear();
84
+ group.lastInvalidated = Date.now();
85
+ }
86
+ return [...allKeys];
87
+ }
88
+ /**
89
+ * Checks whether a cache key has been invalidated since a given timestamp.
90
+ *
91
+ * @param {string} cacheKey - The cache key to check.
92
+ * @param {number} storedAt - The timestamp when the entry was stored.
93
+ * @returns {boolean} `true` if the key was invalidated after `storedAt`.
94
+ */
95
+ isInvalidatedSince(cacheKey, storedAt) {
96
+ for (const group of this.groups.values()) {
97
+ if (group.keys.has(cacheKey) && group.lastInvalidated > storedAt) {
98
+ return true;
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+ /**
104
+ * Returns the number of tracked groups.
105
+ *
106
+ * @returns {number} The group count.
107
+ */
108
+ get size() {
109
+ return this.groups.size;
110
+ }
111
+ /**
112
+ * Removes all groups and their key associations.
113
+ */
114
+ clear() {
115
+ this.groups.clear();
116
+ }
117
+ }
118
+ //# sourceMappingURL=groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.js","sourceRoot":"","sources":["../../src/cache/groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Parsed No-Vary-Search header directive (proposal spec).
3
+ */
4
+ export interface NoVarySearchDirective {
5
+ params: boolean | string[];
6
+ except: string[];
7
+ keyOrder: boolean;
8
+ }
9
+ /**
10
+ * Parses a No-Vary-Search header value into a structured directive.
11
+ *
12
+ * @param {string} header - The raw No-Vary-Search header value.
13
+ * @returns {NoVarySearchDirective|null} The parsed directive, or `null` if the header is empty.
14
+ */
15
+ export declare function parseNoVarySearch(header: string): NoVarySearchDirective | null;
16
+ /**
17
+ * Determines whether two URLs match according to a No-Vary-Search directive.
18
+ *
19
+ * @param {string} cachedUrl - The URL of the cached response.
20
+ * @param {string} requestUrl - The URL of the incoming request.
21
+ * @param {NoVarySearchDirective} directive - The No-Vary-Search directive to apply.
22
+ * @returns {boolean} `true` if the URLs are considered equivalent under the directive.
23
+ */
24
+ export declare function urlsMatchWithNoVarySearch(cachedUrl: string, requestUrl: string, directive: NoVarySearchDirective): boolean;
25
+ /**
26
+ * Normalizes a URL for cache key generation by applying No-Vary-Search filtering.
27
+ *
28
+ * @param {string} url - The URL to normalize.
29
+ * @param {NoVarySearchDirective} directive - The No-Vary-Search directive to apply.
30
+ * @returns {string} The normalized URL string.
31
+ */
32
+ export declare function normalizeUrlForCache(url: string, directive: NoVarySearchDirective): string;
33
+ //# sourceMappingURL=no-vary-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-vary-search.d.ts","sourceRoot":"","sources":["../../src/cache/no-vary-search.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CA4B9E;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAwB1H;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,GAAG,MAAM,CAiB1F"}