rezo 1.0.13 → 1.0.15

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 (38) hide show
  1. package/dist/adapters/curl.cjs +16 -12
  2. package/dist/adapters/curl.js +16 -12
  3. package/dist/adapters/entries/curl.d.ts +32 -4
  4. package/dist/adapters/entries/fetch.d.ts +32 -4
  5. package/dist/adapters/entries/http.d.ts +32 -4
  6. package/dist/adapters/entries/http2.d.ts +32 -4
  7. package/dist/adapters/entries/react-native.d.ts +32 -4
  8. package/dist/adapters/entries/xhr.d.ts +32 -4
  9. package/dist/adapters/fetch.cjs +24 -1
  10. package/dist/adapters/fetch.js +24 -1
  11. package/dist/adapters/http.cjs +23 -0
  12. package/dist/adapters/http.js +23 -0
  13. package/dist/adapters/http2.cjs +24 -1
  14. package/dist/adapters/http2.js +24 -1
  15. package/dist/adapters/index.cjs +6 -6
  16. package/dist/adapters/picker.cjs +1 -1
  17. package/dist/adapters/picker.js +1 -1
  18. package/dist/cache/index.cjs +13 -13
  19. package/dist/core/rezo.cjs +29 -8
  20. package/dist/core/rezo.js +29 -8
  21. package/dist/crawler.d.ts +32 -4
  22. package/dist/entries/crawler.cjs +5 -5
  23. package/dist/index.cjs +24 -24
  24. package/dist/index.d.ts +32 -4
  25. package/dist/platform/browser.d.ts +32 -4
  26. package/dist/platform/bun.d.ts +32 -4
  27. package/dist/platform/deno.d.ts +32 -4
  28. package/dist/platform/node.d.ts +32 -4
  29. package/dist/platform/react-native.d.ts +32 -4
  30. package/dist/platform/worker.d.ts +32 -4
  31. package/dist/plugin/index.cjs +36 -36
  32. package/dist/proxy/index.cjs +2 -2
  33. package/dist/queue/index.cjs +8 -8
  34. package/dist/utils/form-data.cjs +64 -7
  35. package/dist/utils/form-data.js +64 -7
  36. package/dist/utils/http-config.cjs +1 -1
  37. package/dist/utils/http-config.js +1 -1
  38. package/package.json +1 -1
@@ -6,7 +6,7 @@ const { spawn, execSync } = require("node:child_process");
6
6
  const { Readable } = require("node:stream");
7
7
  const { EventEmitter } = require("node:events");
8
8
  const { RezoError } = require('../errors/rezo-error.cjs');
9
- const { buildSmartError } = require('../responses/buildError.cjs');
9
+ const { buildSmartError, builErrorFromResponse } = require('../responses/buildError.cjs');
10
10
  const { RezoCookieJar, Cookie } = require('../utils/cookies.cjs');
11
11
  const RezoFormData = require('../utils/form-data.cjs');
12
12
  const { existsSync } = require("node:fs");
