ranux-fetcher 1.0.0 → 1.0.2

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 CHANGED
@@ -3,10 +3,10 @@
3
3
  # 🌐 ranux-fetcher
4
4
 
5
5
  <a href="https://ransara-devnath.vercel.app/">
6
- <img src="https://readme-typing-svg.demolab.com?font=Fira+Code&weight=600&size=24&pause=1000&color=00F0FF&center=true&vCenter=true&width=800&lines=The+Ultimate+Anti-Bot+HTTP+Client;Smart+Proxy+Pool+%26+Edge+Cluster+Fallback;Drop-in+Replacement+for+Axios+%26+Got-Scraping;Zero-Native+Binaries.+100%25+Pure+JS" alt="Typing SVG" />
6
+ <img src="https://readme-typing-svg.demolab.com?font=Fira+Code&weight=600&size=24&pause=1000&color=00F0FF&center=true&vCenter=true&width=800&lines=The+Ultimate+Anti-Bot+HTTP+Client;Smart+Proxy+Pool+%26+Edge+Cluster+Fallback;100%25+Axios+Drop-in+Replacement+for+Bots;Zero-Disk+I/O+Streams.+Pure+Memory-Safe+JS" alt="Typing SVG" />
7
7
  </a>
8
8
 
9
- **Universal Advanced HTTP & Scraping Client. Unblockable, Memory-Safe, and blazing fast.**
9
+ **Universal Advanced HTTP & Scraping Client. Unblockable, Memory-Safe, and Blazing Fast.**
10
10
 
