rezo 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +1507 -0
  3. package/assets/icon.svg +37 -0
  4. package/assets/logo-dark.svg +47 -0
  5. package/assets/logo.svg +58 -0
  6. package/dist/adapters/curl.cjs +1034 -0
  7. package/dist/adapters/curl.js +1031 -0
  8. package/dist/adapters/entries/curl.cjs +4 -0
  9. package/dist/adapters/entries/curl.d.ts +2136 -0
  10. package/dist/adapters/entries/curl.js +2 -0
  11. package/dist/adapters/entries/fetch.cjs +2 -0
  12. package/dist/adapters/entries/fetch.d.ts +2127 -0
  13. package/dist/adapters/entries/fetch.js +1 -0
  14. package/dist/adapters/entries/http.cjs +2 -0
  15. package/dist/adapters/entries/http.d.ts +2126 -0
  16. package/dist/adapters/entries/http.js +1 -0
  17. package/dist/adapters/entries/http2.cjs +4 -0
  18. package/dist/adapters/entries/http2.d.ts +2136 -0
  19. package/dist/adapters/entries/http2.js +2 -0
  20. package/dist/adapters/entries/react-native.cjs +2 -0
  21. package/dist/adapters/entries/react-native.d.ts +2126 -0
  22. package/dist/adapters/entries/react-native.js +1 -0
  23. package/dist/adapters/entries/xhr.cjs +2 -0
  24. package/dist/adapters/entries/xhr.d.ts +2127 -0
  25. package/dist/adapters/entries/xhr.js +1 -0
  26. package/dist/adapters/fetch.cjs +740 -0
  27. package/dist/adapters/fetch.js +739 -0
  28. package/dist/adapters/http.cjs +1153 -0
  29. package/dist/adapters/http.js +1151 -0
  30. package/dist/adapters/http2.cjs +957 -0
  31. package/dist/adapters/http2.js +956 -0
  32. package/dist/adapters/index.cjs +6 -0
  33. package/dist/adapters/index.js +7 -0
  34. package/dist/adapters/picker.cjs +342 -0
  35. package/dist/adapters/picker.js +331 -0
  36. package/dist/adapters/react-native.cjs +545 -0
  37. package/dist/adapters/react-native.js +544 -0
  38. package/dist/adapters/xhr.cjs +622 -0
  39. package/dist/adapters/xhr.js +621 -0
  40. package/dist/cache/dns-cache.cjs +118 -0
  41. package/dist/cache/dns-cache.js +113 -0
  42. package/dist/cache/file-cacher.cjs +264 -0
  43. package/dist/cache/file-cacher.js +261 -0
  44. package/dist/cache/index.cjs +13 -0
  45. package/dist/cache/index.js +5 -0
  46. package/dist/cache/lru-cache.cjs +96 -0
  47. package/dist/cache/lru-cache.js +93 -0
  48. package/dist/cache/response-cache.cjs +314 -0
  49. package/dist/cache/response-cache.js +310 -0
  50. package/dist/cache/url-store.cjs +288 -0
  51. package/dist/cache/url-store.js +285 -0
  52. package/dist/core/hooks.cjs +133 -0
  53. package/dist/core/hooks.js +120 -0
  54. package/dist/core/rezo.cjs +464 -0
  55. package/dist/core/rezo.js +458 -0
  56. package/dist/crawler.d.ts +6255 -0
  57. package/dist/dom/index.cjs +1 -0
  58. package/dist/dom/index.d.ts +23 -0
  59. package/dist/dom/index.js +1 -0
  60. package/dist/entries/crawler.cjs +5 -0
  61. package/dist/entries/crawler.js +2 -0
  62. package/dist/errors/rezo-error.cjs +722 -0
  63. package/dist/errors/rezo-error.js +716 -0
  64. package/dist/index.cjs +34 -0
  65. package/dist/index.d.ts +3335 -0
  66. package/dist/index.js +26 -0
  67. package/dist/platform/browser.cjs +9 -0
  68. package/dist/platform/browser.d.ts +3203 -0
  69. package/dist/platform/browser.js +7 -0
  70. package/dist/platform/bun.cjs +9 -0
  71. package/dist/platform/bun.d.ts +3203 -0
  72. package/dist/platform/bun.js +7 -0
  73. package/dist/platform/deno.cjs +9 -0
  74. package/dist/platform/deno.d.ts +3203 -0
  75. package/dist/platform/deno.js +7 -0
  76. package/dist/platform/node.cjs +9 -0
  77. package/dist/platform/node.d.ts +3203 -0
  78. package/dist/platform/node.js +7 -0
  79. package/dist/platform/react-native.cjs +9 -0
  80. package/dist/platform/react-native.d.ts +3203 -0
  81. package/dist/platform/react-native.js +7 -0
  82. package/dist/platform/worker.cjs +9 -0
  83. package/dist/platform/worker.d.ts +3203 -0
  84. package/dist/platform/worker.js +7 -0
  85. package/dist/plugin/addon/decodo/index.cjs +1 -0
  86. package/dist/plugin/addon/decodo/index.js +1 -0
  87. package/dist/plugin/addon/decodo/options.cjs +1 -0
  88. package/dist/plugin/addon/decodo/options.js +1 -0
  89. package/dist/plugin/addon/oxylabs/index.cjs +1 -0
  90. package/dist/plugin/addon/oxylabs/index.js +1 -0
  91. package/dist/plugin/addon/oxylabs/options.cjs +1 -0
  92. package/dist/plugin/addon/oxylabs/options.js +1 -0
  93. package/dist/plugin/crawler-options.cjs +1 -0
  94. package/dist/plugin/crawler-options.js +1 -0
  95. package/dist/plugin/crawler.cjs +519 -0
  96. package/dist/plugin/crawler.js +517 -0
  97. package/dist/plugin/index.cjs +36 -0
  98. package/dist/plugin/index.js +32 -0
  99. package/dist/proxy/index.cjs +142 -0
  100. package/dist/proxy/index.js +139 -0
  101. package/dist/responses/buildError.cjs +452 -0
  102. package/dist/responses/buildError.js +441 -0
  103. package/dist/responses/buildResponse.cjs +365 -0
  104. package/dist/responses/buildResponse.js +361 -0
  105. package/dist/responses/download.cjs +54 -0
  106. package/dist/responses/download.js +52 -0
  107. package/dist/responses/stream.cjs +60 -0
  108. package/dist/responses/stream.js +58 -0
  109. package/dist/responses/upload.cjs +54 -0
  110. package/dist/responses/upload.js +52 -0
  111. package/dist/types/cookies.cjs +394 -0
  112. package/dist/types/cookies.js +391 -0
  113. package/dist/types/download.cjs +10 -0
  114. package/dist/types/download.js +10 -0
  115. package/dist/types/rezo-request.cjs +131 -0
  116. package/dist/types/rezo-request.js +131 -0
  117. package/dist/utils/agent-merger.cjs +111 -0
  118. package/dist/utils/agent-merger.js +108 -0
  119. package/dist/utils/compression.cjs +84 -0
  120. package/dist/utils/compression.js +82 -0
  121. package/dist/utils/cookies.cjs +514 -0
  122. package/dist/utils/cookies.js +511 -0
  123. package/dist/utils/data-operations.cjs +75 -0
  124. package/dist/utils/data-operations.js +73 -0
  125. package/dist/utils/form-data.cjs +164 -0
  126. package/dist/utils/form-data.js +161 -0
  127. package/dist/utils/headers.cjs +162 -0
  128. package/dist/utils/headers.js +161 -0
  129. package/dist/utils/http-config.cjs +723 -0
  130. package/dist/utils/http-config.js +718 -0
  131. package/dist/utils/index.cjs +8 -0
  132. package/dist/utils/index.js +8 -0
  133. package/dist/utils/tools.cjs +18 -0
  134. package/dist/utils/tools.js +15 -0
  135. package/package.json +172 -0