@@ -1906,19 +1906,23 @@ async function executeRequest(options, defaultOptions, jar) {
1906
1906
  if (proxyManager && selectedProxy) {
1907
1907
  proxyManager.reportSuccess(selectedProxy);
1908
1908
  }
1909
- if (config.retry && response.status >= 400) {
1910
- const maxRetries = config.retry.maxRetries || 0;
1911
- const statusCodes = config.retry.statusCodes || [408, 429, 500, 502, 503, 504];
1912
- if (config.retryAttempts < maxRetries && statusCodes.includes(response.status)) {
1913
- const retryDelay = config.retry.retryDelay || 0;
1914
- const incrementDelay = config.retry.incrementDelay || false;
1915
- const delay = incrementDelay ? retryDelay * (config.retryAttempts + 1) : retryDelay;
1916
- if (delay > 0) {
1917
- await new Promise((resolve) => setTimeout(resolve, delay));
1909
+ if (response.status >= 400) {
1910
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, originalRequest);
1911
+ if (config.retry) {
1912
+ const maxRetries = config.retry.maxRetries || 0;
1913
+ const statusCodes = config.retry.statusCodes || [408, 429, 500, 502, 503, 504];
1914
+ if (config.retryAttempts < maxRetries && statusCodes.includes(response.status)) {
1915
+ const retryDelay = config.retry.retryDelay || 0;
1916
+ const incrementDelay = config.retry.incrementDelay || false;
1917
+ const delay = incrementDelay ? retryDelay * (config.retryAttempts + 1) : retryDelay;
1918
+ if (delay > 0) {
1919
+ await new Promise((resolve) => setTimeout(resolve, delay));
1920
+ }
1921
+ config.retryAttempts++;
1922
+ return executeRequest(options, defaultOptions, jar);
1918
1923
  }
1919
- config.retryAttempts++;
1920
- return executeRequest(options, defaultOptions, jar);
1921
1924
  }
1925
+ throw httpError;
1922
1926
  }
1923
1927
  }
1924
1928
  return result;
@@ -6,7 +6,7 @@ import { spawn, execSync } from "node:child_process";
6
6
  import { Readable } from "node:stream";
7
7
  import { EventEmitter } from "node:events";
8
8
  import { RezoError } from '../errors/rezo-error.js';
9
- import { buildSmartError } from '../responses/buildError.js';
9
+ import { buildSmartError, builErrorFromResponse } from '../responses/buildError.js';
10
10
  import { RezoCookieJar, Cookie } from '../utils/cookies.js';
11
11
  import RezoFormData from '../utils/form-data.js';
12
12
  import { existsSync } from "node:fs";
@@ -1906,19 +1906,23 @@ export async function executeRequest(options, defaultOptions, jar) {
1906
1906
  if (proxyManager && selectedProxy) {
1907
1907
  proxyManager.reportSuccess(selectedProxy);
1908
1908
  }
1909
- if (config.retry && response.status >= 400) {
1910
- const maxRetries = config.retry.maxRetries || 0;
1911
- const statusCodes = config.retry.statusCodes || [408, 429, 500, 502, 503, 504];
1912
- if (config.retryAttempts < maxRetries && statusCodes.includes(response.status)) {
1913
- const retryDelay = config.retry.retryDelay || 0;
1914
- const incrementDelay = config.retry.incrementDelay || false;
1915
- const delay = incrementDelay ? retryDelay * (config.retryAttempts + 1) : retryDelay;
1916
- if (delay > 0) {
1917
- await new Promise((resolve) => setTimeout(resolve, delay));
1909
+ if (response.status >= 400) {
1910
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, originalRequest);
1911
+ if (config.retry) {
1912
+ const maxRetries = config.retry.maxRetries || 0;
1913
+ const statusCodes = config.retry.statusCodes || [408, 429, 500, 502, 503, 504];
1914
+ if (config.retryAttempts < maxRetries && statusCodes.includes(response.status)) {
1915
+ const retryDelay = config.retry.retryDelay || 0;
1916
+ const incrementDelay = config.retry.incrementDelay || false;
1917
+ const delay = incrementDelay ? retryDelay * (config.retryAttempts + 1) : retryDelay;
1918
+ if (delay > 0) {
1919
+ await new Promise((resolve) => setTimeout(resolve, delay));
1920
+ }
1921
+ config.retryAttempts++;
1922
+ return executeRequest(options, defaultOptions, jar);
1918
1923
  }
1919
- config.retryAttempts++;
1920
- return executeRequest(options, defaultOptions, jar);
1921
1924
  }
1925
+ throw httpError;
1922
1926
  }
1923
1927
  }
1924
1928
  return result;
@@ -314,11 +314,19 @@ export declare class RezoFormData extends NodeFormData {
314
314
  toBuffer(): Buffer;
315
315
  /**
316
316
  * Create RezoFormData from object
317
+ * Properly handles nested objects by JSON.stringify-ing them
317
318
  * @param {Record<string, any>} obj - Object to convert
318
319
  * @param {Options} options - Optional RezoFormData options
319
320
  * @returns {RezoFormData}
320
321
  */
321
322
  static fromObject(obj: Record<string, any>, options?: Options): RezoFormData;
323
+ /**
324
+ * Helper to append a value to FormData with proper type handling
325
+ * @param {RezoFormData} formData - The form data to append to
326
+ * @param {string} key - The field name
327
+ * @param {any} value - The value to append
328
+ */
329
+ private static appendValue;
322
330
  /**
323
331
  * Convert to URL query string
324
332
  * Warning: File, Blob, and binary data will be omitted
@@ -2685,8 +2693,19 @@ export interface RezoRequestConfig<D = any> {
2685
2693
  useProxyManager?: boolean;
2686
2694
  /** Whether to enable automatic cookie handling */
2687
2695
  useCookies?: boolean;
2688
- /** Custom cookie jar for managing cookies */
2689
- cookieJar?: RezoCookieJar;
2696
+ /**
2697
+ * Custom cookie jar for managing cookies in this request.
2698
+ * Note: Passing jar per-request is supported but not recommended.
2699
+ * For better cookie management, pass the jar when creating the instance:
2700
+ * @example
2701
+ * ```typescript
2702
+ * const client = new Rezo({ jar: myJar });
2703
+ * // or
2704
+ * const client = rezo.create({ jar: myJar });
2705
+ * ```
2706
+ * If you need custom cookies for a single request, use the `cookies` option instead.
2707
+ */
2708
+ jar?: RezoCookieJar;
2690
2709
  /** Cookies to send with the request in various formats */
2691
2710
  cookies?: Cookies["array"] | Cookies["netscape"] | Cookies["serialized"] | Cookies["setCookiesString"];
2692
2711
  /** Callback for upload progress events */
@@ -3117,8 +3136,17 @@ export interface RezoDefaultOptions {
3117
3136
  hooks?: Partial<RezoHooks>;
3118
3137
  /** Whether to enable automatic cookie handling (default: true)*/
3119
3138
  enableCookieJar?: boolean;
3120
- /** Custom cookie jar for managing cookies */
3121
- cookieJar?: RezoHttpRequest["cookieJar"];
3139
+ /**
3140
+ * Custom cookie jar for managing cookies.
3141
+ * The recommended way to manage cookies - pass the jar when creating the instance.
3142
+ * @example
3143
+ * ```typescript
3144
+ * const client = new Rezo({ jar: myJar });
3145
+ * // or
3146
+ * const client = rezo.create({ jar: myJar });
3147
+ * ```
3148
+ */
3149
+ jar?: RezoHttpRequest["jar"];
3122
3150
  /** Set default cookies to send with the requests in various formats */
3123
3151
  cookies?: RezoHttpRequest["cookies"];
3124
3152
  /**
@@ -314,11 +314,19 @@ export declare class RezoFormData extends NodeFormData {
314
314
  toBuffer(): Buffer;
315
315
  /**
316
316
  * Create RezoFormData from object
317
+ * Properly handles nested objects by JSON.stringify-ing them
317
318
  * @param {Record<string, any>} obj - Object to convert
318
319
  * @param {Options} options - Optional RezoFormData options
319
320
  * @returns {RezoFormData}
320
321
  */
321
322
  static fromObject(obj: Record<string, any>, options?: Options): RezoFormData;
323
+ /**
324
+ * Helper to append a value to FormData with proper type handling
325
+ * @param {RezoFormData} formData - The form data to append to
326
+ * @param {string} key - The field name
327
+ * @param {any} value - The value to append
328
+ */
329
+ private static appendValue;
322
330
  /**
323
331
  * Convert to URL query string
324
332
  * Warning: File, Blob, and binary data will be omitted
@@ -2685,8 +2693,19 @@ export interface RezoRequestConfig<D = any> {
2685
2693
  useProxyManager?: boolean;
2686
2694
  /** Whether to enable automatic cookie handling */
2687
2695
  useCookies?: boolean;
2688
- /** Custom cookie jar for managing cookies */
2689
- cookieJar?: RezoCookieJar;
2696
+ /**
2697
+ * Custom cookie jar for managing cookies in this request.
2698
+ * Note: Passing jar per-request is supported but not recommended.
2699
+ * For better cookie management, pass the jar when creating the instance:
2700
+ * @example
2701
+ * ```typescript
2702
+ * const client = new Rezo({ jar: myJar });
2703
+ * // or
2704
+ * const client = rezo.create({ jar: myJar });
2705
+ * ```
2706
+ * If you need custom cookies for a single request, use the `cookies` option instead.
2707
+ */
2708
+ jar?: RezoCookieJar;
2690
2709
  /** Cookies to send with the request in various formats */
2691
2710
  cookies?: Cookies["array"] | Cookies["netscape"] | Cookies["serialized"] | Cookies["setCookiesString"];
2692
2711
  /** Callback for upload progress events */
@@ -3117,8 +3136,17 @@ export interface RezoDefaultOptions {
3117
3136
  hooks?: Partial<RezoHooks>;
3118
3137
  /** Whether to enable automatic cookie handling (default: true)*/
3119
3138
  enableCookieJar?: boolean;
3120
- /** Custom cookie jar for managing cookies */
3121
- cookieJar?: RezoHttpRequest["cookieJar"];
3139
+ /**
3140
+ * Custom cookie jar for managing cookies.
3141
+ * The recommended way to manage cookies - pass the jar when creating the instance.
3142
+ * @example
3143
+ * ```typescript
3144
+ * const client = new Rezo({ jar: myJar });
3145
+ * // or
3146
+ * const client = rezo.create({ jar: myJar });
3147
+ * ```
3148
+ */
3149
+ jar?: RezoHttpRequest["jar"];
3122
3150
  /** Set default cookies to send with the requests in various formats */
3123
3151
  cookies?: RezoHttpRequest["cookies"];
3124
3152
  /**
@@ -314,11 +314,19 @@ export declare class RezoFormData extends NodeFormData {
314
314
  toBuffer(): Buffer;
315
315
  /**
316
316
  * Create RezoFormData from object
317
+ * Properly handles nested objects by JSON.stringify-ing them
317
318
  * @param {Record<string, any>} obj - Object to convert
318
319
  * @param {Options} options - Optional RezoFormData options
319
320
  * @returns {RezoFormData}
320
321
  */
321
322
  static fromObject(obj: Record<string, any>, options?: Options): RezoFormData;
323
+ /**
324
+ * Helper to append a value to FormData with proper type handling
325
+ * @param {RezoFormData} formData - The form data to append to
326
+ * @param {string} key - The field name
327
+ * @param {any} value - The value to append
328
+ */
329
+ private static appendValue;
322
330
  /**
323
331
  * Convert to URL query string
324
332
  * Warning: File, Blob, and binary data will be omitted
@@ -2685,8 +2693,19 @@ export interface RezoRequestConfig<D = any> {
2685
2693
  useProxyManager?: boolean;
2686
2694
  /** Whether to enable automatic cookie handling */
2687
2695
  useCookies?: boolean;
2688
- /** Custom cookie jar for managing cookies */
2689
- cookieJar?: RezoCookieJar;
2696
+ /**
2697
+ * Custom cookie jar for managing cookies in this request.
2698
+ * Note: Passing jar per-request is supported but not recommended.
2699
+ * For better cookie management, pass the jar when creating the instance:
2700
+ * @example
2701
+ * ```typescript
2702
+ * const client = new Rezo({ jar: myJar });
2703
+ * // or
2704
+ * const client = rezo.create({ jar: myJar });
2705
+ * ```
2706
+ * If you need custom cookies for a single request, use the `cookies` option instead.
2707
+ */
2708
+ jar?: RezoCookieJar;
2690
2709
  /** Cookies to send with the request in various formats */
2691
2710
  cookies?: Cookies["array"] | Cookies["netscape"] | Cookies["serialized"] | Cookies["setCookiesString"];
2692
2711
  /** Callback for upload progress events */
@@ -3117,8 +3136,17 @@ export interface RezoDefaultOptions {
3117
3136
  hooks?: Partial<RezoHooks>;
3118
3137
  /** Whether to enable automatic cookie handling (default: true)*/
3119
3138
  enableCookieJar?: boolean;
3120
- /** Custom cookie jar for managing cookies */
3121
- cookieJar?: RezoHttpRequest["cookieJar"];
3139
+ /**
3140
+ * Custom cookie jar for managing cookies.
3141
+ * The recommended way to manage cookies - pass the jar when creating the instance.
3142
+ * @example
3143
+ * ```typescript
3144
+ * const client = new Rezo({ jar: myJar });
3145
+ * // or
3146
+ * const client = rezo.create({ jar: myJar });
3147
+ * ```
3148
+ */
3149
+ jar?: RezoHttpRequest["jar"];
3122
3150
  /** Set default cookies to send with the requests in various formats */
3123
3151
  cookies?: RezoHttpRequest["cookies"];
3124
3152
  /**
@@ -314,11 +314,19 @@ export declare class RezoFormData extends NodeFormData {
314
314
  toBuffer(): Buffer;
315
315
  /**
316
316
  * Create RezoFormData from object
317
+ * Properly handles nested objects by JSON.stringify-ing them
317
318
  * @param {Record<string, any>} obj - Object to convert
318
319
  * @param {Options} options - Optional RezoFormData options
319
320
  * @returns {RezoFormData}
320
321
  */
321
322
  static fromObject(obj: Record<string, any>, options?: Options): RezoFormData;
323
+ /**
324
+ * Helper to append a value to FormData with proper type handling
325
+ * @param {RezoFormData} formData - The form data to append to
326
+ * @param {string} key - The field name
327
+ * @param {any} value - The value to append
328
+ */
329
+ private static appendValue;
322
330
  /**
323
331
  * Convert to URL query string
324
332
  * Warning: File, Blob, and binary data will be omitted
@@ -2685,8 +2693,19 @@ export interface RezoRequestConfig<D = any> {
2685
2693
  useProxyManager?: boolean;
2686
2694
  /** Whether to enable automatic cookie handling */
2687
2695
  useCookies?: boolean;
2688
- /** Custom cookie jar for managing cookies */
2689
- cookieJar?: RezoCookieJar;
2696
+ /**
2697
+ * Custom cookie jar for managing cookies in this request.
2698
+ * Note: Passing jar per-request is supported but not recommended.
2699
+ * For better cookie management, pass the jar when creating the instance:
2700
+ * @example
2701
+ * ```typescript
2702
+ * const client = new Rezo({ jar: myJar });
2703
+ * // or
2704
+ * const client = rezo.create({ jar: myJar });
2705
+ * ```
2706
+ * If you need custom cookies for a single request, use the `cookies` option instead.
2707
+ */
2708
+ jar?: RezoCookieJar;
2690
2709
  /** Cookies to send with the request in various formats */
2691
2710
  cookies?: Cookies["array"] | Cookies["netscape"] | Cookies["serialized"] | Cookies["setCookiesString"];
2692
2711
  /** Callback for upload progress events */
@@ -3117,8 +3136,17 @@ export interface RezoDefaultOptions {
3117
3136
  hooks?: Partial<RezoHooks>;
3118
3137
  /** Whether to enable automatic cookie handling (default: true)*/
3119
3138
  enableCookieJar?: boolean;
3120
- /** Custom cookie jar for managing cookies */
3121
- cookieJar?: RezoHttpRequest["cookieJar"];
3139
+ /**
3140
+ * Custom cookie jar for managing cookies.
3141
+ * The recommended way to manage cookies - pass the jar when creating the instance.
3142
+ * @example
3143
+ * ```typescript
3144
+ * const client = new Rezo({ jar: myJar });
3145
+ * // or
3146
+ * const client = rezo.create({ jar: myJar });
3147
+ * ```
3148
+ */
3149
+ jar?: RezoHttpRequest["jar"];
3122
3150
  /** Set default cookies to send with the requests in various formats */
3123
3151
  cookies?: RezoHttpRequest["cookies"];
3124
3152
  /**
@@ -314,11 +314,19 @@ export declare class RezoFormData extends NodeFormData {
314
314
  toBuffer(): Buffer;
315
315
  /**
316
316
  * Create RezoFormData from object
317
+ * Properly handles nested objects by JSON.stringify-ing them
317
318
  * @param {Record<string, any>} obj - Object to convert
318
319
  * @param {Options} options - Optional RezoFormData options
319
320
  * @returns {RezoFormData}
320
321
  */
321
322
  static fromObject(obj: Record<string, any>, options?: Options): RezoFormData;
323
+ /**
324
+ * Helper to append a value to FormData with proper type handling
325
+ * @param {RezoFormData} formData - The form data to append to
326
+ * @param {string} key - The field name
327
+ * @param {any} value - The value to append
328
+ */
329
+ private static appendValue;
322
330
  /**
323
331
  * Convert to URL query string
324
332
  * Warning: File, Blob, and binary data will be omitted
@@ -2685,8 +2693,19 @@ export interface RezoRequestConfig<D = any> {
2685
2693
  useProxyManager?: boolean;
2686
2694
  /** Whether to enable automatic cookie handling */
2687
2695
  useCookies?: boolean;
2688
- /** Custom cookie jar for managing cookies */
2689
- cookieJar?: RezoCookieJar;
2696
+ /**
2697
+ * Custom cookie jar for managing cookies in this request.
2698
+ * Note: Passing jar per-request is supported but not recommended.
2699
+ * For better cookie management, pass the jar when creating the instance:
2700
+ * @example
2701
+ * ```typescript
2702
+ * const client = new Rezo({ jar: myJar });
2703
+ * // or
2704
+ * const client = rezo.create({ jar: myJar });
2705
+ * ```
2706
+ * If you need custom cookies for a single request, use the `cookies` option instead.
2707
+ */
2708
+ jar?: RezoCookieJar;
2690
2709
  /** Cookies to send with the request in various formats */
2691
2710
  cookies?: Cookies["array"] | Cookies["netscape"] | Cookies["serialized"] | Cookies["setCookiesString"];
2692
2711
  /** Callback for upload progress events */
@@ -3117,8 +3136,17 @@ export interface RezoDefaultOptions {
3117
3136
  hooks?: Partial<RezoHooks>;
3118
3137
  /** Whether to enable automatic cookie handling (default: true)*/
3119
3138
  enableCookieJar?: boolean;
3120
- /** Custom cookie jar for managing cookies */
3121
- cookieJar?: RezoHttpRequest["cookieJar"];
3139
+ /**
3140
+ * Custom cookie jar for managing cookies.
3141
+ * The recommended way to manage cookies - pass the jar when creating the instance.
3142
+ * @example
3143
+ * ```typescript
3144
+ * const client = new Rezo({ jar: myJar });
3145
+ * // or
3146
+ * const client = rezo.create({ jar: myJar });
3147
+ * ```
3148
+ */
3149
+ jar?: RezoHttpRequest["jar"];
3122
3150
  /** Set default cookies to send with the requests in various formats */
3123
3151
  cookies?: RezoHttpRequest["cookies"];
3124
3152
  /**
@@ -314,11 +314,19 @@ export declare class RezoFormData extends NodeFormData {
314
314
  toBuffer(): Buffer;
315
315
  /**
316
316
  * Create RezoFormData from object
317
+ * Properly handles nested objects by JSON.stringify-ing them
317
318
  * @param {Record<string, any>} obj - Object to convert
318
319
  * @param {Options} options - Optional RezoFormData options
319
320
  * @returns {RezoFormData}
320
321
  */
321
322
  static fromObject(obj: Record<string, any>, options?: Options): RezoFormData;
323
+ /**
324
+ * Helper to append a value to FormData with proper type handling
325
+ * @param {RezoFormData} formData - The form data to append to
326
+ * @param {string} key - The field name
327
+ * @param {any} value - The value to append
328
+ */
329
+ private static appendValue;
322
330
  /**
323
331
  * Convert to URL query string
324
332
  * Warning: File, Blob, and binary data will be omitted
@@ -2685,8 +2693,19 @@ export interface RezoRequestConfig<D = any> {
2685
2693
  useProxyManager?: boolean;
2686
2694
  /** Whether to enable automatic cookie handling */
2687
2695
  useCookies?: boolean;
2688
- /** Custom cookie jar for managing cookies */
2689
- cookieJar?: RezoCookieJar;
2696
+ /**
2697
+ * Custom cookie jar for managing cookies in this request.
2698
+ * Note: Passing jar per-request is supported but not recommended.
2699
+ * For better cookie management, pass the jar when creating the instance:
2700
+ * @example
2701
+ * ```typescript
2702
+ * const client = new Rezo({ jar: myJar });
2703
+ * // or
2704
+ * const client = rezo.create({ jar: myJar });
2705
+ * ```
2706
+ * If you need custom cookies for a single request, use the `cookies` option instead.
2707
+ */
2708
+ jar?: RezoCookieJar;
2690
2709
  /** Cookies to send with the request in various formats */
2691
2710
  cookies?: Cookies["array"] | Cookies["netscape"] | Cookies["serialized"] | Cookies["setCookiesString"];
2692
2711
  /** Callback for upload progress events */
@@ -3117,8 +3136,17 @@ export interface RezoDefaultOptions {
3117
3136
  hooks?: Partial<RezoHooks>;
3118
3137
  /** Whether to enable automatic cookie handling (default: true)*/
3119
3138
  enableCookieJar?: boolean;
3120
- /** Custom cookie jar for managing cookies */
3121
- cookieJar?: RezoHttpRequest["cookieJar"];
3139
+ /**
3140
+ * Custom cookie jar for managing cookies.
3141
+ * The recommended way to manage cookies - pass the jar when creating the instance.
3142
+ * @example
3143
+ * ```typescript
3144
+ * const client = new Rezo({ jar: myJar });
3145
+ * // or
3146
+ * const client = rezo.create({ jar: myJar });
3147
+ * ```
3148
+ */
3149
+ jar?: RezoHttpRequest["jar"];
3122
3150
  /** Set default cookies to send with the requests in various formats */
3123
3151
  cookies?: RezoHttpRequest["cookies"];
3124
3152
  /**
@@ -366,9 +366,32 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
366
366
  }
367
367
  continue;
368
368
  }
369
- if (statusOnNext === "success" || statusOnNext === "error") {
369
+ if (statusOnNext === "success") {
370
370
  return response;
371
371
  }
372
+ if (statusOnNext === "error") {
373
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, fetchOptions);
374
+ if (config.retry && statusCodes?.includes(response.status)) {
375
+ if (maxRetries > retries) {
376
+ retries++;
377
+ config.retryAttempts++;
378
+ config.errors.push({
379
+ attempt: config.retryAttempts,
380
+ error: httpError,
381
+ duration: perform.now()
382
+ });
383
+ perform.reset();
384
+ if (config.debug) {
385
+ console.log(`Request failed with status code ${response.status}, retrying...${retryDelay > 0 ? " in " + (incrementDelay ? retryDelay * retries : retryDelay) + "ms" : ""}`);
386
+ }
387
+ if (retryDelay > 0) {
388
+ await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
389
+ }
390
+ continue;
391
+ }
392
+ }
393
+ throw httpError;
394
+ }
372
395
  if (statusOnNext === "redirect") {
373
396
  const location = _stats.redirectUrl;
374
397
  if (!location) {
@@ -366,9 +366,32 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
366
366
  }
367
367
  continue;
368
368
  }
369
- if (statusOnNext === "success" || statusOnNext === "error") {
369
+ if (statusOnNext === "success") {
370
370
  return response;
371
371
  }
372
+ if (statusOnNext === "error") {
373
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, fetchOptions);
374
+ if (config.retry && statusCodes?.includes(response.status)) {
375
+ if (maxRetries > retries) {
376
+ retries++;
377
+ config.retryAttempts++;
378
+ config.errors.push({
379
+ attempt: config.retryAttempts,
380
+ error: httpError,
381
+ duration: perform.now()
382
+ });
383
+ perform.reset();
384
+ if (config.debug) {
385
+ console.log(`Request failed with status code ${response.status}, retrying...${retryDelay > 0 ? " in " + (incrementDelay ? retryDelay * retries : retryDelay) + "ms" : ""}`);
386
+ }
387
+ if (retryDelay > 0) {
388
+ await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
389
+ }
390
+ continue;
391
+ }
392
+ }
393
+ throw httpError;
394
+ }
372
395
  if (statusOnNext === "redirect") {
373
396
  const location = _stats.redirectUrl;
374
397
  if (!location) {
@@ -402,6 +402,29 @@ Redirecting to: ${fetchOptions.fullUrl} using GET method`);
402
402
  options = __.options;
403
403
  continue;
404
404
  }
405
+ if (statusOnNext === "error") {
406
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, fetchOptions);
407
+ if (config.retry && statusCodes?.includes(response.status)) {
408
+ if (maxRetries > retries) {
409
+ retries++;
410
+ config.retryAttempts++;
411
+ config.errors.push({
412
+ attempt: config.retryAttempts,
413
+ error: httpError,
414
+ duration: perform.now()
415
+ });
416
+ perform.reset();
417
+ if (config.debug) {
418
+ console.log(`Request failed with status code ${response.status}, retrying...${retryDelay > 0 ? " in " + (incrementDelay ? retryDelay * retries : retryDelay) + "ms" : ""}`);
419
+ }
420
+ if (retryDelay > 0) {
421
+ await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
422
+ }
423
+ continue;
424
+ }
425
+ }
426
+ throw httpError;
427
+ }
405
428
  delete config.beforeRedirect;
406
429
  config.setSignal = () => {};
407
430
  return response;
@@ -402,6 +402,29 @@ Redirecting to: ${fetchOptions.fullUrl} using GET method`);
402
402
  options = __.options;
403
403
  continue;
404
404
  }
405
+ if (statusOnNext === "error") {
406
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, fetchOptions);
407
+ if (config.retry && statusCodes?.includes(response.status)) {
408
+ if (maxRetries > retries) {
409
+ retries++;
410
+ config.retryAttempts++;
411
+ config.errors.push({
412
+ attempt: config.retryAttempts,
413
+ error: httpError,
414
+ duration: perform.now()
415
+ });
416
+ perform.reset();
417
+ if (config.debug) {
418
+ console.log(`Request failed with status code ${response.status}, retrying...${retryDelay > 0 ? " in " + (incrementDelay ? retryDelay * retries : retryDelay) + "ms" : ""}`);
419
+ }
420
+ if (retryDelay > 0) {
421
+ await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
422
+ }
423
+ continue;
424
+ }
425
+ }
426
+ throw httpError;
427
+ }
405
428
  delete config.beforeRedirect;
406
429
  config.setSignal = () => {};
407
430
  return response;
@@ -557,9 +557,32 @@ async function executeHttp2Request(fetchOptions, config, options, perform, fs, s
557
557
  }
558
558
  continue;
559
559
  }
560
- if (statusOnNext === "success" || statusOnNext === "error") {
560
+ if (statusOnNext === "success") {
561
561
  return response;
562
562
  }
563
+ if (statusOnNext === "error") {
564
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, fetchOptions);
565
+ if (config.retry && statusCodes?.includes(response.status)) {
566
+ if (maxRetries > retries) {
567
+ retries++;
568
+ config.retryAttempts++;
569
+ config.errors.push({
570
+ attempt: config.retryAttempts,
571
+ error: httpError,
572
+ duration: perform.now()
573
+ });
574
+ perform.reset();
575
+ if (config.debug) {
576
+ console.log(`Request failed with status code ${response.status}, retrying...${retryDelay > 0 ? " in " + (incrementDelay ? retryDelay * retries : retryDelay) + "ms" : ""}`);
577
+ }
578
+ if (retryDelay > 0) {
579
+ await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
580
+ }
581
+ continue;
582
+ }
583
+ }
584
+ throw httpError;
585
+ }
563
586
  if (statusOnNext === "redirect") {
564
587
  const location = _stats.redirectUrl;
565
588
  if (!location) {
@@ -557,9 +557,32 @@ async function executeHttp2Request(fetchOptions, config, options, perform, fs, s
557
557
  }
558
558
  continue;
559
559
  }
560
- if (statusOnNext === "success" || statusOnNext === "error") {
560
+ if (statusOnNext === "success") {
561
561
  return response;
562
562
  }
563
+ if (statusOnNext === "error") {
564
+ const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, fetchOptions);
565
+ if (config.retry && statusCodes?.includes(response.status)) {
566
+ if (maxRetries > retries) {
567
+ retries++;
568
+ config.retryAttempts++;
569
+ config.errors.push({
570
+ attempt: config.retryAttempts,
571
+ error: httpError,
572
+ duration: perform.now()
573
+ });
574
+ perform.reset();
575
+ if (config.debug) {
576
+ console.log(`Request failed with status code ${response.status}, retrying...${retryDelay > 0 ? " in " + (incrementDelay ? retryDelay * retries : retryDelay) + "ms" : ""}`);
577
+ }
578
+ if (retryDelay > 0) {
579
+ await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
580
+ }
581
+ continue;
582
+ }
583
+ }
584
+ throw httpError;
585
+ }
563
586
  if (statusOnNext === "redirect") {
564
587
  const location = _stats.redirectUrl;
565
588
  if (!location) {