11
11
  [![NPM Version](https://img.shields.io/npm/v/ranux-fetcher?style=for-the-badge&color=00F0FF&logo=npm)](https://www.npmjs.com/package/ranux-fetcher)
12
12
  [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D_20_LTS-339933?style=for-the-badge&logo=nodedotjs)](https://nodejs.org/)
@@ -24,28 +24,28 @@
24
24
 
25
25
  ---
26
26
 
27
- ## ⚡ Why `ranux-fetcher`?
27
+ ## ⚡ Why `ranux-fetcher`? (v1.0.1 Enterprise Edition)
28
28
 
29
- `ranux-fetcher` is the most powerful drop-in replacement for Axios and the deprecated `got-scraping`. It combines the stealth of modern browser fingerprinting with an unbreakable **Smart Proxy Pool** and a **4-Node Stealth Edge Network Fallback**, ensuring your requests never fail.
29
+ `ranux-fetcher` is the most powerful **drop-in replacement for Axios** and the deprecated `got-scraping`. Built specifically for **High-Performance WhatsApp Bots (Baileys)** and heavy scraping infrastructure, it ensures your requests never fail and your RAM never crashes.
30
30
 
31
- * 🛡️ **99.9% WAF Bypass Rate:** Native support to bypass Turnstile, DataDome, Akamai, and IP blocks.
32
- * ☁️ **Stealth Edge Cluster:** If your local IP or Custom Proxies fail, requests are automatically seamlessly relayed through our highly anonymous 4-Node Edge Network.
33
- * 📦 **Zero-Native Dependencies:** 100% Pure JS. Runs flawlessly on Termux, Next.js, Serverless, and Docker without `node-gyp` crashes.
34
- * 🧠 **Smart Context Injection:** Automatically injects perfect `Sec-Fetch-*`, `Origin`, and `Referer` headers mimicking real human browser navigation.
35
- * 💾 **OOM-Safe Media Streams:** Download 1GB+ files smoothly via native streams without crashing your server RAM (Perfect for WhatsApp Bots & YTDL clones).
31
+ * 🛡️ **99.9% WAF Bypass Rate:** Native JA4H HTTP/2 HPACK sorting and Kyber768 TLS Spoofing to flawlessly bypass Turnstile, DataDome, and Akamai.
32
+ * 🤖 **100% Axios Bot-Parity:** Zero-rewrite needed! Fully supports `error.response.status`, `res.data`, and interceptors exactly like Axios.
33
+ * ☁️ **Smart Edge Cluster & Routing:** Failsafe 4-Node Edge Network for APIs, but automatically switches to **Direct Local Engine** for large media streams (Avoids Cloudflare 524 timeouts & 100MB payload limits).
34
+ * 💾 **Zero-Disk I/O Streaming:** Perfectly optimized for WhatsApp Bots. Stream GBs of Movies/Games directly to WhatsApp natively without eating a single megabyte of Server RAM.
35
+ * 🧠 **Memory-Leak Free:** Powered by `QuickLRU` Session Caching and Safe Interceptor Garbage Collection. Designed to run 24/7 on low-RAM VPS environments without crashing.
36
36
 
37
37
  ---
38
38
 
39
39
  ## 📊 Ultimate Comparison
40
40
 
41
- | Feature | `axios` | `got-scraping` (EOL) | **`ranux-fetcher`** 👑 |
41
+ | Feature | `axios` | `got-scraping` | **`ranux-fetcher`** 👑 |
42
42
  | :--- | :---: | :---: | :---: |
43
- | **RAM Usage** | ~30MB | ~40MB (Spikes) | **~25MB - 35MB ⚡** |
44
- | **WAF Bypass Rate** | 10% ❌ | 70% ⚠️ | **99.9% 🛡️ (Edge Proxy)** |
45
- | **Axios Drop-in API & Interceptors** | ✅ | ❌ | **✅ Built-in** |
43
+ | **Server RAM Usage (Bots)** | ~30MB | ~40MB (Spikes) | **~20MB (Zero-Disk) ⚡** |
44
+ | **WAF / Cloudflare Bypass** | 10% ❌ | 70% ⚠️ | **99.9% 🛡️ (Edge + JA4)** |
45
+ | **Axios Drop-in API & Errors**| ✅ | ❌ | **✅ Built-in** |
46
46
  | **Cheerio HTML Parser Built-in**| ❌ | ❌ | **✅ (`res.$()`)** |
47
- | **Smart Proxy Pool Rotation**| ❌ | ❌ | **✅ (`proxyList: []`)** |
48
- | **TLS & HTTP/2 Auto Spoofing**| ❌ | | **✅ Real Browser JA3/JA4** |
47
+ | **Smart Proxy Auto-Rotation**| ❌ | ❌ | **✅ (`proxyList: []`)** |
48
+ | **Large Media Auto-Routing**| ❌ | | **✅ Smart Bypass** |
49
49
 
50
50
  ---
51
51
 
@@ -59,45 +59,57 @@ npm install ranux-fetcher
59
59
 
60
60
  ## 💡 Real-World Examples
61
61
 
62
- ### 1. Basic Axios-Style Request (JSON)
62
+ ### 1. WhatsApp Bot Zero-Disk Streaming (Baileys/WAWeb.js)
63
+ Perfect for downloading 2GB+ Movies or FitGirl Repacks directly to WhatsApp without downloading to your server disk.
63
64
  ```javascript
64
65
  import ranux from 'ranux-fetcher';
65
66
 
66
- const response = await ranux.get('https://dummyjson.com/products/1');
67
- console.log(response.data); // Eagerly loaded JSON response
67
+ // Fetch stream flawlessly (Bypasses Cloudflare Worker Timeouts automatically)
68
+ const res = await ranux.get('https://example.com/large-movie-2gb.mp4', {
69
+ responseType: 'stream',
70
+ headers: { 'Referer': 'https://sinhalasub.lk/' } // Native header casting supported
71
+ });
72
+
73
+ // Pass directly to Baileys. No RAM spikes! 🚀
74
+ await sock.sendMessage(jid, {
75
+ document: { stream: res.data }, // res.data acts exactly like Axios native streams
76
+ mimetype: 'video/mp4',
77
+ fileName: 'Movie.mp4'
78
+ });
68
79
  ```
69
80
 
70
- ### 2. Instant HTML Web Scraping (Cheerio Built-in)
71
- No need to manually import Cheerio. It is built right into the response object!
81
+ ### 2. 100% Axios-Compatible Error Handling
82
+ If you are migrating a bot from Axios, your existing error handling logic will work out of the box without throwing `undefined` errors.
72
83
  ```javascript
73
84
  import ranux from 'ranux-fetcher';
74
85
 
75
- const res = await ranux.get('https://news.ycombinator.com/');
76
-
77
- // Execute the parser only when needed
78
- const $ = res.$();
79
- console.log($('.titleline > a').first().text());
86
+ try {
87
+ const response = await ranux.get('https://dummyjson.com/auth/me');
88
+ } catch (error) {
89
+ if (error.response) {
90
+ // Fully parity with Axios
91
+ console.log("Status Code:", error.response.status);
92
+ console.log("Response Data:", error.response.data);
93
+ } else {
94
+ console.log("Network/Timeout Error:", error.message);
95
+ }
96
+ }
80
97
  ```
81
98
 
82
- ### 3. Safe Media Downloading & Progress Tracking
83
- Perfect for WhatsApp Bots running on low-RAM VPS servers. Track downloads in real-time!
99
+ ### 3. Instant HTML Web Scraping (Cheerio Built-in)
100
+ No need to manually import Cheerio or use `.text()`. It is built right into the response object!
84
101
  ```javascript
85
102
  import ranux from 'ranux-fetcher';
86
- import fs from 'fs';
87
103
 
88
- const res = await ranux.get('https://example.com/large-video.mp4', {
89
- responseType: 'stream',
90
- onDownloadProgress: (progress) => {
91
- console.log(`Downloading: ${Math.round(progress.percent * 100)}%`);
92
- }
93
- });
104
+ const res = await ranux.get('https://news.ycombinator.com/', { responseType: 'cheerio' });
94
105
 
95
- // Pipe to file without filling up your RAM
96
- res.stream.pipe(fs.createWriteStream('./video.mp4'));
106
+ // Execute the parser instantly
107
+ const $ = res.$();
108
+ console.log($('.titleline > a').first().text());
97
109
  ```
98
110
 
99
- ### 4. Smart Proxy Pool Rotation & Edge Fallback (Advanced Bypassing)
100
- Rotate through your proxies. If they all fail, `ranux-fetcher` automatically falls back to its internal Stealth Edge Network.
111
+ ### 4. Smart Proxy Pool Rotation & Edge Fallback
112
+ Rotate through your proxies. If they fail or get blocked by a WAF, `ranux-fetcher` automatically relays the request through its internal highly anonymous Stealth Edge Network.
101
113
  ```javascript
102
114
  import ranux from 'ranux-fetcher';
103
115
 
@@ -107,12 +119,13 @@ const res = await ranux.get('https://highly-protected-site.com/api/data', {
107
119
  'http://user:pass@proxy2.com:8080'
108
120
  ],
109
121
  relayMode: 'auto', // Falls back to Edge Nodes ONLY if proxies fail
110
- cookies: "auth_session=12345; user_pref=dark" // Inject raw cookies easily
122
+ cookies: "auth_session=12345; user_pref=dark" // Inject raw cookies safely
111
123
  });
124
+ console.log(res.data);
112
125
  ```
113
126
 
114
- ### 5. Axios-Style Interceptors
115
- Modify requests before they leave or responses before they arrive, exactly like Axios!
127
+ ### 5. Axios-Style Interceptors & Request Transformers
128
+ Modify requests before they leave or responses before they arrive, exactly like Axios. Safely garbage collected to prevent memory leaks.
116
129
  ```javascript
117
130
  import ranux from 'ranux-fetcher';
118
131
 
@@ -131,9 +144,10 @@ const res = await ranux.get('https://api.example.com/profile');
131
144
 
132
145
  `ranux-fetcher` includes invisible enterprise-grade protections out of the box:
133
146
 
134
- * 🎯 **Auto Smart-Referer Injection:** Our engine automatically parses your target URLs and injects perfect context headers (`Sec-Fetch-Dest`, `Sec-Fetch-Mode`, `Referer`). CDNs and WAFs see your request as a real user navigating via a browser.
135
- * 🔄 **Consistent TLS Persistence:** From the first handshake to the end of a 2GB stream download, the HTTP/2 frames and JA3/JA4 TLS Ciphers are locked to match real Google Chrome/Firefox signatures. Connection resets are a thing of the past.
136
- * 🤖 **Smart Error Masking:** If a requested payload is too large for the Edge Network to buffer, the engine intercepts the internal crash, suppresses it, and returns the original `403 Forbidden` error alongside a smart hint (`💡 Hint: The requested file seems too large... try with stream mode`). Your app stays perfectly stable, and the Edge infrastructure remains invisible.
147
+ * 🎯 **Smart Download Routing:** If `responseType: 'stream'` is requested, the engine intelligently avoids the Edge Network to prevent Cloudflare `Error 524` timeouts and Payload Limits, forcing a direct ultra-fast local connection.
148
+ * 🔄 **JA4H HTTP/2 HPACK Sequencing:** True detection of negotiated ALPN protocols. In HTTP/1.1 it uses `PascalCase` headers, but in HTTP/2 it switches to strict HPACK `lowercase` sorting to perfectly spoof Chrome 151.
149
+ * 🛡️ **Stealth-Killer Guard:** Passing a custom `httpsAgent` will not override the TLS spoofing engine. Your custom agent is automatically wrapped in our `TransformHeadersAgent` to preserve the fingerprint.
150
+ * 🧠 **Zstd Race-Condition Safe:** Asynchronously loads modern `@napi-rs/zstd` compression safely on startup without crashing the first incoming request.
137
151
 
138
152
  ---
139
153
 
@@ -145,8 +159,9 @@ import ranux from 'ranux-fetcher';
145
159
 
146
160
  const apiClient = ranux.create({
147
161
  baseURL: 'https://api.example.com',
148
- timeout: 15000,
149
- relayMode: 'always' // Always use Edge Network to completely mask your Server IP
162
+ timeout: 30000,
163
+ relayMode: 'never', // Always use direct engine
164
+ smartRetry: true // Exponential backoff on 429/503 errors
150
165
  });
151
166
 
152
167
  const res = await apiClient.get('/users/1');
@@ -159,4 +174,4 @@ console.log(res.data);
159
174
 
160
175
  This project is licensed under the **MIT License**.
161
176
 
162
- Designed and maintained by **<a href="https://ransara-devnath.vercel.app/" target="_blank">Ransara Devnath</a>**.
177
+ Designed and engineered by **<a href="https://ransara-devnath.vercel.app/" target="_blank">Ransara Devnath</a>**.
package/dist/index.d.ts CHANGED
@@ -9,15 +9,22 @@ import * as cheerio from 'cheerio';
9
9
 
10
10
  interface Context {
11
11
  proxyUrl?: string;
12
+ proxyList?: string[];
13
+ stealth?: boolean;
14
+ browser?: string;
15
+ os?: string;
16
+ zstd?: boolean;
17
+ smartRetry?: boolean;
12
18
  headerGeneratorOptions?: Record<string, unknown>;
13
19
  useHeaderGenerator?: boolean;
14
20
  headerGenerator?: {
15
21
  getHeaders: (options: Record<string, unknown>) => Record<string, string>;
16
22
  };
17
23
  insecureHTTPParser?: boolean;
18
- sessionToken?: object;
24
+ sessionToken?: string | object;
25
+ cookieJar?: boolean | any;
19
26
  /** @private */
20
- sessionData?: unknown;
27
+ sessionData?: any;
21
28
  /** @private */
22
29
  resolveProtocol?: (data: unknown) => {
23
30
  alpnProtocol: string;
@@ -158,12 +165,7 @@ declare class WrappedAgent<T extends Agent> implements Agent {
158
165
  }
159
166
 
160
167
  declare class TransformHeadersAgent<T extends Agent> extends WrappedAgent<T> {
161
- /**
162
- * Transforms the request via header normalization.
163
- */
164
- transformRequest(request: ClientRequest, { sortHeaders }: {
165
- sortHeaders: boolean;
166
- }): void;
168
+ transformRequest(request: ClientRequest, isHttp2?: boolean): void;
167
169
  addRequest(request: ClientRequest, options: ClientRequestArgs): void;
168
170
  toPascalCase(header: string): string;
169
171
  }
@@ -199,11 +201,21 @@ interface RanuxRequestConfig {
199
201
  request?: number;
200
202
  connect?: number;
201
203
  };
202
- responseType?: 'stream' | 'json' | 'text' | 'buffer';
204
+ responseType?: 'stream' | 'json' | 'text' | 'buffer' | 'arraybuffer' | 'cheerio';
203
205
  signal?: AbortSignal;
204
206
  relayMode?: 'auto' | 'always' | 'never';
205
207
  baseURL?: string;
206
208
  prefixUrl?: string;
209
+ /** Master switch to enable 2026 JA4, Kyber768 TLS, HTTP/2 Frames, and Zstd masking */
210
+ stealth?: boolean;
211
+ /** Specific 2026 Browser Profile to emulate */
212
+ browser?: 'chrome' | 'brave' | 'edge' | 'arc' | 'opera' | 'firefox' | 'safari' | 'samsung' | 'random';
213
+ /** Specific OS Profile to emulate */
214
+ os?: 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'random';
215
+ /** Enable Zstandard (zstd) decompression to mimic modern edge requests */
216
+ zstd?: boolean;
217
+ /** Auto-retry on 503, 429, or Proxy failures with exponential backoff */
218
+ smartRetry?: boolean;
207
219
  /** Array of Proxy URLs for Smart Auto-Rotation (e.g., ['http://p1', 'http://p2']) */
208
220
  proxyList?: string[];
209
221
  /** Download progress event handler */
@@ -222,16 +234,16 @@ interface RanuxRequestConfig {
222
234
  transformResponse?: ((data: any, headers: Record<string, any>) => any) | ((data: any, headers: Record<string, any>) => any)[];
223
235
  /** Single Proxy URL fallback */
224
236
  proxyUrl?: string;
225
- /** Unique object to maintain session persistence (reusing cookies, TLS sessions) */
226
- sessionToken?: object;
237
+ /** Unique string or object to maintain session persistence (reusing cookies, TLS sessions) */
238
+ sessionToken?: string | object;
239
+ /** Auto-manage cookies across redirects and requests like a real browser */
240
+ cookieJar?: boolean | any;
227
241
  /** Options to customize the browser header generation (e.g., browser type, OS) */
228
242
  headerGeneratorOptions?: Record<string, any>;
229
243
  /** Enable or disable automatic browser header injection */
230
244
  useHeaderGenerator?: boolean;
231
245
  /** Allow parsing of insecure or malformed HTTP responses */
232
246
  insecureHTTPParser?: boolean;
233
- /** Tough-Cookie jar instance for session/cookie persistence */
234
- cookieJar?: any;
235
247
  /** Enable HTTP/2 multiplexing (default: true) */
236
248
  http2?: boolean;
237
249
  /** Custom HTTPS settings (e.g., rejectUnauthorized) */
@@ -247,8 +259,8 @@ interface RanuxRequestConfig {
247
259
  * Bridges the gap between Native Streams, Axios eager-loading, and Cheerio parsing.
248
260
  */
249
261
  interface RanuxResponse<T = any> {
250
- data: T;
251
- body: T;
262
+ data: T | Readable;
263
+ body: T | Readable;
252
264
  status: number;
253
265
  statusCode: number;
254
266
  headers: Record<string, string | string[] | undefined>;
@@ -262,39 +274,47 @@ interface RanuxResponse<T = any> {
262
274
  /**
263
275
  * Custom Error class for Ranux Fetch.
264
276
  * Preserves WAF HTTP status codes, error codes, original request configuration, and smart hints.
277
+ * Fully compatible with Axios error handling paradigms (error.response).
265
278
  */
266
279
  declare class RanuxError extends Error {
267
280
  status?: number;
268
281
  code?: string;
269
282
  config?: RanuxRequestConfig;
270
283
  hint?: string;
271
- constructor(message: string, status?: number, code?: string, config?: RanuxRequestConfig, hint?: string);
284
+ response?: {
285
+ status: number;
286
+ data: any;
287
+ headers: Record<string, any>;
288
+ };
289
+ constructor(message: string, status?: number, code?: string, config?: RanuxRequestConfig, hint?: string, responseData?: any, responseHeaders?: Record<string, any>);
272
290
  }
273
291
 
274
292
  declare const gotScraping: GotScraping;
275
293
  declare const hooks: {
276
294
  init: (typeof optionsValidationHandler | typeof customOptionsHook)[];
277
295
  beforeRequest: (typeof insecureParserHook)[];
278
- beforeRedirect: ((options: Options, response: got.Response) => void)[];
296
+ beforeRedirect: ((options: got.Options, response: got.Response) => void)[];
279
297
  fixDecompress: any;
280
298
  insecureParserHook: typeof insecureParserHook;
281
- sessionDataHook: (options: Options) => void;
299
+ sessionDataHook: (options: got.Options) => void;
282
300
  http2Hook: typeof http2Hook;
283
301
  proxyHook: typeof proxyHook;
284
302
  browserHeadersHook: typeof browserHeadersHook;
285
303
  tlsHook: typeof tlsHook;
286
304
  optionsValidationHandler: typeof optionsValidationHandler;
287
305
  customOptionsHook: typeof customOptionsHook;
288
- refererHook: (options: Options, response: got.Response) => void;
306
+ refererHook: (options: got.Options, response: got.Response) => void;
289
307
  };
290
308
  declare class InterceptorManager<V> implements RanuxInterceptorManager<V> {
291
- handlers: Array<{
292
- fulfilled?: ((value: V) => V | Promise<V>) | null;
293
- rejected?: ((error: any) => any) | null;
294
- }>;
309
+ private handlers;
310
+ private idCounter;
295
311
  use(fulfilled?: ((value: V) => V | Promise<V>) | null, rejected?: ((error: any) => any) | null): number;
296
312
  eject(id: number): void;
297
313
  clear(): void;
314
+ forEach(fn: (interceptor: {
315
+ fulfilled?: ((value: V) => V | Promise<V>) | null;
316
+ rejected?: ((error: any) => any) | null;
317
+ }) => void): void;
298
318
  }
299
319
  declare const ranux: ((url: string, config?: RanuxRequestConfig) => Promise<any>) & {
300
320
  get: (url: string, config?: RanuxRequestConfig) => Promise<any>;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import {got as got$1,Options}from'got';export*from'got';import H,{OutgoingMessage}from'http';import oe from'https';import {HeaderGenerator}from'header-generator';import A from'zlib';import {PassThrough,Readable}from'stream';import Ce from'mimic-response';import x from'ow';import it,{createHash}from'crypto';import {isIPv6}from'net';import ve from'tls';import {URL as URL$1}from'url';import ae from'http2-wrapper';import ue from'quick-lru';import Ve from'process';import*as pe from'cheerio';var Ee=(r,e)=>{let t=r.headers["content-encoding"]?.toLowerCase(),s={flush:A.constants.Z_SYNC_FLUSH,finishFlush:A.constants.Z_SYNC_FLUSH},o=n=>{delete r.headers["content-encoding"];let a=new PassThrough({autoDestroy:false,destroy(i,c){r.destroy(),c(i);}});n.once("error",i=>{a.destroy(i);}),r.pipe(n).pipe(a),e(Ce(r,a));};if(t==="gzip"||t==="x-gzip")o(A.createGunzip(s));else if(t==="deflate"||t==="x-deflate"){let n=false;r.once("data",a=>{n=true,r.unshift(a);let i=(a[0]&15)===8?A.createInflate():A.createInflateRaw();o(i);}),r.once("end",()=>{n||e(r);});}else if(t==="br"){let n=false;r.once("data",a=>{n=true,r.unshift(a);let i=A.createBrotliDecompress();o(i);}),r.once("end",()=>{n||e(r);});}else e(r);},U=(r,e)=>{let t=e(r);return t.on("request",s=>{let o=s.emit.bind(s);s.emit=(n,...a)=>{if(n==="response"&&r.decompress){let i=a[0],c=s.listenerCount("response")!==0;return Ee(i,h=>{o("response",h);}),c}return o(n,...a)};}),t};var G=class{storage;constructor(){this.storage=new WeakMap;}get(e){if(e)return this.storage.has(e)||this.storage.set(e,{}),this.storage.get(e)}},Se=new G,$=r=>{let e=r.context||{};e.sessionData=Se.get(e.sessionToken);};function M(r){let e=r.context;e&&e.insecureHTTPParser!==void 0&&(r._unixOptions={...r._unixOptions,insecureHTTPParser:e.insecureHTTPParser});}function j(r,e){let t=r;if(t.cookies){let o=typeof t.cookies=="string"?t.cookies:Object.entries(t.cookies).map(([a,i])=>`${a}=${i}`).join("; ");t.headers||(t.headers={});let n=t.headers.cookie||t.headers.Cookie;t.headers.cookie=n?`${n}; ${o}`:o,delete t.cookies;}let s=["proxyUrl","proxyList","headerGeneratorOptions","useHeaderGenerator","insecureHTTPParser","sessionToken"];for(let o of s)o in t&&(e.context[o]=t[o],delete t[o]);}var Ae={proxyUrl:x.optional.string.url,proxyList:x.optional.array.ofType(x.string.url),useHeaderGenerator:x.optional.boolean,headerGeneratorOptions:x.optional.object,insecureHTTPParser:x.optional.boolean,sessionToken:x.optional.object,cookies:x.any(x.optional.string,x.optional.object)};function N(r){x(r,x.object.partialShape(Ae));}var v=class{agent;constructor(e){this.agent=e;}addRequest(e,t){this.agent.addRequest(e,t);}get keepAlive(){return this.agent.keepAlive}get maxSockets(){return this.agent.maxSockets}get options(){return this.agent.options}get defaultPort(){return this.agent.defaultPort}get protocol(){return this.agent.protocol}destroy(){this.agent.destroy();}get maxFreeSockets(){return this.agent.maxFreeSockets}get maxTotalSockets(){return this.agent.maxTotalSockets}get freeSockets(){return this.agent.freeSockets}get sockets(){return this.agent.sockets}get requests(){return this.agent.requests}on(e,t){return this.agent.on(e,t),this}once(e,t){return this.agent.once(e,t),this}off(e,t){return this.agent.off(e,t),this}addListener(e,t){return this.agent.addListener(e,t),this}removeListener(e,t){return this.agent.removeListener(e,t),this}removeAllListeners(e){return this.agent.removeAllListeners(e),this}setMaxListeners(e){return this.agent.setMaxListeners(e),this}getMaxListeners(){return this.agent.getMaxListeners()}listeners(e){return this.agent.listeners(e)}rawListeners(e){return this.agent.rawListeners(e)}emit(e,...t){return this.agent.emit(e,...t)}eventNames(){return this.agent.eventNames()}listenerCount(e){return this.agent.listenerCount(e)}prependListener(e,t){return this.agent.prependListener(e,t),this}prependOnceListener(e,t){return this.agent.prependOnceListener(e,t),this}createConnection(e,t){return this.agent.createConnection(e,t)}keepSocketAlive(e){this.agent.keepSocketAlive(e);}reuseSocket(e,t){this.agent.reuseSocket(e,t);}getName(e){return this.agent.getName(e)}};var {_storeHeader:be}=OutgoingMessage.prototype,we=new HeaderGenerator,C=class extends v{transformRequest(e,{sortHeaders:t}){let s={},o=e.hasHeader("connection"),n=e.hasHeader("content-length"),a=e.hasHeader("transfer-encoding"),i=e.hasHeader("trailer"),c=e.getHeaderNames();for(let u of c)u.toLowerCase().startsWith("x-")?s[u]=e.getHeader(u):s[this.toPascalCase(u)]=e.getHeader(u),t&&e.removeHeader(u);let h=e;o||(e.shouldKeepAlive&&(n||e.useChunkedEncodingByDefault||h.agent)?s.Connection="keep-alive":s.Connection="close"),!n&&!a&&(!i&&!h._removedContLen&&typeof h._contentLength=="number"?s["Content-Length"]=h._contentLength:h._removedTE||(s["Transfer-Encoding"]="chunked"));let d=t?we.orderHeaders(s):s;for(let[u,p]of Object.entries(d))e.setHeader(u,p);}addRequest(e,t){let s=e;return s._storeHeader=(...o)=>(this.transformRequest(e,{sortHeaders:true}),be.call(e,...o)),t.secureEndpoint=t.protocol==="https:",super.addRequest(e,t)}toPascalCase(e){return e.split("-").map(t=>t[0].toUpperCase()+t.slice(1).toLowerCase()).join("-")}};function b(r){if(!r.username&&!r.password)return null;let e=decodeURIComponent(r.username??""),t=decodeURIComponent(r.password??"");return `Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}function I(r,e){r.proxy=typeof e.proxy=="string"?new URL$1(e.proxy):e.proxy;}function Oe(r){if(r.port!=="")return Number(r.port);if(r.protocol==="http:")return 80;if(r.protocol==="https:")return 443;throw new Error(`Unexpected protocol: ${r.protocol}`)}var B=class extends H.Agent{proxy;constructor(e){super(e),I(this,e);}addRequest(e,t){if(t.socketPath){H.Agent.prototype.addRequest.call(this,e,t);return}let s=`${t.host}:${t.port}`;isIPv6(t.host)&&(s=`[${t.host}]:${t.port}`);let o=new URL$1(`${e.protocol}//${s}${e.path}`);t={...t,host:this.proxy.hostname,port:Oe(this.proxy)},e.path=o.href;let n=b(this.proxy);n&&e.setHeader("proxy-authorization",n),H.Agent.prototype.addRequest.call(this,e,t);}},O=class extends H.Agent{proxy;constructor(e){super(e),I(this,e);}createConnection(e,t){if(e.path)return H.Agent.prototype.createConnection.call(this,e,t);let s=this.proxy.protocol==="https:"?oe.request:H.request,o=`${e.host}:${e.port}`;isIPv6(e.host)&&(o=`[${e.host}]:${e.port}`);let n={host:o},a=b(this.proxy);a&&(n["proxy-authorization"]=a,n.authorization=a);let i=s(this.proxy,{method:"CONNECT",headers:n,path:o,agent:false,rejectUnauthorized:false});i.once("connect",(c,h,d)=>{if(d.length>0||c.statusCode!==200){h.destroy();let u=new Error(`The proxy responded with ${c.statusCode} ${c.statusMessage}: ${d.toString()}`);t&&t(u,null);return}if(e.protocol==="https:"){if(t){let u={...e,socket:h};t(null,ve.connect(u));}return}t&&t(null,h);}),i.once("error",c=>{t&&t(c,null);}),i.end();}},P=class extends oe.Agent{proxy;constructor(e){super(e),I(this,e);}createConnection(e,t){return O.prototype.createConnection.call(this,e,t)}},{auto:Pe}=ae,{HttpOverHttp2:Le,HttpsOverHttp2:Te,Http2OverHttp2:ke,Http2OverHttps:De,Http2OverHttp:qe}=ae.proxies,_=class extends Error{};function Ue(r){if(!(r==="http:"||r==="https:"))throw new _(`Proxy URL protocol "${r}" is not supported. Please use HTTP or HTTPS.`)}async function ie(r,e){let t={},s=b(r);s&&(t.authorization=s,t["proxy-authorization"]=s);let o={proxyOptions:{url:r,headers:t,rejectUnauthorized:e},maxFreeSockets:0,maxEmptySessions:0},n={proxy:r,maxFreeSockets:0},a;if(r.protocol==="https:"){let i="http/1.1";try{i=(await Pe.resolveProtocol({host:r.hostname,port:r.port,rejectUnauthorized:e,ALPNProtocols:["h2","http/1.1"],servername:r.hostname})).alpnProtocol;}catch{}i==="h2"?a={http:new C(new Le(o)),https:new C(new Te(o)),http2:new ke(o)}:a={http:new C(new O(n)),https:new C(new P(n)),http2:new De(o)};}else a={http:new C(new B(n)),https:new C(new P(n)),http2:new qe(o)};return a}async function W(r){let{context:{proxyUrl:e}}=r;if(e){let t=new URL$1(e);Ue(t.protocol),r.agent=await ie(t,r.https.rejectUnauthorized);}}var{auto:V}=ae,Be=async(r,e,t)=>new Promise((s,o)=>{let n=`${e.host}:${e.port}`;isIPv6(e.host)&&(n=`[${e.host}]:${e.port}`),(async()=>{try{let a={host:n},i=new URL$1(r),c=b(i);c&&(a.authorization=c,a["proxy-authorization"]=c);let h=await V(i,{method:"CONNECT",headers:a,path:n,pathname:n,rejectUnauthorized:!1});h.end(),h.once("error",o),h.once("connect",(d,u,p)=>{if(d.statusCode!==200||p.length>0){let R=`Proxy responded with ${d.statusCode} ${d.statusMessage}: ${p.length} bytes.
1
+ import {got as got$1}from'got';export*from'got';import v,{OutgoingMessage}from'http';import pe from'https';import R from'zlib';import {PassThrough,Transform,Readable}from'stream';import Le from'mimic-response';import m from'ow';import {CookieJar}from'tough-cookie';import me from'quick-lru';import ct,{createHash}from'crypto';import {isIPv6}from'net';import De from'tls';import {URL as URL$1}from'url';import D from'http2-wrapper';import*as oe from'cheerio';var U=null,j=class extends Transform{zstdStream;constructor(){super(),this.zstdStream=new U.DecompressStream,this.zstdStream.onData=e=>{this.push(Buffer.from(e));};}_transform(e,t,s){try{this.zstdStream.push(e),s();}catch(n){s(n);}}},Oe=(r,e)=>{let t=r.headers["content-encoding"]?.toLowerCase(),s={flush:R.constants.Z_SYNC_FLUSH,finishFlush:R.constants.Z_SYNC_FLUSH},n=o=>{delete r.headers["content-encoding"];let a=new PassThrough({autoDestroy:false,destroy(i,c){r.destroy(),c(i);}});o.once("error",i=>{a.destroy(i);}),r.pipe(o).pipe(a),e(Le(r,a));};if(t==="gzip"||t==="x-gzip")n(R.createGunzip(s));else if(t==="deflate"||t==="x-deflate"){let o=false;r.once("data",a=>{o=true,r.unshift(a);let i=(a[0]&15)===8?R.createInflate():R.createInflateRaw();n(i);}),r.once("end",()=>{o||e(r);});}else if(t==="br"){let o=false;r.once("data",a=>{o=true,r.unshift(a);let i=R.createBrotliDecompress();n(i);}),r.once("end",()=>{o||e(r);});}else if(t==="zstd"){let o=false;r.once("data",a=>{if(o=true,r.unshift(a),typeof R.createZstdDecompress=="function"){n(R.createZstdDecompress());return}r.pause(),(async()=>{try{U||(U=await import('fzstd'));let i=new j;n(i),r.resume();}catch{let c=new Error("Zstd decompression failed: 'fzstd' package is missing. Please run 'npm i fzstd'.");r.destroy(c);}})();}),r.once("end",()=>{o||e(r);});}else e(r);},B=(r,e)=>{let t=e(r);return t.on("request",s=>{let n=s.emit.bind(s);s.emit=(o,...a)=>{if(o==="response"&&r.decompress){let i=a[0],c=s.listenerCount("response")!==0;return Oe(i,f=>{n("response",f);}),c}return n(o,...a)};}),t};var z=class{weakStorage;stringStorage;constructor(){this.weakStorage=new WeakMap,this.stringStorage=new me({maxSize:1e3,maxAge:36e5});}get(e){if(e){if(typeof e=="string")return this.stringStorage.has(e)||this.stringStorage.set(e,{cookieJar:new CookieJar}),this.stringStorage.get(e);if(typeof e=="object")return this.weakStorage.has(e)||this.weakStorage.set(e,{cookieJar:new CookieJar}),this.weakStorage.get(e)}}},ie=new z,W=r=>{let e=r.context||{};e.sessionToken&&(e.sessionData=ie.get(e.sessionToken));};function F(r){let e=r.context;e&&e.insecureHTTPParser!==void 0&&(r._unixOptions={...r._unixOptions,insecureHTTPParser:e.insecureHTTPParser});}function K(r,e){let t=r,s=["proxyUrl","proxyList","headerGeneratorOptions","useHeaderGenerator","insecureHTTPParser","sessionToken","stealth","browser","os","zstd","smartRetry","cookies","cookieJar"];for(let a of s)a in t&&(e.context[a]=t[a]);let n=e.context,o=n.cookieJar;if(o===true||n.sessionToken){let a=n.sessionData||ie.get(n.sessionToken);a?o=a.cookieJar:o=new CookieJar,e.cookieJar=o;}if(n.cookies){let a=e.url?new URL(e.url.toString()):null,i=a?`${a.protocol}//${a.hostname}`:"",c=typeof n.cookies=="object",f=c?Object.entries(n.cookies).map(([u,l])=>`${u}=${l}`).join("; "):n.cookies;if(o&&o.setCookieSync&&i)if(c)for(let[u,l]of Object.entries(n.cookies))o.setCookieSync(`${u}=${l}`,i);else {let u=f.split(";").map(l=>l.trim());for(let l of u)l&&o.setCookieSync(l,i);}else {e.headers||(e.headers={});let u=e.headers.cookie||e.headers.Cookie;e.headers.cookie=u?`${u}; ${f}`:f;}}}var Pe={proxyUrl:m.optional.string.url,proxyList:m.optional.array.ofType(m.string.url),useHeaderGenerator:m.optional.boolean,headerGeneratorOptions:m.optional.object,insecureHTTPParser:m.optional.boolean,sessionToken:m.any(m.optional.string,m.optional.object),cookies:m.any(m.optional.string,m.optional.object),stealth:m.optional.boolean,browser:m.optional.string,os:m.optional.string,zstd:m.optional.boolean,smartRetry:m.optional.boolean,cookieJar:m.any(m.optional.boolean,m.optional.object)};function Y(r){m(r,m.object.partialShape(Pe));}var k=class{agent;constructor(e){this.agent=e;}addRequest(e,t){this.agent.addRequest(e,t);}get keepAlive(){return this.agent.keepAlive}get maxSockets(){return this.agent.maxSockets}get options(){return this.agent.options}get defaultPort(){return this.agent.defaultPort}get protocol(){return this.agent.protocol}destroy(){this.agent.destroy();}get maxFreeSockets(){return this.agent.maxFreeSockets}get maxTotalSockets(){return this.agent.maxTotalSockets}get freeSockets(){return this.agent.freeSockets}get sockets(){return this.agent.sockets}get requests(){return this.agent.requests}on(e,t){return this.agent.on(e,t),this}once(e,t){return this.agent.once(e,t),this}off(e,t){return this.agent.off(e,t),this}addListener(e,t){return this.agent.addListener(e,t),this}removeListener(e,t){return this.agent.removeListener(e,t),this}removeAllListeners(e){return this.agent.removeAllListeners(e),this}setMaxListeners(e){return this.agent.setMaxListeners(e),this}getMaxListeners(){return this.agent.getMaxListeners()}listeners(e){return this.agent.listeners(e)}rawListeners(e){return this.agent.rawListeners(e)}emit(e,...t){return this.agent.emit(e,...t)}eventNames(){return this.agent.eventNames()}listenerCount(e){return this.agent.listenerCount(e)}prependListener(e,t){return this.agent.prependListener(e,t),this}prependOnceListener(e,t){return this.agent.prependOnceListener(e,t),this}createConnection(e,t){return this.agent.createConnection(e,t)}keepSocketAlive(e){this.agent.keepSocketAlive(e);}reuseSocket(e,t){this.agent.reuseSocket(e,t);}getName(e){return this.agent.getName(e)}};var {_storeHeader:ce}=OutgoingMessage.prototype,ue=["host","connection","content-length","sec-ch-ua","sec-ch-ua-mobile","sec-ch-ua-platform","sec-ch-ua-platform-version","upgrade-insecure-requests","user-agent","accept","sec-fetch-site","sec-fetch-mode","sec-fetch-user","sec-fetch-dest","referer","accept-encoding","accept-language","cookie","priority"],A=class extends k{transformRequest(e,t=false){let s={},n=typeof e.getHeaderNames=="function"?e.getHeaderNames():Object.keys(e.getHeaders?e.getHeaders():{}),o=e.hasHeader?e.hasHeader("connection"):false,a=e.hasHeader?e.hasHeader("content-length"):false,i=e.hasHeader?e.hasHeader("transfer-encoding"):false;for(let u of n)s[u.toLowerCase()]=e.getHeader(u),e.removeHeader(u);let c=e;if(!t&&!o){let u=e.shouldKeepAlive&&(a||e.useChunkedEncodingByDefault||c.agent);s.connection=u?"keep-alive":"close";}!a&&!i&&!c._removedContLen&&typeof c._contentLength=="number"&&(s["content-length"]=c._contentLength);let f=Object.keys(s).sort((u,l)=>{let d=ue.indexOf(u),p=ue.indexOf(l);return d===-1&&p===-1?0:d===-1?1:p===-1?-1:d-p});for(let u of f){let l=t?u.toLowerCase():this.toPascalCase(u);s[u]!==void 0&&e.setHeader(l,s[u]);}}addRequest(e,t){let s=e,o=(s.agent?.constructor?.name||"").includes("Http2")||s.agent?.protocol==="h2:"||s.isH2===true;if(typeof ce=="function")s._storeHeader=(...a)=>{try{this.transformRequest(e,o);}catch{}return ce.call(e,...a)};else try{this.transformRequest(e,o);}catch{}return t.secureEndpoint=t.protocol==="https:",super.addRequest(e,t)}toPascalCase(e){return e.toLowerCase().startsWith("sec-ch-ua")?e.split("-").map(t=>t==="ua"?"UA":t==="sec"?"Sec":t==="ch"?"CH":t[0].toUpperCase()+t.slice(1).toLowerCase()).join("-"):e.split("-").map(t=>t[0].toUpperCase()+t.slice(1).toLowerCase()).join("-")}};function L(r){if(!r.username&&!r.password)return null;let e=decodeURIComponent(r.username??""),t=decodeURIComponent(r.password??"");return `Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}function V(r,e){r.proxy=typeof e.proxy=="string"?new URL$1(e.proxy):e.proxy;}function Me(r){if(r.port!=="")return Number(r.port);if(r.protocol==="http:")return 80;if(r.protocol==="https:")return 443;throw new Error(`Unexpected protocol: ${r.protocol}`)}var I=class extends v.Agent{proxy;constructor(e){super(e),V(this,e);}addRequest(e,t){if(t.socketPath){v.Agent.prototype.addRequest.call(this,e,t);return}let s=`${t.host}:${t.port}`;isIPv6(t.host)&&(s=`[${t.host}]:${t.port}`);let n=new URL$1(`${e.protocol}//${s}${e.path}`);t={...t,host:this.proxy.hostname,port:Me(this.proxy)},e.path=n.href;let o=L(this.proxy);o&&e.setHeader("proxy-authorization",o),v.Agent.prototype.addRequest.call(this,e,t);}},P=class extends v.Agent{proxy;constructor(e){super(e),V(this,e);}createConnection(e,t){if(e.path)return v.Agent.prototype.createConnection.call(this,e,t);let s=this.proxy.protocol==="https:"?pe.request:v.request,n=`${e.host}:${e.port}`;isIPv6(e.host)&&(n=`[${e.host}]:${e.port}`);let o={host:n},a=L(this.proxy);a&&(o["proxy-authorization"]=a,o.authorization=a);let i=s(this.proxy,{method:"CONNECT",headers:o,path:n,agent:false,rejectUnauthorized:false});i.once("connect",(c,f,u)=>{if(u.length>0||c.statusCode!==200){f.destroy();let l=new Error(`The proxy responded with ${c.statusCode} ${c.statusMessage}: ${u.toString()}`);t&&t(l,null);return}if(e.protocol==="https:"){if(t){let l={...e,socket:f};t(null,De.connect(l));}return}t&&t(null,f);}),i.once("error",c=>{t&&t(c,null);}),i.end();}},T=class extends pe.Agent{proxy;constructor(e){super(e),V(this,e);}createConnection(e,t){return P.prototype.createConnection.call(this,e,t)}},{auto:$e}=D,{HttpOverHttp2:Ge,HttpsOverHttp2:qe,Http2OverHttp2:Ue,Http2OverHttps:je,Http2OverHttp:Be}=D.proxies,w=class extends Error{};function Ne(r){if(!(r==="http:"||r==="https:"))throw new w(`Proxy URL protocol "${r}" is not supported. Please use HTTP or HTTPS.`)}async function he(r,e){let t={},s=L(r);s&&(t.authorization=s,t["proxy-authorization"]=s);let n={proxyOptions:{url:r,headers:t,rejectUnauthorized:e},maxFreeSockets:0,maxEmptySessions:0},o={proxy:r,maxFreeSockets:0},a;if(r.protocol==="https:"){let i="http/1.1";try{i=(await $e.resolveProtocol({host:r.hostname,port:r.port,rejectUnauthorized:e,ALPNProtocols:["h2","http/1.1"],servername:r.hostname})).alpnProtocol;}catch{}i==="h2"?a={http:new A(new Ge(n)),https:new A(new qe(n)),http2:new Ue(n)}:a={http:new A(new P(o)),https:new A(new T(o)),http2:new je(n)};}else a={http:new A(new I(o)),https:new A(new T(o)),http2:new Be(n)};return a}async function J(r){let{context:{proxyUrl:e}}=r;if(e){let t=new URL$1(e);Ne(t.protocol),r.agent=await he(t,r.https.rejectUnauthorized);}}var ye=D.auto||D.default?.auto,ge={headerTableSize:65536,enablePush:false,initialWindowSize:6291456,maxHeaderListSize:262144,maxConcurrentStreams:1e3},Ye=async(r,e,t)=>new Promise((s,n)=>{let o=`${e.host}:${e.port}`;isIPv6(e.host)&&(o=`[${e.host}]:${e.port}`),(async()=>{try{let a={host:o},i=new URL$1(r),c=L(i);c&&(a.authorization=c,a["proxy-authorization"]=c);let f=await ye(i,{method:"CONNECT",headers:a,path:o,pathname:o,rejectUnauthorized:!1,settings:ge});f.end(),f.once("error",n),f.once("connect",(u,l,d)=>{if(u.statusCode!==200||d.length>0){let g=`Proxy responded with ${u.statusCode} ${u.statusMessage}: ${d.length} bytes.
2
2
 
3
3
  Below is the first 100 bytes of the proxy response body:
4
- ${p.toString("utf8",0,100)}`;o(new _(R,{cause:p.toString("utf8")})),u.destroy();return}let l=ve.connect({...e,socket:u},t);s(l);});}catch(a){o(a);}})();}),z=()=>({protocolCache:new ue({maxSize:1e3}),resolveAlpnQueue:new Map}),ce=new ue({maxSize:100}),Fe=z(),Y=(r,e,t)=>{let{protocolCache:s,resolveAlpnQueue:o}=Fe;if(e)(!e.protocolCache||!e.resolveAlpnQueue)&&Object.assign(e,z()),s=e.protocolCache,o=e.resolveAlpnQueue;else {let i=createHash("sha256").update(r).digest("hex"),c=ce.get(i)??z();ce.set(i,c),s=c.protocolCache,o=c.resolveAlpnQueue;}let n=async(i,c)=>Be(r,i,c),a=V.createResolveProtocol(s,o,n);return async(...i)=>a({...i[0],timeout:t})};function K(r){let e=r.context||{},{proxyUrl:t,sessionData:s}=e;r.http2&&r.url.protocol!=="http:"?r.request=(o,n,a)=>{let i=n;return t&&(i.resolveProtocol=Y(t,s,Math.min(r?.timeout?.connect??6e4,r?.timeout?.request??6e4))),V(o,i,a)}:r.request=void 0;}function We(r,e){let t=new Map;for(let s of Object.entries(r))t.set(s[0].toLowerCase(),s);for(let s of Object.entries(e))s[1]!==void 0&&t.set(s[0].toLowerCase(),s);return Object.fromEntries(t.values())}var ze=(r,e,t)=>{let{resolveProtocol:s}=r.context||{};if(s)return s;let o=r?.timeout?.connect??6e4,n=r?.timeout?.request??6e4,a=Math.min(o,n);return e?Y(e,t,a):(...i)=>ae.auto.resolveProtocol({...i[0],timeout:a})};async function X(r){let e=r.context;if(!e)return;let{headerGeneratorOptions:t,useHeaderGenerator:s,headerGenerator:o,proxyUrl:n}=e,a=e.sessionData;if(!s||!o)return;let i=()=>({1:o.getHeaders({httpVersion:"1",...t}),2:o.getHeaders({httpVersion:"2",...t})}),c=r.url,h=ze(r,n,a),d;c.protocol==="https:"&&(d=(await h({host:c.hostname,port:c.port||443,rejectUnauthorized:false,ALPNProtocols:["h2","http/1.1"],servername:c.hostname})).alpnProtocol);let u=d==="h2"?"2":"1",p;if(a?(a.headers||(a.headers=i()),p=a.headers[u]):p=o.getHeaders({httpVersion:u,...t}),!r.decompress)for(let l of Object.keys(p))l.toLowerCase()==="accept-encoding"&&delete p[l];r.headers=We(p,r.headers);}var Ye=Number(Ve.versions.node.split(".")[0])>=17,J=16,Q=1<<19,Ke={firefox:(Ye?["X25519","prime256v1","secp384r1","secp521r1","ffdhe2048","ffdhe3072"]:["X25519","prime256v1","secp384r1","secp521r1"]).join(":"),chrome:["X25519","prime256v1","secp384r1"].join(":"),safari:["X25519","prime256v1","secp384r1","secp521r1"].join(":")},Xe={firefox:["ecdsa_secp256r1_sha256","ecdsa_secp384r1_sha384","ecdsa_secp521r1_sha512","rsa_pss_rsae_sha256","rsa_pss_rsae_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha256","rsa_pkcs1_sha384","rsa_pkcs1_sha512"].join(":"),chrome:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),safari:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":")},Je={chrome:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),firefox:["TLS_AES_128_GCM_SHA256","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_256_GCM_SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384"].join(":"),safari:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-RSA-CHACHA20-POLY1305"].join(":")},Qe={firefox:"TLSv1.2",chrome:"TLSv1.2",safari:"TLSv1.2"},Ze={firefox:"TLSv1.3",chrome:"TLSv1.3",safari:"TLSv1.3"},et={firefox:J|Q,chrome:J|Q,safari:J|Q},tt={firefox:true,chrome:true,safari:true},rt=r=>{for(let[e,t]of Object.entries(r))if(e.toLowerCase()==="user-agent")return t},st=r=>{if(!r)return;let e;return r.includes("Firefox")?e="firefox":r.includes("Chrome")?e="chrome":e="safari",e};function Z(r){let{https:e}=r;if(e.ciphers||e.signatureAlgorithms||e.minVersion||e.maxVersion)return;let t=st(rt(r.headers))??"firefox";e.ciphers=Je[t],e.signatureAlgorithms=Xe[t],e.ecdhCurve=Ke[t],e.minVersion=Qe[t],e.maxVersion=Ze[t],r._unixOptions={...r._unixOptions,secureOptions:et[t],requestOCSP:tt[t]};}var ee=(r,e)=>{let t=r.url,s=new URL$1(e.url),o=e.headers["referer-policy"]||"strict-origin-when-cross-origin",n=r.headers;o==="no-referrer"?delete n.referer:o==="no-referrer-when-downgrade"?s.protocol==="https:"&&t.protocol==="http:"?delete n.referer:n.referer=`${s.origin}${s.pathname}${s.search}`:o==="origin"?n.referer=s.origin:o==="origin-when-cross-origin"?t.origin===s.origin?n.referer=`${s.origin}${s.pathname}${s.search}`:n.referer=s.origin:o==="same-origin"?t.origin===s.origin?n.referer=`${s.origin}${s.pathname}${s.search}`:delete n.referer:o==="strict-origin"?s.protocol==="https:"&&t.protocol==="http:"?delete n.referer:n.referer=s.origin:o==="strict-origin-when-cross-origin"?t.origin===s.origin?n.referer=`${s.origin}${s.pathname}${s.search}`:s.protocol==="https:"&&t.protocol==="http:"?delete n.referer:n.referer=s.origin:o==="unsafe-url"&&(n.referer=`${s.origin}${s.pathname}${s.search}`);};var y=class r extends Error{status;code;config;hint;constructor(e,t,s,o,n){let a=n?`${e}
5
- \u{1F4A1} Hint: ${n}`:e;super(a),this.name="RanuxError",this.status=t,this.code=s,this.config=o,this.hint=n,Object.setPrototypeOf(this,r.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,r);}};var le=r=>String.fromCharCode(...r),ct=()=>le([82,97,110,117,120,95,85,108,116,114,97,95,83,101,99,117,114,101,95,69,100,103,101,95,50,48,50,54,95,88,57]),ut=[[104,116,116,112,115,58,47,47,114,97,110,117,120,46,114,97,110,115,97,114,97,100,101,118,110,97,116,104,46,119,111,114,107,101,114,115,46,100,101,118,47],[104,116,116,112,115,58,47,47,114,97,110,117,120,50,46,97,109,114,97,110,115,97,114,97,109,97,120,46,119,111,114,107,101,114,115,46,100,101,118,47],[104,116,116,112,115,58,47,47,114,97,110,117,120,51,46,114,97,110,117,120,114,97,110,115,97,114,97,46,119,111,114,107,101,114,115,46,100,101,118,47],[104,116,116,112,115,58,47,47,114,97,110,117,120,52,46,114,97,110,117,120,110,101,119,46,119,111,114,107,101,114,115,46,100,101,118,47]],pt=()=>ut.map(le);function te(r){return new Promise((e,t)=>{let s=[];r.on("data",o=>s.push(Buffer.from(o))),r.on("end",()=>e(Buffer.concat(s))),r.on("error",t);})}function lt(r,e){return !!([403,429,503].includes(r)||(e.server||"").toLowerCase().includes("cloudflare")&&e["cf-mitigated"])}function dt(r,e){let t=new URL(r),s=Object.keys(e).map(o=>o.toLowerCase());if(s.includes("referer")||(e.Referer=t.origin+"/"),!s.includes("sec-fetch-dest")){let o=t.pathname.includes("/api/")||t.pathname.endsWith(".json");e["Sec-Fetch-Dest"]=o?"empty":"document",e["Sec-Fetch-Mode"]=o?"cors":"navigate",e["Sec-Fetch-Site"]="cross-site",e["Sec-Fetch-User"]="?1";}}function ht(r,e,t,s){return new Promise((o,n)=>{let a={...t.headers||{}};dt(e,a);let i=e,c=t.proxyUrl;if(s.type==="proxy"&&s.url)c=s.url;else if(s.type==="edge"&&s.url){i=s.url;let l=Date.now().toString(),R=it.createHash("sha256").update(e+l+ct()).digest("hex");a["X-Amz-Cf-Id"]=Buffer.from(e).toString("base64"),a["X-Amz-Request-Id"]=`${l}-${R}`;}let h=typeof t.timeout=="number"?t.timeout:t.timeout?.request||6e4,d={method:t.method||"GET",headers:a,timeout:{request:h},throwHttpErrors:false,retry:{limit:0},followRedirect:true,isStream:true,proxyUrl:c,sessionToken:t.sessionToken,headerGeneratorOptions:t.headerGeneratorOptions,useHeaderGenerator:t.useHeaderGenerator,insecureHTTPParser:t.insecureHTTPParser,cookieJar:t.cookieJar,http2:t.http2,https:t.https,decompress:t.decompress,context:t.context,...Object.fromEntries(Object.entries(t).filter(([l])=>!["method","headers","timeout","data","json","params","searchParams","signal","relayMode","responseType","baseURL","prefixUrl","proxyUrl","proxyList","onDownloadProgress","onUploadProgress","cookies","httpAgent","httpsAgent","transformRequest","transformResponse","sessionToken","headerGeneratorOptions","useHeaderGenerator","insecureHTTPParser","cookieJar","http2","https","decompress","context"].includes(l)))};for(let l in d)d[l]===void 0&&delete d[l];t.data?typeof t.data=="string"||Buffer.isBuffer(t.data)?d.body=t.data:d.json=t.data:t.json&&(d.json=t.json);let u=t.params||t.searchParams;u&&(d.searchParams=u),(t.httpAgent||t.httpsAgent)&&(d.agent={http:t.httpAgent,https:t.httpsAgent});let p=r.stream(i,d);t.onDownloadProgress&&p.on("downloadProgress",l=>t.onDownloadProgress(l)),t.onUploadProgress&&p.on("uploadProgress",l=>t.onUploadProgress(l)),t.signal&&t.signal.addEventListener("abort",()=>{p.destroy(),n(new y("Request aborted by user signal",0,"ERR_ABORTED",t));}),p.on("response",async l=>{let R=l.statusCode,w=l.headers;if(s.type==="edge"&&[502,504,524].includes(R))return p.destroy(),n(new y("Worker Node Exhausted",R,"ERR_EDGE_OOM",t));if(lt(R,w))return p.destroy(),n(new y("WAF Block Detected",R,"ERR_WAF_BLOCK",t));let m=null,E=null,re=(w["content-type"]||"").toLowerCase(),Re=parseInt(w["content-length"]||"0",10),se=re.match(/(audio|video|image|application\/(zip|octet-stream|x-rar))/i)||Re>5*1024*1024;if(re.includes("text/html")&&!se&&R===200)try{m=await te(p);let f=m.toString("utf-8",0,8e3);if(f.includes("_cf_chl_opt")||f.includes("Just a moment...")||f.includes("cf-please-wait")||f.includes("DataDome"))return n(new y("WAF Challenge (Status 200) Detected",200,"ERR_WAF_BLOCK",t))}catch{return n(new y("Failed to read response stream",R,"ERR_NETWORK",t))}let D=m?Readable.from(m):p.pipe(new PassThrough),S={status:R,statusCode:R,headers:w,stream:D,data:null,body:null,async buffer(){return m||(m=await te(D),m)},async text(){return (await this.buffer()).toString("utf-8")},async json(){let f=await this.text();try{return JSON.parse(f)}catch{return f}},$(){if(!m&&!E)throw new y("Data not loaded. Wait for request to finish or use res.text() for streams.");let f=m?m.toString("utf-8"):typeof E=="string"?E:"";return pe.load(f)}};if(t.responseType==="stream"||se)S.data="[STREAM_READY_USE_RES_BUFFER]",S.body=S.data,o(S);else try{let f=m||await te(D);m=f;let q=f.toString("utf-8");try{E=JSON.parse(q);}catch{E=q;}S.data=E,S.body=E,o(S);}catch(f){n(f);}}),p.on("error",l=>{n(new y(l.message,0,"ERR_NETWORK",t));});})}async function de(r,e,t={}){let s=pt(),o=[];t.relayMode!=="always"&&o.push({type:"local"}),t.proxyList&&Array.isArray(t.proxyList)&&t.proxyList.forEach(i=>o.push({type:"proxy",url:i})),t.relayMode!=="never"&&s.forEach(i=>o.push({type:"edge",url:i}));let n,a;for(let i of o)try{return await ht(r,e,t,i)}catch(c){if(a=c,c instanceof y){if(c.code==="ERR_WAF_BLOCK"&&!n&&(n=c),c.code==="ERR_EDGE_OOM")throw n?(n.hint="The requested file seems too large to buffer directly via Edge Nodes. You can try setting `{ responseType: 'stream' }` to download it successfully without IP blocks.",n):c;if(c.code!=="ERR_WAF_BLOCK"&&c.code!=="ERR_NETWORK")throw c}}throw n||new y("All execution nodes and proxies exhausted. Target is unreachable or heavily shielded.",a?.status||500,"ERR_EXHAUSTED",t)}var Rt=()=>{let r=Object.getOwnPropertyDescriptor(Options.prototype,"url");if(r&&r.set){let e=r.set;Object.defineProperty(Options.prototype,"url",{set(t){let s=global.decodeURI;global.decodeURI=o=>o;try{return e.call(this,t)}finally{global.decodeURI=s;}}});}};Rt();var fe=[N,j],me=[M,$,K,W,X,Z],ye=[ee],L=got$1.extend({handlers:[U],mutableDefaults:true,http2:true,https:{rejectUnauthorized:false},throwHttpErrors:false,timeout:{request:6e4},retry:{limit:0},headers:{"user-agent":void 0},context:{headerGenerator:new HeaderGenerator,useHeaderGenerator:true,insecureHTTPParser:true},agent:{http:new C(H.globalAgent),https:new C(oe.globalAgent)},hooks:{init:fe,beforeRequest:me,beforeRedirect:ye}}),Hr={init:fe,beforeRequest:me,beforeRedirect:ye,fixDecompress:U,insecureParserHook:M,sessionDataHook:$,http2Hook:K,proxyHook:W,browserHeadersHook:X,tlsHook:Z,optionsValidationHandler:N,customOptionsHook:j,refererHook:ee},T=class{handlers=[];use(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null);}clear(){this.handlers=[];}},k={request:new T,response:new T};async function g(r,e={}){e.transformRequest&&(Array.isArray(e.transformRequest)?e.transformRequest:[e.transformRequest]).forEach(o=>{e.data=o(e.data,e.headers||{});});let t=Promise.resolve(e);return k.request.handlers.forEach(s=>{s&&(t=t.then(s.fulfilled,s.rejected));}),t=t.then(s=>de(L,r,s)),k.response.handlers.forEach(s=>{s&&(t=t.then(s.fulfilled,s.rejected));}),t=t.then(s=>(e.transformResponse&&s&&s.data&&s.data!=="[STREAM_READY_USE_RES_BUFFER]"&&(Array.isArray(e.transformResponse)?e.transformResponse:[e.transformResponse]).forEach(n=>{s.data=n(s.data,s.headers||{}),s.body=s.data;}),s)),t}var ge=Object.assign((r,e)=>g(r,e),{get:(r,e)=>g(r,{...e,method:"GET"}),post:(r,e,t)=>g(r,{...t,data:e,method:"POST"}),put:(r,e,t)=>g(r,{...t,data:e,method:"PUT"}),delete:(r,e)=>g(r,{...e,method:"DELETE"}),patch:(r,e,t)=>g(r,{...t,data:e,method:"PATCH"}),head:(r,e)=>g(r,{...e,method:"HEAD"}),interceptors:k,native:L,paginate:L.paginate,stream:L.stream,create:r=>({get:(e,t)=>g((r.baseURL||"")+e,{...r,...t,method:"GET"}),post:(e,t,s)=>g((r.baseURL||"")+e,{...r,...s,data:t,method:"POST"}),put:(e,t,s)=>g((r.baseURL||"")+e,{...r,...s,data:t,method:"PUT"}),delete:(e,t)=>g((r.baseURL||"")+e,{...r,...t,method:"DELETE"}),patch:(e,t,s)=>g((r.baseURL||"")+e,{...r,...s,data:t,method:"PATCH"}),head:(e,t)=>g((r.baseURL||"")+e,{...r,...t,method:"HEAD"}),interceptors:k}),extend:r=>ge.create({baseURL:r.prefixUrl,...r})});var _r=ge;export{_ as ProxyError,y as RanuxError,C as TransformHeadersAgent,_r as default,ie as getAgents,L as gotScraping,Hr as hooks,ge as ranux};
4
+ ${d.toString("utf8",0,100)}`;n(new w(g,{cause:d.toString("utf8")})),l.destroy();return}let p=De.connect({...e,socket:l},t);s(p);});}catch(a){n(a);}})();}),Q=()=>({protocolCache:new me({maxSize:1e3}),resolveAlpnQueue:new Map}),fe=new me({maxSize:100}),Ie=Q(),Z=(r,e,t)=>{let{protocolCache:s,resolveAlpnQueue:n}=Ie;if(e)(!e.protocolCache||!e.resolveAlpnQueue)&&Object.assign(e,Q()),s=e.protocolCache,n=e.resolveAlpnQueue;else {let i=createHash("sha256").update(r).digest("hex"),c=fe.get(i)??Q();fe.set(i,c),s=c.protocolCache,n=c.resolveAlpnQueue;}let o=async(i,c)=>Ye(r,i,c),a=(D.auto||D.default?.auto).createResolveProtocol(s,n,o);return async(...i)=>a({...i[0],timeout:t})};function ee(r){let e=r.context||{},{proxyUrl:t,sessionData:s,stealth:n}=e;r.http2&&r.url.protocol!=="http:"?r.request=(o,a,i)=>{let c=a;return t&&(c.resolveProtocol=Z(t,s,Math.min(r?.timeout?.connect??6e4,r?.timeout?.request??6e4))),n!==false&&(c.settings=ge),ye(o,c,i)}:r.request=void 0;}var y={chrome:"151.0.0.0",chrome_ch:"151",edge_ch:"151",brave_ch:"151",arc_ch:"151",opera_ch:"134",samsung_ch:"26",samsung_ua:"26.0",firefox:"154.0",safari:"605.1.15",safari_version:"19.0"},_e={windows:{ua:"Windows NT 10.0; Win64; x64",ch:'"Windows"',ch_ver:'"15.0.0"'},mac:{ua:"Macintosh; Intel Mac OS X 10_15_7",ch:'"macOS"',ch_ver:'"26.0.0"'},linux:{ua:"X11; Linux x86_64",ch:'"Linux"',ch_ver:'"6.5.0"'},android:{ua:"Linux; Android 14; SM-S928B",ch:'"Android"',ch_ver:'"14.0.0"'},ios:{ua:"iPhone; CPU iPhone OS 17_5_1 like Mac OS X",ch:'"iOS"',ch_ver:'"17.5.1"'}};function Ve(r,e){let t=e==="android"||e==="ios"?"?1":"?0",s=_e[e]||_e.windows,n="",o="",a={Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","Accept-Language":"en-US,en;q=0.9","Upgrade-Insecure-Requests":"1","Sec-Fetch-Site":"none","Sec-Fetch-Mode":"navigate","Sec-Fetch-User":"?1","Sec-Fetch-Dest":"document",Priority:"u=0, i"};return r==="samsung"?(n=`Mozilla/5.0 (${s.ua}) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/${y.samsung_ua} Chrome/${y.chrome} Mobile Safari/537.36`,o=`"Samsung Internet";v="${y.samsung_ch}", "Chromium";v="${y.chrome_ch}", "Not_A Brand";v="24"`,Object.assign(a,{"Sec-CH-UA":o,"Sec-CH-UA-Mobile":"?1","Sec-CH-UA-Platform":'"Android"',"Sec-CH-UA-Platform-Version":s.ch_ver})):["chrome","brave","edge","arc","opera"].includes(r)?(n=`Mozilla/5.0 (${s.ua}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${y.chrome} Safari/537.36`,r==="brave"?o=`"Brave";v="${y.brave_ch}", "Chromium";v="${y.chrome_ch}", "Not_A Brand";v="24"`:r==="edge"?(o=`"Microsoft Edge";v="${y.edge_ch}", "Chromium";v="${y.chrome_ch}", "Not_A Brand";v="24"`,n=`${n} Edg/${y.edge_ch}.0.0.0`):r==="opera"?(o=`"Opera";v="${y.opera_ch}", "Chromium";v="${y.chrome_ch}", "Not_A Brand";v="24"`,n=`${n} OPR/${y.opera_ch}.0.0.0`):r==="arc"?o=`"Arc";v="${y.arc_ch}", "Chromium";v="${y.chrome_ch}", "Not_A Brand";v="24"`:o=`"Chromium";v="${y.chrome_ch}", "Google Chrome";v="${y.chrome_ch}", "Not_A Brand";v="24"`,Object.assign(a,{"Sec-CH-UA":o,"Sec-CH-UA-Mobile":t,"Sec-CH-UA-Platform":s.ch,"Sec-CH-UA-Platform-Version":s.ch_ver})):r==="firefox"?(n=`Mozilla/5.0 (${s.ua}; rv:${y.firefox}) Gecko/20100101 Firefox/${y.firefox}`,a.Accept="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",a.Priority="u=1"):(n=`Mozilla/5.0 (${s.ua}) AppleWebKit/${y.safari} (KHTML, like Gecko) Version/${y.safari_version} Safari/${y.safari}`,a.Accept="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),a["User-Agent"]=n,a}function Je(r,e){let t=new Map;for(let[s,n]of Object.entries(r))t.set(s.toLowerCase(),n);for(let[s,n]of Object.entries(e))n!==void 0&&t.set(s.toLowerCase(),n);return Object.fromEntries(t.entries())}var Qe=(r,e,t)=>{let{resolveProtocol:s}=r.context||{};if(s)return s;let n=r?.timeout?.connect??6e4,o=r?.timeout?.request??6e4,a=Math.min(n,o);return e?Z(e,t,a):(...i)=>D.auto.resolveProtocol({...i[0],timeout:a})};async function te(r){let e=r.context;if(!e)return;let{stealth:t,browser:s,os:n,zstd:o,proxyUrl:a,sessionData:i}=e,c=s||"chrome",f=n||"windows";if(c==="random"){let g=["chrome","brave","edge","arc","opera","firefox","safari"];c=g[Math.floor(Math.random()*g.length)];}if(f==="random"){let g=["windows","mac","linux","android"];f=g[Math.floor(Math.random()*g.length)];}let u=r.url,l=Qe(r,a,i),d;if(u.protocol==="https:")try{d=(await l({host:u.hostname,port:u.port||443,rejectUnauthorized:!1,ALPNProtocols:["h2","http/1.1"],servername:u.hostname})).alpnProtocol;}catch{d="http/1.1";}e.negotiatedProtocol=d;let p;t!==false?i&&i.cachedHeaders?p=i.cachedHeaders:(p=Ve(c,f),i&&(i.cachedHeaders=p)):p={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36"},r.decompress?p["Accept-Encoding"]=o!==false?"gzip, deflate, br, zstd":"gzip, deflate, br":delete p["Accept-Encoding"],r.headers=Je(p,r.headers);}var Ze=16,et=1<<19,tt={chrome:["X25519MLKEM768","X25519Kyber768","X25519","prime256v1","secp384r1"].join(":"),brave:["X25519MLKEM768","X25519Kyber768","X25519","prime256v1","secp384r1"].join(":"),edge:["X25519MLKEM768","X25519Kyber768","X25519","prime256v1","secp384r1"].join(":"),arc:["X25519MLKEM768","X25519Kyber768","X25519","prime256v1","secp384r1"].join(":"),opera:["X25519MLKEM768","X25519Kyber768","X25519","prime256v1","secp384r1"].join(":"),samsung:["X25519","prime256v1","secp384r1"].join(":"),firefox:["X25519","prime256v1","secp384r1","secp521r1","ffdhe2048","ffdhe3072"].join(":"),safari:["X25519","prime256v1","secp384r1","secp521r1"].join(":")},rt={chrome:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),brave:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),edge:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),arc:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),opera:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),samsung:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":"),firefox:["ecdsa_secp256r1_sha256","ecdsa_secp384r1_sha384","ecdsa_secp521r1_sha512","rsa_pss_rsae_sha256","rsa_pss_rsae_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha256","rsa_pkcs1_sha384","rsa_pkcs1_sha512"].join(":"),safari:["ecdsa_secp256r1_sha256","rsa_pss_rsae_sha256","rsa_pkcs1_sha256","ecdsa_secp384r1_sha384","rsa_pss_rsae_sha384","rsa_pkcs1_sha384","rsa_pss_rsae_sha512","rsa_pkcs1_sha512"].join(":")},Se={chrome:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),brave:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),edge:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),arc:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),opera:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),samsung:["TLS_AES_128_GCM_SHA256","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_256_GCM_SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305"].join(":"),firefox:["TLS_AES_128_GCM_SHA256","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_256_GCM_SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384"].join(":"),safari:["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-AES128-GCM-SHA256","ECDHE-RSA-CHACHA20-POLY1305"].join(":")},st=r=>{for(let[e,t]of Object.entries(r))if(e.toLowerCase()==="user-agent")return t},ot=r=>r?r.includes("Edg/")?"edge":r.includes("OPR/")?"opera":r.includes("SamsungBrowser")?"samsung":r.includes("Firefox")?"firefox":r.includes("Chrome")?"chrome":r.includes("Safari")&&!r.includes("Chrome")?"safari":"chrome":"chrome";function re(r){let{https:e,context:t}=r;if(e.ciphers||e.signatureAlgorithms||e.minVersion)return;let s=t?.browser;(!s||s==="random")&&(s=ot(st(r.headers))),s in Se||(s="chrome"),e.ciphers=Se[s],e.signatureAlgorithms=rt[s],e.ecdhCurve=tt[s],e.minVersion="TLSv1.2",e.maxVersion="TLSv1.3",r._unixOptions={...r._unixOptions,secureOptions:Ze|et,requestOCSP:true};}var se=(r,e)=>{let t=r.url,s=new URL$1(e.url),n=e.headers["referer-policy"]||"strict-origin-when-cross-origin",o=r.headers;n==="no-referrer"?delete o.referer:n==="no-referrer-when-downgrade"?s.protocol==="https:"&&t.protocol==="http:"?delete o.referer:o.referer=`${s.origin}${s.pathname}${s.search}`:n==="origin"?o.referer=s.origin:n==="origin-when-cross-origin"?t.origin===s.origin?o.referer=`${s.origin}${s.pathname}${s.search}`:o.referer=s.origin:n==="same-origin"?t.origin===s.origin?o.referer=`${s.origin}${s.pathname}${s.search}`:delete o.referer:n==="strict-origin"?s.protocol==="https:"&&t.protocol==="http:"?delete o.referer:o.referer=s.origin:n==="strict-origin-when-cross-origin"?t.origin===s.origin?o.referer=`${s.origin}${s.pathname}${s.search}`:s.protocol==="https:"&&t.protocol==="http:"?delete o.referer:o.referer=s.origin:n==="unsafe-url"&&(o.referer=`${s.origin}${s.pathname}${s.search}`);};var C=class r extends Error{status;code;config;hint;response;constructor(e,t,s,n,o,a,i){let c=o?`${e}
5
+ \u{1F4A1} Hint: ${o}`:e;super(c),this.name="RanuxError",this.status=t,this.code=s,this.config=n,this.hint=o,t&&(this.response={status:t,data:a||c,headers:i||{}}),Object.setPrototypeOf(this,r.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,r);}};var Ae=r=>String.fromCharCode(...r),ut=()=>Ae([82,97,110,117,120,95,85,108,116,114,97,95,83,101,99,117,114,101,95,69,100,103,101,95,50,48,50,54,95,88,57]),pt=[[104,116,116,112,115,58,47,47,114,97,110,117,120,46,114,97,110,115,97,114,97,100,101,118,110,97,116,104,46,119,111,114,107,101,114,115,46,100,101,118,47],[104,116,116,112,115,58,47,47,114,97,110,117,120,50,46,97,109,114,97,110,115,97,114,97,109,97,120,46,119,111,114,107,101,114,115,46,100,101,118,47],[104,116,116,112,115,58,47,47,114,97,110,117,120,51,46,114,97,110,117,120,114,97,110,115,97,114,97,46,119,111,114,107,101,114,115,46,100,101,118,47],[104,116,116,112,115,58,47,47,114,97,110,117,120,52,46,114,97,110,117,120,110,101,119,46,119,111,114,107,101,114,115,46,100,101,118,47]],lt=()=>pt.map(Ae);function O(r){return new Promise((e,t)=>{let s=[];r.on("data",n=>s.push(Buffer.from(n))),r.on("end",()=>e(Buffer.concat(s))),r.on("error",t);})}function dt(r,e){return !!([403,429,503].includes(r)||(e.server||"").toLowerCase().includes("cloudflare")&&e["cf-mitigated"])}function ht(r,e){let t=new URL(r),s=Object.keys(e).map(n=>n.toLowerCase());if(s.includes("referer")||(e.Referer=t.origin+"/"),!s.includes("sec-fetch-dest")){let n=t.pathname.includes("/api/")||t.pathname.endsWith(".json");e["Sec-Fetch-Dest"]=n?"empty":"document",e["Sec-Fetch-Mode"]=n?"cors":"navigate",e["Sec-Fetch-Site"]="cross-site",e["Sec-Fetch-User"]="?1";}}function ft(r,e,t,s){return new Promise((n,o)=>{let a={...t.headers||{}};ht(e,a);let i=e,c=t.proxyUrl;if(s.type==="proxy"&&s.url)c=s.url;else if(s.type==="edge"&&s.url){i=s.url;let p=Date.now().toString(),g=ct.createHash("sha256").update(e+p+ut()).digest("hex");a["X-Amz-Cf-Id"]=Buffer.from(e).toString("base64"),a["X-Amz-Request-Id"]=`${p}-${g}`;}let f=typeof t.timeout=="number"?t.timeout:t.timeout?.request||6e4,u={method:t.method||"GET",headers:a,timeout:{request:f},throwHttpErrors:false,retry:{limit:0},followRedirect:true,isStream:true,proxyUrl:c,sessionToken:t.sessionToken,headerGeneratorOptions:t.headerGeneratorOptions,useHeaderGenerator:t.useHeaderGenerator,insecureHTTPParser:t.insecureHTTPParser,cookieJar:t.cookieJar,http2:t.http2,https:t.https,decompress:t.decompress,context:t.context,...Object.fromEntries(Object.entries(t).filter(([p])=>!["method","headers","timeout","data","json","params","searchParams","signal","relayMode","responseType","baseURL","prefixUrl","proxyUrl","proxyList","onDownloadProgress","onUploadProgress","cookies","httpAgent","httpsAgent","transformRequest","transformResponse","sessionToken","headerGeneratorOptions","useHeaderGenerator","insecureHTTPParser","cookieJar","http2","https","decompress","context"].includes(p)))};for(let p in u)u[p]===void 0&&delete u[p];t.data?typeof t.data=="string"||Buffer.isBuffer(t.data)?u.body=t.data:t.data instanceof Uint8Array?u.body=Buffer.from(t.data):u.json=t.data:t.json&&(u.json=t.json);let l=t.params||t.searchParams;l&&(u.searchParams=l),(t.httpAgent||t.httpsAgent)&&(u.agent={http:t.httpAgent?t.stealth!==false?new A(t.httpAgent):t.httpAgent:void 0,https:t.httpsAgent?t.stealth!==false?new A(t.httpsAgent):t.httpsAgent:void 0});let d;try{d=r.stream(i,u);}catch(p){return o(p)}t.onDownloadProgress&&d.on("downloadProgress",p=>t.onDownloadProgress(p)),t.onUploadProgress&&d.on("uploadProgress",p=>t.onUploadProgress(p)),t.signal&&t.signal.addEventListener("abort",()=>{d.destroy(),o(new C("Request aborted by user signal",0,"ERR_ABORTED",t));}),d.on("response",async p=>{let g=p.statusCode,H=p.headers;if(s.type==="edge"&&[502,504,524].includes(g))return d.destroy(),o(new C("Worker Node Exhausted",g,"ERR_EDGE_OOM",t,void 0,"Edge Timeout",H));if(dt(g,H))return d.destroy(),o(new C("WAF Block Detected or Rate Limited",g,"ERR_WAF_BLOCK",t,void 0,"WAF Execution Blocked",H));let _=null,x=null,ne=(H["content-type"]||"").toLowerCase(),be=parseInt(H["content-length"]||"0",10),ae=ne.match(/(audio|video|image|application\/(zip|octet-stream|x-rar))/i)||be>5*1024*1024;if(ne.includes("text/html")&&!ae&&g===200)try{_=await O(d);let h=_.toString("utf-8",0,8e3);if(h.includes("_cf_chl_opt")||h.includes("Just a moment...")||h.includes("cf-please-wait")||h.includes("DataDome"))return o(new C("WAF Challenge (Status 200) Detected",200,"ERR_WAF_BLOCK",t,void 0,h,H))}catch{return o(new C("Failed to read response stream",g,"ERR_NETWORK",t))}let b=_?Readable.from(_):d.pipe(new PassThrough),S={status:g,statusCode:g,headers:H,stream:b,data:null,body:null,async buffer(){return _||(_=await O(b),_)},async text(){return (await this.buffer()).toString("utf-8")},async json(){let h=await this.text();try{return JSON.parse(h)}catch{return h}},$(){if(!_&&!x&&t.responseType!=="cheerio")throw new C("Data not loaded. Set { responseType: 'cheerio' } or wait for text() resolution.");let h=_?_.toString("utf-8"):typeof x=="string"?x:"";return oe.load(h)}};if(t.responseType==="stream"||ae)S.data=b,S.body=S.data,n(S);else if(t.responseType==="buffer"||t.responseType==="arraybuffer")try{let h=_||await O(b);_=h,S.data=h,S.body=S.data,n(S);}catch(h){o(h);}else if(t.responseType==="cheerio")try{let h=_||await O(b);_=h,S.data=oe.load(h.toString("utf-8")),S.body=S.data,n(S);}catch(h){o(h);}else try{let h=_||await O(b);_=h;let q=h.toString("utf-8");try{x=JSON.parse(q);}catch{x=q;}S.data=x,S.body=x,n(S);}catch(h){o(h);}}),d.on("error",p=>{o(new C(p.message,0,"ERR_NETWORK",t));});})}var mt=r=>new Promise(e=>setTimeout(e,r));async function Ce(r,e,t={}){let s=lt(),n=[],o=t.responseType==="stream"||t.responseType==="buffer"||t.responseType==="arraybuffer";t.relayMode!=="always"&&n.push({type:"local"}),t.proxyList&&Array.isArray(t.proxyList)&&t.proxyList.forEach(l=>n.push({type:"proxy",url:l})),t.relayMode!=="never"&&(!o||t.relayMode==="always")&&s.forEach(l=>n.push({type:"edge",url:l}));let a,i,c=t.smartRetry===false?1:3,f=typeof t.timeout=="number"?t.timeout:t.timeout?.request||12e4,u=Date.now();for(let l of n)for(let d=1;d<=c;d++){if(Date.now()-u>f)throw new C("Global request timeout exceeded during failover retries.",408,"ERR_GLOBAL_TIMEOUT",t);try{return await ft(r,e,t,l)}catch(p){if(i=p,p instanceof C){if(p.code==="ERR_WAF_BLOCK"){a||(a=p);break}if(p.code==="ERR_EDGE_OOM")throw a?(a.hint="The requested file seems too large to buffer via Edge Nodes. Try `{ responseType: 'stream' }` to download it successfully.",a):p;if((p.code==="ERR_NETWORK"||[502,503,504].includes(p.status||0))&&d<c){await mt(1e3*Math.pow(2,d));continue}if(p.code!=="ERR_WAF_BLOCK"&&p.code!=="ERR_NETWORK")throw p}else throw p;break}}throw a||new C(`All execution nodes and proxies exhausted. Last error: ${i?.message||"Unreachable or Blocked"}`,i?.status||500,"ERR_EXHAUSTED",t,void 0,i?.response?.data,i?.response?.headers)}var Ee=[Y,K],Re=[F,W,ee,J,te,re],He=[se],M=got$1.extend({handlers:[B],mutableDefaults:true,http2:true,https:{rejectUnauthorized:false},throwHttpErrors:false,timeout:{request:6e4},retry:{limit:0},headers:{"user-agent":void 0},context:{insecureHTTPParser:true,stealth:true},agent:{http:new A(v.globalAgent),https:new A(pe.globalAgent)},hooks:{init:Ee,beforeRequest:Re,beforeRedirect:He}}),Hr={init:Ee,beforeRequest:Re,beforeRedirect:He,fixDecompress:B,insecureParserHook:F,sessionDataHook:W,http2Hook:ee,proxyHook:J,browserHeadersHook:te,tlsHook:re,optionsValidationHandler:Y,customOptionsHook:K,refererHook:se},$=class{handlers=new Map;idCounter=0;use(e,t){let s=this.idCounter++;return this.handlers.set(s,{fulfilled:e,rejected:t}),s}eject(e){this.handlers.delete(e);}clear(){this.handlers.clear();}forEach(e){this.handlers.forEach(e);}},G={request:new $,response:new $};async function E(r,e={}){e.transformRequest&&(Array.isArray(e.transformRequest)?e.transformRequest:[e.transformRequest]).forEach(n=>{e.data=n(e.data,e.headers||{});});let t=Promise.resolve(e);return G.request.forEach(s=>{s&&(t=t.then(s.fulfilled,s.rejected));}),t=t.then(s=>Ce(M,r,s)),G.response.forEach(s=>{s&&(t=t.then(s.fulfilled,s.rejected));}),t=t.then(s=>(e.transformResponse&&s&&s.data&&typeof s.data!="string"&&(!s.stream||typeof s.data=="object"&&!Buffer.isBuffer(s.data))&&(Array.isArray(e.transformResponse)?e.transformResponse:[e.transformResponse]).forEach(o=>{s.data=o(s.data,s.headers||{}),s.body=s.data;}),s)),t}var xe=Object.assign((r,e)=>E(r,e),{get:(r,e)=>E(r,{...e,method:"GET"}),post:(r,e,t)=>E(r,{...t,data:e,method:"POST"}),put:(r,e,t)=>E(r,{...t,data:e,method:"PUT"}),delete:(r,e)=>E(r,{...e,method:"DELETE"}),patch:(r,e,t)=>E(r,{...t,data:e,method:"PATCH"}),head:(r,e)=>E(r,{...e,method:"HEAD"}),interceptors:G,native:M,paginate:M.paginate,stream:M.stream,create:r=>({get:(e,t)=>E((r.baseURL||"")+e,{...r,...t,method:"GET"}),post:(e,t,s)=>E((r.baseURL||"")+e,{...r,...s,data:t,method:"POST"}),put:(e,t,s)=>E((r.baseURL||"")+e,{...r,...s,data:t,method:"PUT"}),delete:(e,t)=>E((r.baseURL||"")+e,{...r,...t,method:"DELETE"}),patch:(e,t,s)=>E((r.baseURL||"")+e,{...r,...s,data:t,method:"PATCH"}),head:(e,t)=>E((r.baseURL||"")+e,{...r,...t,method:"HEAD"}),interceptors:G}),extend:r=>xe.create({baseURL:r.prefixUrl,...r})});var xr=xe;export{w as ProxyError,C as RanuxError,A as TransformHeadersAgent,xr as default,he as getAgents,M as gotScraping,Hr as hooks,xe as ranux};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ranux-fetcher",
3
- "version": "1.0.0",
4
- "description": "Universal Advanced HTTP & Scraping Client with Smart Proxy Pool Rotation and 4-Node Cloudflare Edge Fallback. Drop-in replacement for Axios and got-scraping.",
3
+ "version": "1.0.2",
4
+ "description": "Universal Advanced HTTP & Scraping Client with Smart Proxy Pool Rotation, Chrome 151 JA4/Kyber768 Stealth Engine, Zstd Decompression, and 4-Node Cloudflare Edge Fallback. Drop-in replacement for Axios and got-scraping.",
5
5
  "keywords": [
6
6
  "scraping",
7
7
  "fetch",
@@ -10,10 +10,13 @@
10
10
  "got-scraping",
11
11
  "cloudflare-bypass",
12
12
  "waf-bypass",
13
+ "datadome-bypass",
13
14
  "proxy-rotation",
14
15
  "stream-downloader",
15
16
  "http2",
16
17
  "tls-fingerprint",
18
+ "ja4",
19
+ "kyber768",
17
20
  "cheerio",
18
21
  "edge-proxy"
19
22
  ],
@@ -41,12 +44,13 @@
41
44
  },
42
45
  "dependencies": {
43
46
  "cheerio": "^1.2.0",
47
+ "fzstd": "^0.1.1",
44
48
  "got": "^14.2.1",
45
- "header-generator": "^2.1.88",
46
49
  "http2-wrapper": "^2.2.1",
47
50
  "mimic-response": "^4.0.0",
48
51
  "ow": "^3.1.1",
49
52
  "quick-lru": "^7.3.0",
53
+ "tough-cookie": "^5.0.0",
50
54
  "tslib": "^2.6.2"
51
55
  },
52
56
  "devDependencies": {
@@ -54,4 +58,4 @@
54
58
  "tsup": "^8.5.1",
55
59
  "typescript": "^5.5.0"
56
60
  }
57
- }
61
+ }