package/README.md ADDED
@@ -0,0 +1,1507 @@
1
+ <p align="center">
2
+ <img src="assets/logo.svg" alt="Rezo HTTP Client" width="400">
3
+ </p>
4
+
5
+ <h1 align="center">Rezo HTTP Client</h1>
6
+
7
+ <p align="center">
8
+ <strong>Lightning-fast, enterprise-grade HTTP client for modern JavaScript</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="#installation">Installation</a> •
13
+ <a href="#quick-start">Quick Start</a> •
14
+ <a href="#features">Features</a> •
15
+ <a href="#api-reference">API Reference</a> •
16
+ <a href="#adapters">Adapters</a> •
17
+ <a href="#advanced-usage">Advanced Usage</a> •
18
+ <a href="#migration-guide">Migration</a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <img src="https://img.shields.io/npm/v/rezo?style=flat-square&color=00D4FF" alt="npm version">
23
+ <img src="https://img.shields.io/npm/dm/rezo?style=flat-square&color=0099FF" alt="npm downloads">
24
+ <img src="https://img.shields.io/bundlephobia/minzip/rezo?style=flat-square&color=0066CC" alt="bundle size">
25
+ <img src="https://img.shields.io/npm/l/rezo?style=flat-square&color=00D4FF" alt="license">
26
+ <img src="https://img.shields.io/node/v/rezo?style=flat-square&color=0099FF" alt="node version">
27
+ </p>
28
+
29
+ ---
30
+
31
+ ## Overview
32
+
33
+ Rezo is a production-ready HTTP client library engineered for Node.js 22+ and universal JavaScript runtimes. Built from the ground up with TypeScript, Rezo delivers exceptional performance, comprehensive feature coverage, and seamless cross-environment compatibility.
34
+
35
+ **Why Rezo?**
36
+
37
+ - **Lightning Fast**: Native HTTP/2 multiplexing, connection pooling, and optimized stream handling
38
+ - **Universal**: Works seamlessly across Node.js, Bun, Deno, browsers, React Native, and edge runtimes
39
+ - **Type-Safe**: First-class TypeScript support with comprehensive type definitions
40
+ - **Enterprise Ready**: Advanced cookie management, proxy support, retry logic, and error handling
41
+ - **Tree-Shakeable**: Modular architecture enables optimal bundle sizes
42
+ - **Production Proven**: Battle-tested in high-throughput enterprise applications
43
+
44
+ ---
45
+
46
+ ## Table of Contents
47
+
48
+ - [Installation](#installation)
49
+ - [Quick Start](#quick-start)
50
+ - [Features](#features)
51
+ - [Adapters](#adapters)
52
+ - [HTTP Adapter](#http-adapter)
53
+ - [HTTP/2 Adapter](#http2-adapter)
54
+ - [Fetch Adapter](#fetch-adapter)
55
+ - [cURL Adapter](#curl-adapter)
56
+ - [XHR Adapter](#xhr-adapter)
57
+ - [React Native Adapter](#react-native-adapter)
58
+ - [API Reference](#api-reference)
59
+ - [Request Methods](#request-methods)
60
+ - [Request Configuration](#request-configuration)
61
+ - [Response Schema](#response-schema)
62
+ - [Instance Methods](#instance-methods)
63
+ - [Advanced Usage](#advanced-usage)
64
+ - [Cookie Management](#cookie-management)
65
+ - [Proxy Configuration](#proxy-configuration)
66
+ - [Streaming](#streaming)
67
+ - [File Downloads](#file-downloads)
68
+ - [File Uploads](#file-uploads)
69
+ - [Hooks & Interceptors](#hooks--interceptors)
70
+ - [Retry Logic](#retry-logic)
71
+ - [Error Handling](#error-handling)
72
+ - [Performance Metrics](#performance-metrics)
73
+ - [Platform Support](#platform-support)
74
+ - [Migration Guide](#migration-guide)
75
+ - [TypeScript](#typescript)
76
+ - [Crawler Module](#crawler-module)
77
+ - [DOM Module](#dom-module)
78
+ - [Troubleshooting](#troubleshooting)
79
+ - [Contributing](#contributing)
80
+ - [License](#license)
81
+
82
+ ---
83
+
84
+ ## Installation
85
+
86
+ ### npm
87
+
88
+ ```bash
89
+ npm install rezo
90
+ ```
91
+
92
+ ### Yarn
93
+
94
+ ```bash
95
+ yarn add rezo
96
+ ```
97
+
98
+ ### pnpm
99
+
100
+ ```bash
101
+ pnpm add rezo
102
+ ```
103
+
104
+ ### Bun
105
+
106
+ ```bash
107
+ bun add rezo
108
+ ```
109
+
110
+ ### Requirements
111
+
112
+ - **Node.js**: 22.0.0 or higher
113
+ - **Bun**: 1.0.0 or higher
114
+ - **Deno**: 1.40.0 or higher (with Node.js compatibility)
115
+
116
+ ---
117
+
118
+ ## Quick Start
119
+
120
+ ### Basic GET Request
121
+
122
+ ```typescript
123
+ import rezo from 'rezo';
124
+
125
+ // Simple GET request
126
+ const response = await rezo.get('https://api.example.com/users');
127
+ console.log(response.data);
128
+
129
+ // With query parameters
130
+ const users = await rezo.get('https://api.example.com/users', {
131
+ params: { page: 1, limit: 10 }
132
+ });
133
+ ```
134
+
135
+ ### POST Request with JSON
136
+
137
+ ```typescript
138
+ import rezo from 'rezo';
139
+
140
+ const response = await rezo.post('https://api.example.com/users', {
141
+ name: 'John Doe',
142
+ email: 'john@example.com'
143
+ });
144
+
145
+ console.log(response.data);
146
+ console.log(response.status); // 201
147
+ ```
148
+
149
+ ### Creating an Instance
150
+
151
+ ```typescript
152
+ import rezo from 'rezo';
153
+
154
+ const api = rezo.create({
155
+ baseURL: 'https://api.example.com',
156
+ timeout: 30000,
157
+ headers: {
158
+ 'Authorization': 'Bearer your-token',
159
+ 'Content-Type': 'application/json'
160
+ }
161
+ });
162
+
163
+ // All requests will use the base configuration
164
+ const users = await api.get('/users');
165
+ const user = await api.post('/users', { name: 'Jane Doe' });
166
+ ```
167
+
168
+ ### CommonJS Usage
169
+
170
+ ```javascript
171
+ const rezo = require('rezo').default;
172
+
173
+ // Using default instance
174
+ rezo.get('https://api.example.com/data')
175
+ .then(response => console.log(response.data))
176
+ .catch(error => console.error(error));
177
+
178
+ // Creating custom instance
179
+ const client = rezo.create({ baseURL: 'https://api.example.com' });
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Features
185
+
186
+ ### Core Capabilities
187
+
188
+ | Feature | Description |
189
+ |---------|-------------|
190
+ | **HTTP/1.1 & HTTP/2** | Full support for both protocols with automatic negotiation |
191
+ | **All HTTP Methods** | GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE |
192
+ | **Request Body Types** | JSON, FormData, URLSearchParams, Streams, Buffers |
193
+ | **Response Types** | JSON, Text, ArrayBuffer, Blob, Streams |
194
+ | **Automatic Transforms** | JSON parsing, content-type detection, compression handling |
195
+ | **Query Parameters** | Automatic URL encoding and serialization |
196
+ | **Request Cancellation** | AbortController support for request cancellation |
197
+
198
+ ### Network Features
199
+
200
+ | Feature | Description |
201
+ |---------|-------------|
202
+ | **Cookie Management** | RFC 6265 compliant cookie jar with persistence |
203
+ | **Proxy Support** | HTTP, HTTPS, SOCKS4, and SOCKS5 proxies |
204
+ | **TLS/SSL** | Custom certificates, client certs, certificate pinning |
205
+ | **Compression** | Automatic gzip, deflate, brotli, and zstd handling |
206
+ | **Connection Pooling** | Reusable connections for improved performance |
207
+ | **Keep-Alive** | Persistent connections with configurable timeouts |
208
+
209
+ ### Enterprise Features
210
+
211
+ | Feature | Description |
212
+ |---------|-------------|
213
+ | **Retry Logic** | Configurable retry with exponential backoff |
214
+ | **Timeout Control** | Connection, request, and total timeout options |
215
+ | **Rate Limiting** | Request queue with priority and concurrency control |
216
+ | **Hooks System** | Lifecycle hooks for request/response interception |
217
+ | **Error Handling** | Structured errors with actionable suggestions |
218
+ | **Performance Metrics** | Detailed timing data for monitoring |
219
+
220
+ ### Developer Experience
221
+
222
+ | Feature | Description |
223
+ |---------|-------------|
224
+ | **TypeScript First** | Comprehensive type definitions and generics |
225
+ | **Tree-Shakeable** | Modular exports for optimal bundle size |
226
+ | **Zero Config** | Works out of the box with sensible defaults |
227
+ | **Extensive Logging** | Debug mode for troubleshooting |
228
+ | **Cross-Platform** | Node.js, Bun, Deno, browsers, React Native, edge |
229
+
230
+ ---
231
+
232
+ ## Adapters
233
+
234
+ Rezo uses a pluggable adapter architecture, allowing you to choose the optimal HTTP implementation for your environment and requirements.
235
+
236
+ ### Automatic Adapter Selection
237
+
238
+ By default, Rezo automatically selects the best adapter based on your runtime environment:
239
+
240
+ | Environment | Default Adapter |
241
+ |-------------|-----------------|
242
+ | Node.js | HTTP Adapter |
243
+ | Bun | HTTP Adapter |
244
+ | Deno | HTTP Adapter |
245
+ | Browser | Fetch Adapter |
246
+ | Cloudflare Workers | Fetch Adapter |
247
+ | React Native | React Native Adapter |
248
+
249
+ ### HTTP Adapter
250
+
251
+ The full-featured adapter for Node.js environments with complete cookie, proxy, and streaming support.
252
+
253
+ ```typescript
254
+ import rezo from 'rezo/adapters/http';
255
+
256
+ const response = await rezo.get('https://api.example.com/data');
257
+ ```
258
+
259
+ **Features:**
260
+ - Full cookie jar support with persistence
261
+ - HTTP/HTTPS/SOCKS proxy support
262
+ - Streaming request and response bodies
263
+ - All compression algorithms
264
+ - Custom TLS configuration
265
+ - Connection keep-alive
266
+
267
+ ### HTTP/2 Adapter
268
+
269
+ Native HTTP/2 support with session multiplexing for maximum performance.
270
+
271
+ ```typescript
272
+ import rezo from 'rezo/adapters/http2';
273
+
274
+ const response = await rezo.get('https://api.example.com/data');
275
+ ```
276
+
277
+ **Features:**
278
+ - HTTP/2 multiplexing (multiple requests over single connection)
279
+ - Automatic session pooling and reuse
280
+ - ALPN protocol negotiation
281
+ - Falls back to HTTP/1.1 when needed
282
+ - Server push support
283
+ - Header compression (HPACK)
284
+
285
+ ### Fetch Adapter
286
+
287
+ Lightweight adapter using the native Fetch API, ideal for browsers and edge runtimes.
288
+
289
+ ```typescript
290
+ import rezo from 'rezo/adapters/fetch';
291
+
292
+ const response = await rezo.get('https://api.example.com/data');
293
+ ```
294
+
295
+ **Features:**
296
+ - Minimal bundle size
297
+ - Native browser support
298
+ - Edge runtime compatible (Cloudflare Workers, Vercel Edge)
299
+ - Streaming response bodies
300
+ - AbortController integration
301
+
302
+ ### cURL Adapter
303
+
304
+ Advanced adapter wrapping the cURL command-line tool for maximum compatibility and debugging.
305
+
306
+ ```typescript
307
+ import rezo from 'rezo/adapters/curl';
308
+
309
+ const response = await rezo.get('https://api.example.com/data', {
310
+ curl: {
311
+ verbose: true,
312
+ insecure: false
313
+ }
314
+ });
315
+ ```
316
+
317
+ **Features:**
318
+ - 200+ cURL options available
319
+ - Advanced authentication (Basic, Digest, NTLM, Negotiate)
320
+ - Connection pooling
321
+ - Detailed timing information
322
+ - Perfect for debugging and testing
323
+
324
+ ### XHR Adapter
325
+
326
+ Legacy browser support using XMLHttpRequest for maximum compatibility.
327
+
328
+ ```typescript
329
+ import rezo from 'rezo/adapters/xhr';
330
+
331
+ const response = await rezo.get('https://api.example.com/data');
332
+ ```
333
+
334
+ **Features:**
335
+ - Legacy browser support (IE11+)
336
+ - Upload progress events
337
+ - Download progress events
338
+ - Synchronous request option
339
+ - Cross-origin request handling
340
+
341
+ ### React Native Adapter
342
+
343
+ Optimized adapter for React Native mobile applications.
344
+
345
+ ```typescript
346
+ import rezo from 'rezo/adapters/react-native';
347
+
348
+ const response = await rezo.get('https://api.example.com/data');
349
+ ```
350
+
351
+ **Features:**
352
+ - Optimized for mobile networks
353
+ - File download support (react-native-fs)
354
+ - Manual cookie header management
355
+ - Background fetch support
356
+ - Network state awareness
357
+
358
+ ---
359
+
360
+ ## API Reference
361
+
362
+ ### Request Methods
363
+
364
+ Rezo provides convenient methods for all standard HTTP verbs:
365
+
366
+ ```typescript
367
+ // GET request
368
+ rezo.get(url[, config])
369
+
370
+ // POST request
371
+ rezo.post(url[, data[, config]])
372
+
373
+ // PUT request
374
+ rezo.put(url[, data[, config]])
375
+
376
+ // PATCH request
377
+ rezo.patch(url[, data[, config]])
378
+
379
+ // DELETE request
380
+ rezo.delete(url[, config])
381
+
382
+ // HEAD request
383
+ rezo.head(url[, config])
384
+
385
+ // OPTIONS request
386
+ rezo.options(url[, config])
387
+
388
+ // Generic request
389
+ rezo.request(config)
390
+ ```
391
+
392
+ ### Convenience Methods
393
+
394
+ Rezo provides specialized methods for common content types:
395
+
396
+ ```typescript
397
+ // JSON POST with automatic Content-Type header
398
+ rezo.postJson(url, data[, config])
399
+
400
+ // Form-encoded POST
401
+ rezo.postForm(url, data[, config])
402
+
403
+ // Multipart form data POST
404
+ rezo.postMultipart(url, data[, config])
405
+
406
+ // Same patterns available for PUT and PATCH
407
+ rezo.putJson(url, data[, config])
408
+ rezo.patchJson(url, data[, config])
409
+ ```
410
+
411
+ ### Request Configuration
412
+
413
+ ```typescript
414
+ interface RezoConfig {
415
+ // URL and Method
416
+ url?: string;
417
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
418
+ baseURL?: string;
419
+
420
+ // Request Data
421
+ params?: Record<string, any>;
422
+ data?: any;
423
+ headers?: RezoHeaders | Record<string, string>;
424
+
425
+ // Timeouts (in milliseconds)
426
+ timeout?: number;
427
+ connectTimeout?: number;
428
+ requestTimeout?: number;
429
+
430
+ // Response Handling
431
+ responseType?: 'json' | 'text' | 'arraybuffer' | 'blob' | 'stream';
432
+ responseEncoding?: string;
433
+ validateStatus?: (status: number) => boolean;
434
+ maxContentLength?: number;
435
+ maxBodyLength?: number;
436
+
437
+ // Redirects
438
+ maxRedirects?: number;
439
+ followRedirect?: boolean;
440
+
441
+ // Authentication
442
+ auth?: {
443
+ username: string;
444
+ password: string;
445
+ };
446
+
447
+ // Proxy Configuration
448
+ proxy?: {
449
+ protocol?: 'http' | 'https' | 'socks4' | 'socks5';
450
+ host: string;
451
+ port: number;
452
+ auth?: {
453
+ username: string;
454
+ password: string;
455
+ };
456
+ };
457
+
458
+ // TLS/SSL
459
+ httpsAgent?: any;
460
+ rejectUnauthorized?: boolean;
461
+ ca?: string | Buffer;
462
+ cert?: string | Buffer;
463
+ key?: string | Buffer;
464
+
465
+ // Advanced
466
+ decompress?: boolean;
467
+ signal?: AbortSignal;
468
+ onUploadProgress?: (progressEvent: ProgressEvent) => void;
469
+ onDownloadProgress?: (progressEvent: ProgressEvent) => void;
470
+
471
+ // Retry Configuration
472
+ retry?: {
473
+ limit?: number;
474
+ delay?: number;
475
+ maxDelay?: number;
476
+ backoff?: number;
477
+ retryOn?: number[] | ((error: Error, attempt: number) => boolean);
478
+ };
479
+
480
+ // Cookies
481
+ jar?: CookieJar;
482
+ withCredentials?: boolean;
483
+ }
484
+ ```
485
+
486
+ ### Response Schema
487
+
488
+ ```typescript
489
+ interface RezoResponse<T = any> {
490
+ // Response data (automatically parsed based on content-type)
491
+ data: T;
492
+
493
+ // HTTP status
494
+ status: number;
495
+ statusText: string;
496
+
497
+ // Response headers (case-insensitive access)
498
+ headers: RezoHeaders;
499
+
500
+ // Request configuration used
501
+ config: RezoConfig;
502
+
503
+ // The request that generated this response
504
+ request: any;
505
+
506
+ // Timing metrics (when available)
507
+ timing?: {
508
+ start: number;
509
+ dns: number;
510
+ connect: number;
511
+ tls: number;
512
+ firstByte: number;
513
+ download: number;
514
+ total: number;
515
+ };
516
+ }
517
+ ```
518
+
519
+ ### Instance Methods
520
+
521
+ ```typescript
522
+ const instance = rezo.create(config);
523
+
524
+ // Request methods
525
+ instance.get(url, config?)
526
+ instance.post(url, data?, config?)
527
+ instance.put(url, data?, config?)
528
+ instance.patch(url, data?, config?)
529
+ instance.delete(url, config?)
530
+ instance.head(url, config?)
531
+ instance.options(url, config?)
532
+ instance.request(config)
533
+
534
+ // Instance configuration
535
+ instance.defaults // Access default configuration
536
+ instance.getUri(config) // Get the full URL
537
+
538
+ // Cookie management
539
+ instance.jar // Access the cookie jar
540
+ instance.getCookies(url)
541
+ instance.setCookie(cookie, url)
542
+ instance.clearCookies()
543
+
544
+ // Hooks
545
+ instance.hooks.beforeRequest.push(handler)
546
+ instance.hooks.afterResponse.push(handler)
547
+ instance.hooks.beforeRetry.push(handler)
548
+ instance.hooks.beforeError.push(handler)
549
+ ```
550
+
551
+ ---
552
+
553
+ ## Advanced Usage
554
+
555
+ ### Cookie Management
556
+
557
+ Rezo provides RFC 6265 compliant cookie management with automatic persistence. The default instance already has a built-in cookie jar - no configuration required.
558
+
559
+ ```typescript
560
+ import rezo from 'rezo';
561
+
562
+ // Cookies work automatically with the default instance
563
+ await rezo.post('https://api.example.com/login', { username: 'user', password: 'pass' });
564
+
565
+ // Subsequent requests automatically include session cookies
566
+ const profile = await rezo.get('https://api.example.com/profile');
567
+
568
+ // Access cookies directly from the default instance
569
+ const cookies = rezo.getCookies('https://api.example.com');
570
+ console.log(cookies);
571
+
572
+ // Set cookies manually
573
+ rezo.setCookie('custom=value; Path=/; HttpOnly', 'https://api.example.com');
574
+
575
+ // Clear all cookies
576
+ rezo.clearCookies();
577
+ ```
578
+
579
+ #### Custom Cookie Jar (Optional)
580
+
581
+ Only create your own CookieJar if you need to manage cookies externally or use multiple isolated jars:
582
+
583
+ ```typescript
584
+ import rezo, { CookieJar } from 'rezo';
585
+
586
+ // Custom jar for isolated cookie management
587
+ const myJar = new CookieJar();
588
+
589
+ const client = rezo.create({
590
+ baseURL: 'https://api.example.com',
591
+ jar: myJar
592
+ });
593
+
594
+ // Export cookies to different formats
595
+ const netscapeFormat = myJar.toNetscapeString();
596
+ const setCookieHeaders = myJar.toSetCookieStrings();
597
+ const jsonFormat = myJar.toJSON();
598
+ ```
599
+
600
+ ### Proxy Configuration
601
+
602
+ Rezo provides comprehensive proxy support for HTTP, HTTPS, SOCKS4, and SOCKS5 protocols, enabling secure and anonymous web requests through proxy servers.
603
+
604
+ #### Quick Usage (Per-Request)
605
+
606
+ You can use a proxy directly in any request without creating an instance:
607
+
608
+ ```typescript
609
+ import rezo from 'rezo';
610
+
611
+ // Use proxy for a single request
612
+ const response = await rezo.get('https://api.example.com/data', {
613
+ proxy: {
614
+ protocol: 'http',
615
+ host: 'proxy.example.com',
616
+ port: 8080
617
+ }
618
+ });
619
+ ```
620
+
621
+ #### Proxy Protocols
622
+
623
+ | Protocol | Description | Use Case |
624
+ |----------|-------------|----------|
625
+ | `http` | HTTP proxy (CONNECT method for HTTPS targets) | General-purpose web proxy |
626
+ | `https` | HTTPS proxy (encrypted proxy connection) | Secure corporate proxies |
627
+ | `socks4` | SOCKS4 proxy (TCP connections only) | Legacy proxy servers |
628
+ | `socks5` | SOCKS5 proxy (TCP + UDP, authentication) | Anonymous browsing, Tor |
629
+
630
+ #### Basic HTTP Proxy
631
+
632
+ ```typescript
633
+ import rezo from 'rezo';
634
+
635
+ // HTTP Proxy - routes all traffic through the proxy
636
+ const client = rezo.create({
637
+ proxy: {
638
+ protocol: 'http',
639
+ host: 'proxy.example.com',
640
+ port: 8080
641
+ }
642
+ });
643
+
644
+ const response = await client.get('https://api.example.com/data');
645
+ ```
646
+
647
+ #### HTTPS Proxy
648
+
649
+ ```typescript
650
+ import rezo from 'rezo';
651
+
652
+ // HTTPS Proxy - encrypted connection to proxy server
653
+ const client = rezo.create({
654
+ proxy: {
655
+ protocol: 'https',
656
+ host: 'secure-proxy.example.com',
657
+ port: 443
658
+ }
659
+ });
660
+ ```
661
+
662
+ #### Authenticated Proxy
663
+
664
+ ```typescript
665
+ import rezo from 'rezo';
666
+
667
+ // Proxy with username/password authentication
668
+ const client = rezo.create({
669
+ proxy: {
670
+ protocol: 'http',
671
+ host: 'proxy.example.com',
672
+ port: 8080,
673
+ auth: {
674
+ username: 'proxyuser',
675
+ password: 'proxypass'
676
+ }
677
+ }
678
+ });
679
+ ```
680
+
681
+ #### SOCKS4 Proxy
682
+
683
+ ```typescript
684
+ import rezo from 'rezo';
685
+
686
+ // SOCKS4 Proxy - TCP connections only, no authentication
687
+ const client = rezo.create({
688
+ proxy: {
689
+ protocol: 'socks4',
690
+ host: 'socks4.example.com',
691
+ port: 1080
692
+ }
693
+ });
694
+ ```
695
+
696
+ #### SOCKS5 Proxy
697
+
698
+ ```typescript
699
+ import rezo from 'rezo';
700
+
701
+ // SOCKS5 Proxy - supports TCP, UDP, and authentication
702
+ const client = rezo.create({
703
+ proxy: {
704
+ protocol: 'socks5',
705
+ host: 'socks5.example.com',
706
+ port: 1080
707
+ }
708
+ });
709
+
710
+ // SOCKS5 with authentication
711
+ const authenticatedSocks = rezo.create({
712
+ proxy: {
713
+ protocol: 'socks5',
714
+ host: 'socks5.example.com',
715
+ port: 1080,
716
+ auth: {
717
+ username: 'socksuser',
718
+ password: 'sockspass'
719
+ }
720
+ }
721
+ });
722
+
723
+ // Using Tor network (typically SOCKS5 on port 9050)
724
+ const torClient = rezo.create({
725
+ proxy: {
726
+ protocol: 'socks5',
727
+ host: '127.0.0.1',
728
+ port: 9050
729
+ }
730
+ });
731
+ ```
732
+
733
+ #### Per-Request Proxy Override
734
+
735
+ ```typescript
736
+ import rezo from 'rezo';
737
+
738
+ const client = rezo.create({
739
+ proxy: {
740
+ protocol: 'http',
741
+ host: 'default-proxy.example.com',
742
+ port: 8080
743
+ }
744
+ });
745
+
746
+ // Use a different proxy for this specific request
747
+ await client.get('https://api.example.com/data', {
748
+ proxy: {
749
+ protocol: 'https',
750
+ host: 'different-proxy.example.com',
751
+ port: 443
752
+ }
753
+ });
754
+
755
+ // Disable proxy for specific request (direct connection)
756
+ await client.get('https://internal.example.com/data', {
757
+ proxy: false
758
+ });
759
+ ```
760
+
761
+ #### Proxy Configuration Interface
762
+
763
+ ```typescript
764
+ interface ProxyConfig {
765
+ protocol: 'http' | 'https' | 'socks4' | 'socks5';
766
+ host: string;
767
+ port: number;
768
+ auth?: {
769
+ username: string;
770
+ password: string;
771
+ };
772
+ }
773
+ ```
774
+
775
+ ### Streaming
776
+
777
+ Rezo provides powerful streaming capabilities for handling large data efficiently.
778
+
779
+ ```typescript
780
+ import rezo from 'rezo';
781
+ import { createWriteStream } from 'fs';
782
+
783
+ const client = rezo.create();
784
+
785
+ // Stream response to file
786
+ const response = await client.get('https://example.com/large-file.zip', {
787
+ responseType: 'stream'
788
+ });
789
+
790
+ const writer = createWriteStream('./download.zip');
791
+ response.data.pipe(writer);
792
+
793
+ await new Promise((resolve, reject) => {
794
+ writer.on('finish', resolve);
795
+ writer.on('error', reject);
796
+ });
797
+
798
+ // Stream request body
799
+ import { createReadStream } from 'fs';
800
+
801
+ await client.post('https://api.example.com/upload', createReadStream('./file.txt'), {
802
+ headers: {
803
+ 'Content-Type': 'application/octet-stream'
804
+ }
805
+ });
806
+ ```
807
+
808
+ ### File Downloads
809
+
810
+ Rezo provides a dedicated download API with progress tracking.
811
+
812
+ ```typescript
813
+ import rezo, { DownloadResponse } from 'rezo';
814
+
815
+ const client = rezo.create();
816
+
817
+ // Download with progress
818
+ const download = await client.download('https://example.com/file.zip', {
819
+ outputPath: './downloads/file.zip'
820
+ });
821
+
822
+ download.on('progress', (progress) => {
823
+ console.log(`Downloaded: ${progress.percent}%`);
824
+ console.log(`Speed: ${progress.speed} bytes/sec`);
825
+ console.log(`ETA: ${progress.eta} seconds`);
826
+ });
827
+
828
+ download.on('complete', (result) => {
829
+ console.log('Download complete:', result.path);
830
+ console.log('Total size:', result.size);
831
+ console.log('Duration:', result.duration);
832
+ });
833
+
834
+ download.on('error', (error) => {
835
+ console.error('Download failed:', error.message);
836
+ });
837
+
838
+ // Wait for completion
839
+ await download.finished();
840
+ ```
841
+
842
+ ### File Uploads
843
+
844
+ Upload files with progress tracking and multipart support.
845
+
846
+ ```typescript
847
+ import rezo, { FormData } from 'rezo';
848
+ import { createReadStream } from 'fs';
849
+
850
+ const client = rezo.create();
851
+
852
+ // Simple file upload
853
+ const formData = new FormData();
854
+ formData.append('file', createReadStream('./document.pdf'));
855
+ formData.append('name', 'My Document');
856
+
857
+ const response = await client.post('https://api.example.com/upload', formData, {
858
+ onUploadProgress: (progress) => {
859
+ console.log(`Uploaded: ${Math.round(progress.loaded / progress.total * 100)}%`);
860
+ }
861
+ });
862
+
863
+ // Upload with detailed progress
864
+ const upload = await client.upload('https://api.example.com/upload', {
865
+ file: createReadStream('./large-file.zip'),
866
+ filename: 'archive.zip'
867
+ });
868
+
869
+ upload.on('progress', (progress) => {
870
+ console.log(`Uploaded: ${progress.percent}%`);
871
+ });
872
+
873
+ await upload.finished();
874
+ console.log('Upload complete:', upload.response.data);
875
+ ```
876
+
877
+ ### Hooks & Interceptors
878
+
879
+ Rezo provides a powerful hooks system for request/response interception.
880
+
881
+ ```typescript
882
+ import rezo from 'rezo';
883
+
884
+ const client = rezo.create({
885
+ baseURL: 'https://api.example.com'
886
+ });
887
+
888
+ // Before request hook
889
+ client.hooks.beforeRequest.push((options) => {
890
+ // Add timestamp to all requests
891
+ options.headers['X-Request-Time'] = Date.now().toString();
892
+
893
+ // Log outgoing requests
894
+ console.log(`-> ${options.method} ${options.url}`);
895
+
896
+ return options;
897
+ });
898
+
899
+ // After response hook
900
+ client.hooks.afterResponse.push((response, options) => {
901
+ // Log responses
902
+ console.log(`<- ${response.status} ${options.url}`);
903
+
904
+ // Transform response data
905
+ if (response.data && typeof response.data === 'object') {
906
+ response.data._receivedAt = new Date().toISOString();
907
+ }
908
+
909
+ return response;
910
+ });
911
+
912
+ // Before retry hook
913
+ client.hooks.beforeRetry.push((error, retryCount) => {
914
+ console.log(`Retry attempt ${retryCount} for ${error.config.url}`);
915
+
916
+ // Optionally modify the request before retry
917
+ error.config.headers['X-Retry-Count'] = retryCount.toString();
918
+ });
919
+
920
+ // Before error hook (transform errors)
921
+ client.hooks.beforeError.push((error) => {
922
+ // Add additional context to errors
923
+ error.timestamp = new Date().toISOString();
924
+ error.requestId = error.config?.headers?.['X-Request-ID'];
925
+
926
+ return error;
927
+ });
928
+
929
+ // Authentication refresh example
930
+ client.hooks.afterResponse.push(async (response, options, client) => {
931
+ if (response.status === 401 && !options._retry) {
932
+ // Refresh token
933
+ const refreshResponse = await client.post('/auth/refresh', {
934
+ refreshToken: getRefreshToken()
935
+ });
936
+
937
+ // Update authorization header
938
+ const newToken = refreshResponse.data.accessToken;
939
+ client.defaults.headers['Authorization'] = `Bearer ${newToken}`;
940
+
941
+ // Retry original request
942
+ options._retry = true;
943
+ return client.request(options);
944
+ }
945
+
946
+ return response;
947
+ });
948
+ ```
949
+
950
+ ### Retry Logic
951
+
952
+ Configure automatic retry with exponential backoff.
953
+
954
+ ```typescript
955
+ import rezo from 'rezo';
956
+
957
+ const client = rezo.create({
958
+ retry: {
959
+ limit: 3, // Maximum retry attempts
960
+ delay: 1000, // Initial delay (ms)
961
+ maxDelay: 30000, // Maximum delay (ms)
962
+ backoff: 2, // Exponential backoff multiplier
963
+ retryOn: [408, 429, 500, 502, 503, 504] // Status codes to retry
964
+ }
965
+ });
966
+
967
+ // Custom retry logic
968
+ const customClient = rezo.create({
969
+ retry: {
970
+ limit: 5,
971
+ retryOn: (error, attemptNumber) => {
972
+ // Retry on network errors
973
+ if (error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT') {
974
+ return true;
975
+ }
976
+
977
+ // Retry on specific status codes
978
+ if (error.response?.status >= 500) {
979
+ return true;
980
+ }
981
+
982
+ // Don't retry on 4xx errors (except 429)
983
+ if (error.response?.status === 429) {
984
+ return true;
985
+ }
986
+
987
+ return false;
988
+ }
989
+ }
990
+ });
991
+
992
+ // Per-request retry configuration
993
+ await client.get('https://api.example.com/data', {
994
+ retry: {
995
+ limit: 10,
996
+ delay: 500
997
+ }
998
+ });
999
+
1000
+ // Disable retry for specific request
1001
+ await client.get('https://api.example.com/critical', {
1002
+ retry: false
1003
+ });
1004
+ ```
1005
+
1006
+ ### Error Handling
1007
+
1008
+ Rezo provides structured errors with actionable information.
1009
+
1010
+ ```typescript
1011
+ import rezo, { RezoError, isRezoError, RezoErrorCode } from 'rezo';
1012
+
1013
+ const client = rezo.create();
1014
+
1015
+ try {
1016
+ await client.get('https://api.example.com/data');
1017
+ } catch (error) {
1018
+ if (isRezoError(error)) {
1019
+ // Access structured error information
1020
+ console.log('Error Code:', error.code);
1021
+ console.log('Message:', error.message);
1022
+ console.log('Details:', error.details);
1023
+ console.log('Suggestion:', error.suggestion);
1024
+
1025
+ // Check error type
1026
+ if (error.isTimeout) {
1027
+ console.log('Request timed out');
1028
+ }
1029
+
1030
+ if (error.isNetworkError) {
1031
+ console.log('Network error occurred');
1032
+ }
1033
+
1034
+ if (error.isHttpError) {
1035
+ console.log('HTTP error:', error.status, error.statusText);
1036
+ console.log('Response data:', error.response?.data);
1037
+ }
1038
+
1039
+ if (error.isProxyError) {
1040
+ console.log('Proxy connection failed');
1041
+ }
1042
+
1043
+ if (error.isTlsError) {
1044
+ console.log('TLS/SSL error');
1045
+ }
1046
+
1047
+ // Check if error is retryable
1048
+ if (error.isRetryable) {
1049
+ console.log('This error can be retried');
1050
+ }
1051
+
1052
+ // Access original request configuration
1053
+ console.log('Request URL:', error.config?.url);
1054
+ console.log('Request Method:', error.config?.method);
1055
+
1056
+ // Serialize error (hides sensitive data)
1057
+ console.log('Error JSON:', JSON.stringify(error));
1058
+ }
1059
+ }
1060
+
1061
+ // Error code enumeration
1062
+ switch (error.code) {
1063
+ case RezoErrorCode.TIMEOUT:
1064
+ // Handle timeout
1065
+ break;
1066
+ case RezoErrorCode.NETWORK_ERROR:
1067
+ // Handle network error
1068
+ break;
1069
+ case RezoErrorCode.PROXY_ERROR:
1070
+ // Handle proxy error
1071
+ break;
1072
+ case RezoErrorCode.TLS_ERROR:
1073
+ // Handle TLS error
1074
+ break;
1075
+ case RezoErrorCode.HTTP_ERROR:
1076
+ // Handle HTTP error
1077
+ break;
1078
+ }
1079
+ ```
1080
+
1081
+ ### Performance Metrics
1082
+
1083
+ Track detailed timing information for performance monitoring.
1084
+
1085
+ ```typescript
1086
+ import rezo, { RezoPerformance } from 'rezo';
1087
+
1088
+ const client = rezo.create({
1089
+ timing: true // Enable timing collection
1090
+ });
1091
+
1092
+ const response = await client.get('https://api.example.com/data');
1093
+
1094
+ // Access timing metrics
1095
+ const timing = response.timing;
1096
+ console.log('DNS Lookup:', timing.dns, 'ms');
1097
+ console.log('TCP Connect:', timing.connect, 'ms');
1098
+ console.log('TLS Handshake:', timing.tls, 'ms');
1099
+ console.log('Time to First Byte:', timing.firstByte, 'ms');
1100
+ console.log('Download Time:', timing.download, 'ms');
1101
+ console.log('Total Time:', timing.total, 'ms');
1102
+
1103
+ // Using RezoPerformance utility
1104
+ const perf = new RezoPerformance();
1105
+
1106
+ perf.mark('start');
1107
+ await client.get('https://api.example.com/data');
1108
+ perf.mark('end');
1109
+
1110
+ const metrics = perf.measure('request', 'start', 'end');
1111
+ console.log('Request Duration:', metrics.duration, 'ms');
1112
+ ```
1113
+
1114
+ ---
1115
+
1116
+ ## Platform Support
1117
+
1118
+ Rezo is designed for universal JavaScript environments with platform-specific optimizations.
1119
+
1120
+ ### Node.js
1121
+
1122
+ Full feature support including all adapters, cookie management, proxy, and streaming.
1123
+
1124
+ ```typescript
1125
+ import rezo from 'rezo';
1126
+ // or
1127
+ import rezo from 'rezo/platform/node';
1128
+ ```
1129
+
1130
+ ### Bun
1131
+
1132
+ Optimized for Bun runtime with native performance.
1133
+
1134
+ ```typescript
1135
+ import rezo from 'rezo';
1136
+ // or
1137
+ import rezo from 'rezo/platform/bun';
1138
+ ```
1139
+
1140
+ ### Deno
1141
+
1142
+ Compatible with Deno's Node.js compatibility layer.
1143
+
1144
+ ```typescript
1145
+ import rezo from 'npm:rezo';
1146
+ // or
1147
+ import rezo from 'npm:rezo/platform/deno';
1148
+ ```
1149
+
1150
+ ### Browser
1151
+
1152
+ Lightweight Fetch-based implementation for browsers.
1153
+
1154
+ ```typescript
1155
+ import rezo from 'rezo';
1156
+ // or
1157
+ import rezo from 'rezo/platform/browser';
1158
+ ```
1159
+
1160
+ ### Cloudflare Workers & Edge Runtimes
1161
+
1162
+ Edge-compatible Fetch adapter with minimal footprint.
1163
+
1164
+ ```typescript
1165
+ import rezo from 'rezo';
1166
+ // or
1167
+ import rezo from 'rezo/platform/worker';
1168
+ ```
1169
+
1170
+ ### React Native
1171
+
1172
+ Mobile-optimized adapter with file system integration.
1173
+
1174
+ ```typescript
1175
+ import rezo from 'rezo';
1176
+ // or
1177
+ import rezo from 'rezo/platform/react-native';
1178
+ ```
1179
+
1180
+ ---
1181
+
1182
+ ## Migration Guide
1183
+
1184
+ ### Migrating from Fetch API
1185
+
1186
+ ```typescript
1187
+ // Before (Fetch)
1188
+ const response = await fetch('https://api.example.com/data', {
1189
+ method: 'POST',
1190
+ headers: { 'Content-Type': 'application/json' },
1191
+ body: JSON.stringify({ name: 'John' })
1192
+ });
1193
+ const data = await response.json();
1194
+
1195
+ // After (Rezo)
1196
+ const response = await rezo.post('https://api.example.com/data', {
1197
+ name: 'John'
1198
+ });
1199
+ const data = response.data; // Automatically parsed
1200
+ ```
1201
+
1202
+ ### Migrating from Got
1203
+
1204
+ ```typescript
1205
+ // Before (Got)
1206
+ import got from 'got';
1207
+ const response = await got.post('https://api.example.com/data', {
1208
+ json: { name: 'John' },
1209
+ responseType: 'json',
1210
+ retry: { limit: 3 }
1211
+ });
1212
+
1213
+ // After (Rezo)
1214
+ import rezo from 'rezo';
1215
+ const response = await rezo.post('https://api.example.com/data',
1216
+ { name: 'John' },
1217
+ { retry: { limit: 3 } }
1218
+ );
1219
+ ```
1220
+
1221
+ ### Migrating from Node-Fetch
1222
+
1223
+ ```typescript
1224
+ // Before (node-fetch)
1225
+ import fetch from 'node-fetch';
1226
+ const response = await fetch('https://api.example.com/data');
1227
+ const data = await response.json();
1228
+
1229
+ // After (Rezo)
1230
+ import rezo from 'rezo';
1231
+ const { data } = await rezo.get('https://api.example.com/data');
1232
+ ```
1233
+
1234
+ ---
1235
+
1236
+ ## TypeScript
1237
+
1238
+ Rezo is written in TypeScript and provides comprehensive type definitions.
1239
+
1240
+ ### Generic Response Types
1241
+
1242
+ ```typescript
1243
+ import rezo from 'rezo';
1244
+
1245
+ interface User {
1246
+ id: number;
1247
+ name: string;
1248
+ email: string;
1249
+ }
1250
+
1251
+ interface ApiResponse<T> {
1252
+ data: T;
1253
+ meta: { total: number; page: number };
1254
+ }
1255
+
1256
+ const client = rezo.create({ baseURL: 'https://api.example.com' });
1257
+
1258
+ // Typed response
1259
+ const response = await client.get<User>('/users/1');
1260
+ const user: User = response.data;
1261
+
1262
+ // Nested generic types
1263
+ const listResponse = await client.get<ApiResponse<User[]>>('/users');
1264
+ const users: User[] = listResponse.data.data;
1265
+ const total: number = listResponse.data.meta.total;
1266
+ ```
1267
+
1268
+ ### Request Configuration Types
1269
+
1270
+ ```typescript
1271
+ import { RezoConfig, RezoResponse, RezoError } from 'rezo';
1272
+
1273
+ // Type-safe configuration
1274
+ const config: RezoConfig = {
1275
+ baseURL: 'https://api.example.com',
1276
+ timeout: 30000,
1277
+ headers: {
1278
+ 'Authorization': 'Bearer token'
1279
+ }
1280
+ };
1281
+
1282
+ // Type-safe error handling
1283
+ function handleError(error: RezoError): void {
1284
+ if (error.isHttpError) {
1285
+ console.log('Status:', error.status);
1286
+ }
1287
+ }
1288
+ ```
1289
+
1290
+ ### Custom Type Guards
1291
+
1292
+ ```typescript
1293
+ import { isRezoError, RezoError } from 'rezo';
1294
+
1295
+ try {
1296
+ await rezo.get('/data');
1297
+ } catch (error) {
1298
+ if (isRezoError(error)) {
1299
+ // TypeScript knows error is RezoError here
1300
+ console.log(error.code);
1301
+ console.log(error.details);
1302
+ }
1303
+ }
1304
+ ```
1305
+
1306
+ ---
1307
+
1308
+ ## Crawler Module
1309
+
1310
+ Rezo includes a powerful web crawler module for web scraping scenarios.
1311
+
1312
+ ```typescript
1313
+ import { Crawler, CrawlerOptions } from 'rezo/crawler';
1314
+
1315
+ const options = new CrawlerOptions()
1316
+ .setGlobalProxy({ host: 'proxy.example.com', port: 8080 })
1317
+ .setGlobalHeaders({ 'User-Agent': 'Mozilla/5.0...' })
1318
+ .addLimiter({ domain: 'example.com', concurrency: 2, interval: 1000 });
1319
+
1320
+ const crawler = new Crawler(options);
1321
+
1322
+ crawler.onDocument(async (doc, url) => {
1323
+ const title = doc.querySelector('title')?.textContent;
1324
+ console.log(`Title: ${title}`);
1325
+ });
1326
+
1327
+ crawler.onAnchor((href, anchor) => {
1328
+ console.log(`Found link: ${href}`);
1329
+ });
1330
+
1331
+ await crawler.crawl('https://example.com');
1332
+ ```
1333
+
1334
+ ---
1335
+
1336
+ ## DOM Module
1337
+
1338
+ Rezo includes a DOM parsing module that re-exports all [linkedom](https://github.com/WebReflection/linkedom) utilities for HTML parsing and DOM manipulation.
1339
+
1340
+ ```typescript
1341
+ import { parseHTML, DOMParser } from 'rezo/dom';
1342
+
1343
+ // Parse HTML string into a document
1344
+ const { document } = parseHTML('<html><body><h1>Hello World</h1></body></html>');
1345
+ console.log(document.querySelector('h1')?.textContent); // 'Hello World'
1346
+
1347
+ // Using DOMParser
1348
+ const parser = new DOMParser();
1349
+ const doc = parser.parseFromString('<div class="content">Text</div>', 'text/html');
1350
+ console.log(doc.querySelector('.content')?.textContent); // 'Text'
1351
+ ```
1352
+
1353
+ ### Available Exports
1354
+
1355
+ All linkedom exports are available from `rezo/dom`:
1356
+
1357
+ - `parseHTML` - Parse HTML string into a window-like object
1358
+ - `parseJSON` / `toJSON` - JSON serialization utilities
1359
+ - `DOMParser` - Standard DOMParser interface
1360
+ - `Document` - Document constructor
1361
+ - `Event` / `CustomEvent` / `InputEvent` - Event classes
1362
+ - `EventTarget` - EventTarget interface
1363
+ - `NodeList` - NodeList interface
1364
+
1365
+ ---
1366
+
1367
+ ## Troubleshooting
1368
+
1369
+ ### Common Issues
1370
+
1371
+ #### Request Timeout
1372
+
1373
+ ```typescript
1374
+ // Increase timeout
1375
+ const client = rezo.create({
1376
+ timeout: 60000, // 60 seconds
1377
+ connectTimeout: 10000 // 10 seconds for connection
1378
+ });
1379
+ ```
1380
+
1381
+ #### SSL Certificate Errors
1382
+
1383
+ ```typescript
1384
+ // For development only - not recommended for production
1385
+ const client = rezo.create({
1386
+ rejectUnauthorized: false
1387
+ });
1388
+
1389
+ // Better: provide custom CA
1390
+ const client = rezo.create({
1391
+ ca: fs.readFileSync('./custom-ca.pem')
1392
+ });
1393
+ ```
1394
+
1395
+ #### Proxy Connection Issues
1396
+
1397
+ ```typescript
1398
+ // Verify proxy settings
1399
+ const client = rezo.create({
1400
+ proxy: {
1401
+ protocol: 'http', // Ensure correct protocol
1402
+ host: 'proxy.example.com',
1403
+ port: 8080
1404
+ }
1405
+ });
1406
+
1407
+ // Test proxy connection
1408
+ try {
1409
+ await client.get('https://httpbin.org/ip');
1410
+ } catch (error) {
1411
+ if (error.isProxyError) {
1412
+ console.log('Proxy connection failed:', error.details);
1413
+ }
1414
+ }
1415
+ ```
1416
+
1417
+ #### Memory Issues with Large Files
1418
+
1419
+ ```typescript
1420
+ // Use streaming for large files
1421
+ const response = await client.get('https://example.com/large-file', {
1422
+ responseType: 'stream'
1423
+ });
1424
+
1425
+ // Or use download API
1426
+ const download = await client.download('https://example.com/large-file', {
1427
+ outputPath: './large-file.zip'
1428
+ });
1429
+ ```
1430
+
1431
+ ### Debug Mode
1432
+
1433
+ ```typescript
1434
+ // Enable debug logging
1435
+ const client = rezo.create({
1436
+ debug: true
1437
+ });
1438
+
1439
+ // Or set environment variable
1440
+ process.env.REZO_DEBUG = 'true';
1441
+ ```
1442
+
1443
+ ---
1444
+
1445
+ ## Contributing
1446
+
1447
+ We welcome contributions to Rezo! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1448
+
1449
+ ### Development Setup
1450
+
1451
+ ```bash
1452
+ # Clone repository
1453
+ git clone https://github.com/yuniqsolutions/rezo.git
1454
+ cd rezo
1455
+
1456
+ # Install dependencies
1457
+ bun install
1458
+
1459
+ # Run tests
1460
+ bun test
1461
+
1462
+ # Build
1463
+ bun run bundle
1464
+
1465
+ # Lint
1466
+ bun run lint
1467
+ ```
1468
+
1469
+ ### Running Tests
1470
+
1471
+ ```bash
1472
+ # Run all tests
1473
+ bun test
1474
+
1475
+ # Run with coverage
1476
+ bun run test:coverage
1477
+
1478
+ # Run specific test file
1479
+ bun test src/adapters/http.test.ts
1480
+ ```
1481
+
1482
+ ---
1483
+
1484
+ ## Acknowledgments
1485
+
1486
+ Rezo was built with inspiration from the JavaScript HTTP client ecosystem, including the excellent work done by the teams behind Got, Ky, Undici, and other HTTP client libraries. We thank the open-source community for their contributions to the JavaScript ecosystem.
1487
+
1488
+ ---
1489
+
1490
+ ## License
1491
+
1492
+ Rezo is open source software licensed under the [MIT License](LICENSE).
1493
+
1494
+ Copyright (c) 2024-2025 Yuniq Solutions Tech
1495
+
1496
+ See the [LICENSE](LICENSE) file for the complete license text.
1497
+
1498
+ ---
1499
+
1500
+ <p align="center">
1501
+ <img src="assets/icon.svg" alt="Rezo Icon" width="60">
1502
+ </p>
1503
+
1504
+ <p align="center">
1505
+ <strong>Built with lightning speed in mind</strong><br>
1506
+ <sub>Made by <a href="https://yuniq.solutions">Yuniq Solutions Tech</a></sub>
1507
+ </p>