nlcurl 0.7.0 → 0.8.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.
- package/README.md +143 -140
- package/dist/cache/groups.d.ts +75 -0
- package/dist/cache/groups.d.ts.map +1 -0
- package/dist/cache/groups.js +118 -0
- package/dist/cache/groups.js.map +1 -0
- package/dist/cache/no-vary-search.d.ts +33 -0
- package/dist/cache/no-vary-search.d.ts.map +1 -0
- package/dist/cache/no-vary-search.js +148 -0
- package/dist/cache/no-vary-search.js.map +1 -0
- package/dist/cache/range.d.ts +120 -0
- package/dist/cache/range.d.ts.map +1 -0
- package/dist/cache/range.js +193 -0
- package/dist/cache/range.js.map +1 -0
- package/dist/cache/store.d.ts +58 -36
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +58 -46
- package/dist/cache/store.js.map +1 -1
- package/dist/cache/types.d.ts +7 -39
- package/dist/cache/types.d.ts.map +1 -1
- package/dist/cli/args.d.ts +4 -37
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/index.d.ts +0 -5
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +14 -20
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +14 -20
- package/dist/cli/output.js.map +1 -1
- package/dist/cookies/jar.d.ts +30 -39
- package/dist/cookies/jar.d.ts.map +1 -1
- package/dist/cookies/jar.js +27 -37
- package/dist/cookies/jar.js.map +1 -1
- package/dist/cookies/parser.d.ts +13 -17
- package/dist/cookies/parser.d.ts.map +1 -1
- package/dist/cookies/parser.js +17 -14
- package/dist/cookies/parser.js.map +1 -1
- package/dist/cookies/psl-data.d.ts +1 -1
- package/dist/cookies/psl-data.js +1 -1
- package/dist/cookies/public-suffix.d.ts +5 -27
- package/dist/cookies/public-suffix.d.ts.map +1 -1
- package/dist/cookies/public-suffix.js +5 -37
- package/dist/cookies/public-suffix.js.map +1 -1
- package/dist/core/auth.d.ts +30 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +34 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/client.d.ts +28 -40
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +31 -41
- package/dist/core/client.js.map +1 -1
- package/dist/core/errors.d.ts +64 -88
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +64 -88
- package/dist/core/errors.js.map +1 -1
- package/dist/core/request.d.ts +23 -111
- package/dist/core/request.d.ts.map +1 -1
- package/dist/core/response.d.ts +49 -66
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +45 -59
- package/dist/core/response.js.map +1 -1
- package/dist/core/session.d.ts +66 -78
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +105 -76
- package/dist/core/session.js.map +1 -1
- package/dist/core/validation.d.ts +44 -43
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +44 -56
- package/dist/core/validation.js.map +1 -1
- package/dist/dns/cache.d.ts +59 -0
- package/dist/dns/cache.d.ts.map +1 -0
- package/dist/dns/cache.js +99 -0
- package/dist/dns/cache.js.map +1 -0
- package/dist/dns/codec.d.ts +20 -18
- package/dist/dns/codec.d.ts.map +1 -1
- package/dist/dns/codec.js +20 -36
- package/dist/dns/codec.js.map +1 -1
- package/dist/dns/doh-resolver.d.ts +17 -31
- package/dist/dns/doh-resolver.d.ts.map +1 -1
- package/dist/dns/doh-resolver.js +46 -47
- package/dist/dns/doh-resolver.js.map +1 -1
- package/dist/dns/dot-resolver.d.ts +89 -0
- package/dist/dns/dot-resolver.d.ts.map +1 -0
- package/dist/dns/dot-resolver.js +158 -0
- package/dist/dns/dot-resolver.js.map +1 -0
- package/dist/dns/https-rr.d.ts +19 -30
- package/dist/dns/https-rr.d.ts.map +1 -1
- package/dist/dns/https-rr.js +22 -40
- package/dist/dns/https-rr.js.map +1 -1
- package/dist/dns/types.d.ts +31 -59
- package/dist/dns/types.d.ts.map +1 -1
- package/dist/dns/types.js +3 -14
- package/dist/dns/types.js.map +1 -1
- package/dist/fingerprints/akamai.d.ts +3 -11
- package/dist/fingerprints/akamai.d.ts.map +1 -1
- package/dist/fingerprints/akamai.js +3 -11
- package/dist/fingerprints/akamai.js.map +1 -1
- package/dist/fingerprints/database.d.ts +6 -14
- package/dist/fingerprints/database.d.ts.map +1 -1
- package/dist/fingerprints/database.js +6 -14
- package/dist/fingerprints/database.js.map +1 -1
- package/dist/fingerprints/extensions.d.ts +56 -71
- package/dist/fingerprints/extensions.d.ts.map +1 -1
- package/dist/fingerprints/extensions.js +58 -71
- package/dist/fingerprints/extensions.js.map +1 -1
- package/dist/fingerprints/ja3.d.ts +12 -30
- package/dist/fingerprints/ja3.d.ts.map +1 -1
- package/dist/fingerprints/ja3.js +12 -30
- package/dist/fingerprints/ja3.js.map +1 -1
- package/dist/fingerprints/ja4.d.ts +18 -0
- package/dist/fingerprints/ja4.d.ts.map +1 -0
- package/dist/fingerprints/ja4.js +83 -0
- package/dist/fingerprints/ja4.js.map +1 -0
- package/dist/fingerprints/profiles/chrome.d.ts +18 -21
- package/dist/fingerprints/profiles/chrome.d.ts.map +1 -1
- package/dist/fingerprints/profiles/chrome.js +35 -31
- package/dist/fingerprints/profiles/chrome.js.map +1 -1
- package/dist/fingerprints/profiles/edge.d.ts +7 -10
- package/dist/fingerprints/profiles/edge.d.ts.map +1 -1
- package/dist/fingerprints/profiles/edge.js +7 -10
- package/dist/fingerprints/profiles/edge.js.map +1 -1
- package/dist/fingerprints/profiles/firefox.d.ts +8 -11
- package/dist/fingerprints/profiles/firefox.d.ts.map +1 -1
- package/dist/fingerprints/profiles/firefox.js +8 -11
- package/dist/fingerprints/profiles/firefox.js.map +1 -1
- package/dist/fingerprints/profiles/safari.d.ts +11 -14
- package/dist/fingerprints/profiles/safari.d.ts.map +1 -1
- package/dist/fingerprints/profiles/safari.js +11 -14
- package/dist/fingerprints/profiles/safari.js.map +1 -1
- package/dist/fingerprints/profiles/tor.d.ts +5 -8
- package/dist/fingerprints/profiles/tor.d.ts.map +1 -1
- package/dist/fingerprints/profiles/tor.js +5 -8
- package/dist/fingerprints/profiles/tor.js.map +1 -1
- package/dist/fingerprints/types.d.ts +42 -73
- package/dist/fingerprints/types.d.ts.map +1 -1
- package/dist/hsts/store.d.ts +19 -21
- package/dist/hsts/store.d.ts.map +1 -1
- package/dist/hsts/store.js +20 -28
- package/dist/hsts/store.js.map +1 -1
- package/dist/hsts/types.d.ts +10 -14
- package/dist/hsts/types.d.ts.map +1 -1
- package/dist/http/alt-svc.d.ts +31 -49
- package/dist/http/alt-svc.d.ts.map +1 -1
- package/dist/http/alt-svc.js +21 -55
- package/dist/http/alt-svc.js.map +1 -1
- package/dist/http/early-hints.d.ts +23 -0
- package/dist/http/early-hints.d.ts.map +1 -0
- package/dist/http/early-hints.js +33 -0
- package/dist/http/early-hints.js.map +1 -0
- package/dist/http/form-data.d.ts +17 -35
- package/dist/http/form-data.d.ts.map +1 -1
- package/dist/http/form-data.js +12 -34
- package/dist/http/form-data.js.map +1 -1
- package/dist/http/h1/client.d.ts +14 -26
- package/dist/http/h1/client.d.ts.map +1 -1
- package/dist/http/h1/client.js +14 -23
- package/dist/http/h1/client.js.map +1 -1
- package/dist/http/h1/encoder.d.ts +10 -17
- package/dist/http/h1/encoder.d.ts.map +1 -1
- package/dist/http/h1/encoder.js +10 -17
- package/dist/http/h1/encoder.js.map +1 -1
- package/dist/http/h1/parser.d.ts +22 -59
- package/dist/http/h1/parser.d.ts.map +1 -1
- package/dist/http/h1/parser.js +15 -47
- package/dist/http/h1/parser.js.map +1 -1
- package/dist/http/h2/client.d.ts +18 -59
- package/dist/http/h2/client.d.ts.map +1 -1
- package/dist/http/h2/client.js +29 -64
- package/dist/http/h2/client.js.map +1 -1
- package/dist/http/h2/frames.d.ts +53 -84
- package/dist/http/h2/frames.d.ts.map +1 -1
- package/dist/http/h2/frames.js +48 -76
- package/dist/http/h2/frames.js.map +1 -1
- package/dist/http/h2/hpack.d.ts +16 -35
- package/dist/http/h2/hpack.d.ts.map +1 -1
- package/dist/http/h2/hpack.js +16 -35
- package/dist/http/h2/hpack.js.map +1 -1
- package/dist/http/h3/detection.d.ts +5 -7
- package/dist/http/h3/detection.d.ts.map +1 -1
- package/dist/http/h3/detection.js +5 -23
- package/dist/http/h3/detection.js.map +1 -1
- package/dist/http/negotiator.d.ts +25 -38
- package/dist/http/negotiator.d.ts.map +1 -1
- package/dist/http/negotiator.js +16 -28
- package/dist/http/negotiator.js.map +1 -1
- package/dist/http/pool.d.ts +32 -62
- package/dist/http/pool.d.ts.map +1 -1
- package/dist/http/pool.js +22 -41
- package/dist/http/pool.js.map +1 -1
- package/dist/http/resumable-upload.d.ts +76 -0
- package/dist/http/resumable-upload.d.ts.map +1 -0
- package/dist/http/resumable-upload.js +104 -0
- package/dist/http/resumable-upload.js.map +1 -0
- package/dist/http/trailers.d.ts +29 -0
- package/dist/http/trailers.d.ts.map +1 -0
- package/dist/http/trailers.js +57 -0
- package/dist/http/trailers.js.map +1 -0
- package/dist/index.d.ts +21 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/middleware/interceptor.d.ts +13 -32
- package/dist/middleware/interceptor.d.ts.map +1 -1
- package/dist/middleware/interceptor.js +11 -16
- package/dist/middleware/interceptor.js.map +1 -1
- package/dist/middleware/rate-limiter.d.ts +8 -17
- package/dist/middleware/rate-limiter.d.ts.map +1 -1
- package/dist/middleware/rate-limiter.js +11 -12
- package/dist/middleware/rate-limiter.js.map +1 -1
- package/dist/middleware/retry-after.d.ts +15 -0
- package/dist/middleware/retry-after.d.ts.map +1 -0
- package/dist/middleware/retry-after.js +36 -0
- package/dist/middleware/retry-after.js.map +1 -0
- package/dist/middleware/retry.d.ts +9 -18
- package/dist/middleware/retry.d.ts.map +1 -1
- package/dist/middleware/retry.js +12 -9
- package/dist/middleware/retry.js.map +1 -1
- package/dist/proxy/auth.d.ts +73 -0
- package/dist/proxy/auth.d.ts.map +1 -0
- package/dist/proxy/auth.js +128 -0
- package/dist/proxy/auth.js.map +1 -0
- package/dist/proxy/env-proxy.d.ts +5 -15
- package/dist/proxy/env-proxy.d.ts.map +1 -1
- package/dist/proxy/env-proxy.js +5 -23
- package/dist/proxy/env-proxy.js.map +1 -1
- package/dist/proxy/http-proxy.d.ts +12 -19
- package/dist/proxy/http-proxy.d.ts.map +1 -1
- package/dist/proxy/http-proxy.js +5 -8
- package/dist/proxy/http-proxy.js.map +1 -1
- package/dist/proxy/socks.d.ts +13 -20
- package/dist/proxy/socks.d.ts.map +1 -1
- package/dist/proxy/socks.js +5 -8
- package/dist/proxy/socks.js.map +1 -1
- package/dist/sse/parser.d.ts +14 -37
- package/dist/sse/parser.d.ts.map +1 -1
- package/dist/sse/parser.js +14 -28
- package/dist/sse/parser.js.map +1 -1
- package/dist/tls/constants.d.ts +15 -74
- package/dist/tls/constants.d.ts.map +1 -1
- package/dist/tls/constants.js +15 -74
- package/dist/tls/constants.js.map +1 -1
- package/dist/tls/ct.d.ts +78 -0
- package/dist/tls/ct.d.ts.map +1 -0
- package/dist/tls/ct.js +175 -0
- package/dist/tls/ct.js.map +1 -0
- package/dist/tls/early-data.d.ts +45 -0
- package/dist/tls/early-data.d.ts.map +1 -0
- package/dist/tls/early-data.js +46 -0
- package/dist/tls/early-data.js.map +1 -0
- package/dist/tls/ech.d.ts +68 -85
- package/dist/tls/ech.d.ts.map +1 -1
- package/dist/tls/ech.js +54 -102
- package/dist/tls/ech.js.map +1 -1
- package/dist/tls/keylog.d.ts +34 -0
- package/dist/tls/keylog.d.ts.map +1 -0
- package/dist/tls/keylog.js +64 -0
- package/dist/tls/keylog.js.map +1 -0
- package/dist/tls/node-engine.d.ts +10 -17
- package/dist/tls/node-engine.d.ts.map +1 -1
- package/dist/tls/node-engine.js +20 -18
- package/dist/tls/node-engine.js.map +1 -1
- package/dist/tls/ocsp.d.ts +55 -0
- package/dist/tls/ocsp.d.ts.map +1 -0
- package/dist/tls/ocsp.js +131 -0
- package/dist/tls/ocsp.js.map +1 -0
- package/dist/tls/pin-verification.d.ts +5 -4
- package/dist/tls/pin-verification.d.ts.map +1 -1
- package/dist/tls/pin-verification.js +5 -11
- package/dist/tls/pin-verification.js.map +1 -1
- package/dist/tls/session-cache.d.ts +27 -39
- package/dist/tls/session-cache.d.ts.map +1 -1
- package/dist/tls/session-cache.js +20 -24
- package/dist/tls/session-cache.js.map +1 -1
- package/dist/tls/stealth/client-hello.d.ts +25 -44
- package/dist/tls/stealth/client-hello.d.ts.map +1 -1
- package/dist/tls/stealth/client-hello.js +17 -28
- package/dist/tls/stealth/client-hello.js.map +1 -1
- package/dist/tls/stealth/engine.d.ts +5 -15
- package/dist/tls/stealth/engine.d.ts.map +1 -1
- package/dist/tls/stealth/engine.js +11 -17
- package/dist/tls/stealth/engine.js.map +1 -1
- package/dist/tls/stealth/handshake.d.ts +21 -31
- package/dist/tls/stealth/handshake.d.ts.map +1 -1
- package/dist/tls/stealth/handshake.js +15 -43
- package/dist/tls/stealth/handshake.js.map +1 -1
- package/dist/tls/stealth/key-schedule.d.ts +59 -86
- package/dist/tls/stealth/key-schedule.d.ts.map +1 -1
- package/dist/tls/stealth/key-schedule.js +46 -58
- package/dist/tls/stealth/key-schedule.js.map +1 -1
- package/dist/tls/stealth/record-layer.d.ts +52 -75
- package/dist/tls/stealth/record-layer.d.ts.map +1 -1
- package/dist/tls/stealth/record-layer.js +47 -63
- package/dist/tls/stealth/record-layer.js.map +1 -1
- package/dist/tls/stealth/tls12-handshake.d.ts +16 -0
- package/dist/tls/stealth/tls12-handshake.d.ts.map +1 -1
- package/dist/tls/stealth/tls12-handshake.js +8 -0
- package/dist/tls/stealth/tls12-handshake.js.map +1 -1
- package/dist/tls/types.d.ts +42 -60
- package/dist/tls/types.d.ts.map +1 -1
- package/dist/utils/buffer-reader.d.ts +26 -81
- package/dist/utils/buffer-reader.d.ts.map +1 -1
- package/dist/utils/buffer-reader.js +26 -81
- package/dist/utils/buffer-reader.js.map +1 -1
- package/dist/utils/buffer-writer.d.ts +30 -66
- package/dist/utils/buffer-writer.d.ts.map +1 -1
- package/dist/utils/buffer-writer.js +30 -66
- package/dist/utils/buffer-writer.js.map +1 -1
- package/dist/utils/compression.d.ts +18 -0
- package/dist/utils/compression.d.ts.map +1 -0
- package/dist/utils/compression.js +34 -0
- package/dist/utils/compression.js.map +1 -0
- package/dist/utils/dictionary-transport.d.ts +97 -0
- package/dist/utils/dictionary-transport.d.ts.map +1 -0
- package/dist/utils/dictionary-transport.js +171 -0
- package/dist/utils/dictionary-transport.js.map +1 -0
- package/dist/utils/encoding.d.ts +12 -30
- package/dist/utils/encoding.d.ts.map +1 -1
- package/dist/utils/encoding.js +15 -46
- package/dist/utils/encoding.js.map +1 -1
- package/dist/utils/happy-eyeballs.d.ts +18 -8
- package/dist/utils/happy-eyeballs.d.ts.map +1 -1
- package/dist/utils/happy-eyeballs.js +19 -27
- package/dist/utils/happy-eyeballs.js.map +1 -1
- package/dist/utils/logger.d.ts +54 -81
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +92 -64
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/tcp-fast-open.d.ts +30 -0
- package/dist/utils/tcp-fast-open.d.ts.map +1 -0
- package/dist/utils/tcp-fast-open.js +36 -0
- package/dist/utils/tcp-fast-open.js.map +1 -0
- package/dist/utils/url.d.ts +18 -25
- package/dist/utils/url.d.ts.map +1 -1
- package/dist/utils/url.js +18 -25
- package/dist/utils/url.js.map +1 -1
- package/dist/ws/client.d.ts +33 -53
- package/dist/ws/client.d.ts.map +1 -1
- package/dist/ws/client.js +29 -30
- package/dist/ws/client.js.map +1 -1
- package/dist/ws/frame.d.ts +24 -41
- package/dist/ws/frame.d.ts.map +1 -1
- package/dist/ws/frame.js +18 -33
- package/dist/ws/frame.js.map +1 -1
- package/dist/ws/permessage-deflate.d.ts +23 -28
- package/dist/ws/permessage-deflate.d.ts.map +1 -1
- package/dist/ws/permessage-deflate.js +18 -26
- package/dist/ws/permessage-deflate.js.map +1 -1
- package/package.json +62 -62
package/README.md
CHANGED
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
# NLcURL
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
NLcURL provides
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- HTTP/1.1
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- `
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
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
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **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.
|
|
10
|
+
- **Custom Stealth TLS Engine** — A from-scratch TLS 1.2/1.3 implementation with GREASE injection (RFC 8701), configurable cipher suites, extension ordering, and Encrypted Client Hello (ECH) support.
|
|
11
|
+
- **HTTP/1.1 & HTTP/2** — Full HTTP/1.1 with chunked transfer encoding and HTTP/2 with HPACK compression, stream multiplexing, and configurable flow control.
|
|
12
|
+
- **Connection Pooling** — Per-origin connection reuse with idle eviction, configurable pool limits, and automatic HTTP/2 multiplexing.
|
|
13
|
+
- **RFC 6265 Cookie Jar** — Persistent cookie storage with Public Suffix List validation, `__Host-`/`__Secure-` prefix enforcement, `SameSite` defaults, and Netscape file format import/export.
|
|
14
|
+
- **HTTP Caching (RFC 9111)** — In-memory cache with `max-age`, `ETag`/`Last-Modified` conditional revalidation, `stale-while-revalidate`, heuristic freshness, and five cache modes.
|
|
15
|
+
- **HSTS (RFC 6797)** — Automatic `http://` to `https://` upgrading with `includeSubDomains` support and configurable preload lists.
|
|
16
|
+
- **DNS-over-HTTPS (RFC 8484)** — Wire-format DoH with GET/POST methods, bootstrap resolution, and integrated DNS caching.
|
|
17
|
+
- **DNS-over-TLS (RFC 7858)** — Secure DNS resolution over TLS port 853 with persistent connection support and pre-configured public resolvers.
|
|
18
|
+
- **HTTPS Resource Records (RFC 9460)** — SVCB/HTTPS DNS record resolution for ALPN hints, ECH config delivery, and address hints.
|
|
19
|
+
- **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`).
|
|
20
|
+
- **WebSocket (RFC 6455)** — Full WebSocket client with TLS fingerprinting, per-message deflate compression (RFC 7692), ping/pong, and binary/text framing.
|
|
21
|
+
- **Server-Sent Events** — W3C EventSource-compliant SSE parser with streaming async generator interface.
|
|
22
|
+
- **Request/Response Interceptors** — Middleware pipeline for modifying requests before send and responses after receipt.
|
|
23
|
+
- **Retry with Backoff** — Configurable automatic retry with linear or exponential backoff, jitter, `Retry-After` header respect, and custom retry predicates.
|
|
24
|
+
- **Rate Limiting** — Token-bucket rate limiter with configurable request quotas and automatic queuing.
|
|
25
|
+
- **Request Body Compression** — Outgoing body compression with gzip, deflate, and Brotli.
|
|
26
|
+
- **Response Decompression** — Automatic decompression of gzip, deflate, Brotli, and zstd (Node.js 20.10+) with multi-layer encoding support.
|
|
27
|
+
- **Happy Eyeballs v2 (RFC 8305)** — Dual-stack connection racing with 250ms stagger for optimal latency.
|
|
28
|
+
- **Alt-Svc (RFC 7838)** — HTTP Alternative Services tracking with automatic protocol upgrade preference.
|
|
29
|
+
- **FormData (RFC 7578)** — Multipart form-data encoding with file upload support.
|
|
30
|
+
- **Authentication** — Built-in Basic and Bearer authentication, plus Digest proxy authentication (RFC 7616).
|
|
31
|
+
- **Progress Callbacks** — Upload and download progress events with byte counts and percentages.
|
|
32
|
+
- **Structured Logging** — Console and JSON logger implementations with child logger support and configurable log levels.
|
|
33
|
+
- **CLI Tool** — `nlcurl` command-line interface with curl-compatible flags for scripting and interactive use.
|
|
34
|
+
- **Zero Dependencies** — Pure TypeScript with no runtime dependencies. Requires only Node.js ≥ 18.17.0.
|
|
29
35
|
|
|
30
36
|
## Installation
|
|
31
37
|
|
|
@@ -33,155 +39,152 @@ NLcURL provides session-based and one-shot HTTP APIs, browser profile impersonat
|
|
|
33
39
|
npm install nlcurl
|
|
34
40
|
```
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
npm install
|
|
40
|
-
npm run build
|
|
41
|
-
```
|
|
42
|
+
**Requirements:** Node.js ≥ 18.17.0
|
|
42
43
|
|
|
43
44
|
## Quick Start
|
|
44
45
|
|
|
45
|
-
### One-
|
|
46
|
+
### One-Shot Requests
|
|
46
47
|
|
|
47
|
-
```
|
|
48
|
-
import {
|
|
48
|
+
```typescript
|
|
49
|
+
import { get, post } from "nlcurl";
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
// Simple GET
|
|
52
|
+
const response = await get("https://httpbin.org/get");
|
|
53
|
+
console.log(response.status); // 200
|
|
54
|
+
console.log(response.json()); // parsed JSON body
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
// POST with JSON body
|
|
57
|
+
const res = await post("https://httpbin.org/post", { key: "value" });
|
|
58
|
+
console.log(res.text());
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
###
|
|
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
|
-
```
|
|
61
|
+
### Browser Impersonation
|
|
71
62
|
|
|
72
|
-
|
|
63
|
+
```typescript
|
|
64
|
+
import { get } from "nlcurl";
|
|
73
65
|
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
},
|
|
66
|
+
const response = await get("https://example.com", {
|
|
67
|
+
impersonate: "chrome136",
|
|
84
68
|
});
|
|
85
69
|
```
|
|
86
70
|
|
|
87
|
-
### Session
|
|
71
|
+
### Session with Connection Reuse
|
|
88
72
|
|
|
89
|
-
```
|
|
73
|
+
```typescript
|
|
90
74
|
import { createSession } from "nlcurl";
|
|
91
75
|
|
|
92
76
|
const session = createSession({
|
|
93
|
-
baseURL: "https://
|
|
94
|
-
impersonate: "
|
|
95
|
-
|
|
77
|
+
baseURL: "https://api.example.com",
|
|
78
|
+
impersonate: "chrome136",
|
|
79
|
+
headers: { "authorization": "Bearer token" },
|
|
80
|
+
retry: { count: 3, backoff: "exponential" },
|
|
96
81
|
});
|
|
97
82
|
|
|
98
|
-
const
|
|
99
|
-
|
|
83
|
+
const users = await session.get("/users");
|
|
84
|
+
const user = await session.post("/users", { name: "Alice" });
|
|
100
85
|
|
|
101
86
|
session.close();
|
|
102
87
|
```
|
|
103
88
|
|
|
104
|
-
###
|
|
89
|
+
### Stealth TLS
|
|
105
90
|
|
|
106
|
-
```
|
|
107
|
-
|
|
91
|
+
```typescript
|
|
92
|
+
import { get } from "nlcurl";
|
|
93
|
+
|
|
94
|
+
// Uses the custom stealth TLS engine (bypasses Node.js TLS)
|
|
95
|
+
const response = await get("https://example.com", {
|
|
96
|
+
stealth: true,
|
|
97
|
+
impersonate: "chrome136",
|
|
98
|
+
});
|
|
108
99
|
```
|
|
109
100
|
|
|
110
|
-
|
|
101
|
+
### WebSocket
|
|
111
102
|
|
|
112
|
-
```
|
|
113
|
-
|
|
103
|
+
```typescript
|
|
104
|
+
import { WebSocketClient } from "nlcurl";
|
|
105
|
+
|
|
106
|
+
const ws = new WebSocketClient("wss://echo.websocket.events", {
|
|
107
|
+
impersonate: "chrome136",
|
|
108
|
+
compress: true,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
ws.on("open", () => ws.sendText("Hello"));
|
|
112
|
+
ws.on("message", (data) => console.log(data));
|
|
113
|
+
ws.on("close", (code, reason) => console.log("Closed:", code));
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
|
|
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
|
|
116
|
+
### CLI
|
|
161
117
|
|
|
162
118
|
```bash
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
npm run test
|
|
166
|
-
npm run test:integration
|
|
167
|
-
npm run build
|
|
168
|
-
```
|
|
119
|
+
# Simple GET
|
|
120
|
+
nlcurl https://httpbin.org/get
|
|
169
121
|
|
|
170
|
-
|
|
122
|
+
# Impersonate Chrome with verbose output
|
|
123
|
+
nlcurl -v --impersonate chrome136 https://example.com
|
|
171
124
|
|
|
172
|
-
|
|
173
|
-
-
|
|
125
|
+
# POST with data
|
|
126
|
+
nlcurl -X POST -d '{"key":"value"}' -H "Content-Type: application/json" https://httpbin.org/post
|
|
174
127
|
|
|
175
|
-
|
|
128
|
+
# Through a proxy
|
|
129
|
+
nlcurl -x socks5://127.0.0.1:1080 https://example.com
|
|
130
|
+
```
|
|
176
131
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
132
|
+
## Documentation
|
|
133
|
+
|
|
134
|
+
| Document | Description |
|
|
135
|
+
|----------|-------------|
|
|
136
|
+
| [API Reference](docs/API.md) | Complete API for all exported classes, functions, types, and interfaces |
|
|
137
|
+
| [Configuration](docs/CONFIGURATION.md) | All configuration options for requests, sessions, TLS, DNS, caching, and proxies |
|
|
138
|
+
| [Examples](docs/EXAMPLES.md) | Practical usage patterns covering common and advanced scenarios |
|
|
139
|
+
| [Modules](docs/MODULES.md) | Architecture overview and detailed breakdown of every module |
|
|
140
|
+
| [Onboarding](docs/ONBOARDING.md) | Getting started guide for new contributors and integrators |
|
|
141
|
+
| [Setup](docs/SETUP.md) | Build, test, and development environment instructions |
|
|
142
|
+
|
|
143
|
+
## Browser Profiles
|
|
144
|
+
|
|
145
|
+
49 resolvable browser profile names across 5 browser families:
|
|
146
|
+
|
|
147
|
+
| Browser | Profiles |
|
|
148
|
+
|---------|----------|
|
|
149
|
+
| Chrome | `chrome99` through `chrome136`, `chrome_latest`, `chrome` |
|
|
150
|
+
| Firefox | `firefox133` through `firefox138`, `firefox_latest`, `firefox` |
|
|
151
|
+
| Safari | `safari153` through `safari182`, `safari_latest`, `safari` |
|
|
152
|
+
| Edge | `edge99` through `edge136`, `edge_latest`, `edge` |
|
|
153
|
+
| Tor | `tor133` through `tor145`, `tor_latest`, `tor` |
|
|
154
|
+
|
|
155
|
+
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.
|
|
156
|
+
|
|
157
|
+
## Standards Compliance
|
|
158
|
+
|
|
159
|
+
NLcURL implements or references the following RFCs and standards:
|
|
160
|
+
|
|
161
|
+
| Standard | Coverage |
|
|
162
|
+
|----------|----------|
|
|
163
|
+
| RFC 8446 | TLS 1.3 — full handshake, key schedule, AEAD record encryption |
|
|
164
|
+
| RFC 5246 | TLS 1.2 — ECDHE key exchange, GCM/ChaCha20 cipher suites |
|
|
165
|
+
| RFC 8701 | GREASE — randomized TLS extension values for anti-fingerprinting |
|
|
166
|
+
| RFC 9113 | HTTP/2 — frames, HPACK, flow control, GOAWAY, stream multiplexing |
|
|
167
|
+
| RFC 7541 | HPACK — header compression with Huffman encoding |
|
|
168
|
+
| RFC 9112 | HTTP/1.1 — message syntax, chunked transfer encoding |
|
|
169
|
+
| RFC 9111 | HTTP Caching — freshness, conditional requests, cache modes |
|
|
170
|
+
| RFC 9110 | HTTP Semantics — methods, status codes, range requests |
|
|
171
|
+
| RFC 6265 | HTTP Cookies — Set-Cookie parsing, domain/path scoping, prefixes |
|
|
172
|
+
| RFC 6797 | HSTS — Strict-Transport-Security header processing |
|
|
173
|
+
| RFC 8484 | DNS-over-HTTPS — wire-format queries, GET/POST methods |
|
|
174
|
+
| RFC 7858 | DNS-over-TLS — encrypted DNS over port 853 |
|
|
175
|
+
| RFC 9460 | SVCB/HTTPS DNS Records — service binding, ALPN, ECH delivery |
|
|
176
|
+
| RFC 8305 | Happy Eyeballs v2 — dual-stack connection racing |
|
|
177
|
+
| RFC 6455 | WebSocket — upgrade handshake, framing, close protocol |
|
|
178
|
+
| RFC 7692 | WebSocket Compression — permessage-deflate negotiation |
|
|
179
|
+
| RFC 7838 | HTTP Alt-Svc — alternative service advertisement |
|
|
180
|
+
| RFC 7578 | Multipart Form Data — multipart/form-data encoding |
|
|
181
|
+
| RFC 7616 | HTTP Digest Authentication — MD5/SHA-256, qop=auth |
|
|
182
|
+
| RFC 1928 | SOCKS5 — proxy protocol with auth negotiation |
|
|
183
|
+
| RFC 5869 | HKDF — key derivation for TLS key schedule |
|
|
184
|
+
| RFC 9180 | HPKE — Hybrid Public Key Encryption for ECH |
|
|
185
|
+
| RFC 7413 | TCP Fast Open — platform-aware TFO support |
|
|
186
|
+
| RFC 8297 | 103 Early Hints — Link header parsing |
|
|
184
187
|
|
|
185
188
|
## License
|
|
186
189
|
|
|
187
|
-
MIT
|
|
190
|
+
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"}
|