rezo 1.0.138 → 1.0.139

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 (52) hide show
  1. package/dist/adapters/curl.cjs +5 -1
  2. package/dist/adapters/curl.js +5 -1
  3. package/dist/adapters/entries/curl.d.ts +34 -1
  4. package/dist/adapters/entries/fetch.d.ts +34 -1
  5. package/dist/adapters/entries/http.d.ts +34 -1
  6. package/dist/adapters/entries/http2.d.ts +34 -1
  7. package/dist/adapters/entries/react-native.cjs +6 -6
  8. package/dist/adapters/entries/react-native.d.ts +34 -1
  9. package/dist/adapters/entries/xhr.d.ts +34 -1
  10. package/dist/adapters/fetch.cjs +5 -0
  11. package/dist/adapters/fetch.js +5 -0
  12. package/dist/adapters/http.cjs +16 -0
  13. package/dist/adapters/http.js +16 -0
  14. package/dist/adapters/http2.cjs +5 -0
  15. package/dist/adapters/http2.js +5 -0
  16. package/dist/adapters/index.cjs +10 -10
  17. package/dist/adapters/index.d.ts +33 -0
  18. package/dist/adapters/react-native.cjs +6 -0
  19. package/dist/adapters/react-native.js +6 -0
  20. package/dist/adapters/xhr.cjs +5 -1
  21. package/dist/adapters/xhr.js +5 -1
  22. package/dist/cache/index.cjs +9 -9
  23. package/dist/cookies/cookie-jar.cjs +4 -4
  24. package/dist/cookies/index.cjs +10 -10
  25. package/dist/crawler/index.cjs +42 -42
  26. package/dist/crawler/plugin/index.cjs +1 -1
  27. package/dist/crawler.d.ts +33 -0
  28. package/dist/entries/crawler.cjs +24 -24
  29. package/dist/index.cjs +58 -58
  30. package/dist/index.d.ts +34 -1
  31. package/dist/internal/agents/index.cjs +14 -14
  32. package/dist/platform/browser.d.ts +34 -1
  33. package/dist/platform/bun.d.ts +34 -1
  34. package/dist/platform/deno.d.ts +34 -1
  35. package/dist/platform/node.d.ts +34 -1
  36. package/dist/platform/react-native.cjs +6 -6
  37. package/dist/platform/react-native.d.ts +34 -1
  38. package/dist/platform/worker.d.ts +34 -1
  39. package/dist/proxy/index.cjs +4 -4
  40. package/dist/queue/index.cjs +8 -8
  41. package/dist/responses/universal/index.cjs +11 -11
  42. package/dist/stealth/index.cjs +17 -17
  43. package/dist/stealth/profiles/index.cjs +10 -10
  44. package/dist/utils/debug-error-dump.cjs +59 -0
  45. package/dist/utils/debug-error-dump.js +56 -0
  46. package/dist/utils/http-config.cjs +5 -1
  47. package/dist/utils/http-config.js +5 -1
  48. package/dist/version.cjs +1 -1
  49. package/dist/version.js +1 -1
  50. package/dist/wget/index.cjs +51 -51
  51. package/dist/wget/index.d.ts +33 -0
  52. package/package.json +1 -1
@@ -11,6 +11,7 @@ const { RezoCookieJar, Cookie } = require('../cookies/cookie-jar.cjs');
11
11
  const RezoFormData = require('../utils/form-data.cjs');
12
12
  const { existsSync } = require("node:fs");
13
13
  const { getDefaultConfig, prepareHTTPOptions, calculateRetryDelay, shouldRetry } = require('../utils/http-config.cjs');
14
+ const { debugErrorDump } = require('../utils/debug-error-dump.cjs');
14
15
  const { handleRateLimitWait, shouldWaitOnStatus } = require('../utils/rate-limit-wait.cjs');
15
16
  const { RezoHeaders } = require('../utils/headers.cjs');
16
17
  const { StreamResponse } = require('../responses/stream.cjs');
@@ -2470,12 +2471,15 @@ async function executeRequest(options, defaultOptions, jar) {
2470
2471
  }
2471
2472
  }
2472
2473
  }
2474
+ debugErrorDump(config, error);
2473
2475
  throw error;
2474
2476
  }
2475
2477
  if (proxyManager && selectedProxy) {
2476
2478
  proxyManager.reportFailure(selectedProxy, error);
2477
2479
  }
2478
- throw buildSmartError(config, originalRequest, error);
2480
+ const smartError = buildSmartError(config, originalRequest, error);
2481
+ debugErrorDump(config, smartError);
2482
+ throw smartError;
2479
2483
  }
2480
2484
  }
2481
2485
  }
@@ -11,6 +11,7 @@ import { RezoCookieJar, Cookie } from '../cookies/cookie-jar.js';
11
11
  import RezoFormData from '../utils/form-data.js';
12
12
  import { existsSync } from "node:fs";
13
13
  import { getDefaultConfig, prepareHTTPOptions, calculateRetryDelay, shouldRetry } from '../utils/http-config.js';
14
+ import { debugErrorDump } from '../utils/debug-error-dump.js';
14
15
  import { handleRateLimitWait, shouldWaitOnStatus } from '../utils/rate-limit-wait.js';
15
16
  import { RezoHeaders } from '../utils/headers.js';
16
17
  import { StreamResponse } from '../responses/stream.js';
@@ -2470,12 +2471,15 @@ export async function executeRequest(options, defaultOptions, jar) {
2470
2471
  }
2471
2472
  }
2472
2473
  }
2474
+ debugErrorDump(config, error);
2473
2475
  throw error;
2474
2476
  }
2475
2477
  if (proxyManager && selectedProxy) {
2476
2478
  proxyManager.reportFailure(selectedProxy, error);
2477
2479
  }
2478
- throw buildSmartError(config, originalRequest, error);
2480
+ const smartError = buildSmartError(config, originalRequest, error);
2481
+ debugErrorDump(config, smartError);
2482
+ throw smartError;
2479
2483
  }
2480
2484
  }
2481
2485
  }
@@ -761,6 +761,12 @@ export interface RezoResponse<T = any> {
761
761
  contentLength: number;
762
762
  urls: string[];
763
763
  config: RezoConfig;
764
+ /**
765
+ * Present (true) only when `acceptPartialBody: true` salvaged a body whose
766
+ * connection was torn down before a clean end-of-stream — the data may be
767
+ * complete or may be missing its tail.
768
+ */
769
+ truncated?: boolean;
764
770
  }
765
771
  /**
766
772
  * Platform-agnostic base interface for event-emitting responses
@@ -2767,6 +2773,31 @@ export interface RezoRequestConfig<D = any> {
2767
2773
  maxRedirects?: number;
2768
2774
  /** Whether to automatically decompress response data */
2769
2775
  decompress?: boolean;
2776
+ /**
2777
+ * Accept response bodies that arrive without a clean end-of-stream.
2778
+ *
2779
+ * Some servers send the complete payload and then reset the connection
2780
+ * instead of closing it cleanly (or advertise a Content-Length larger than
2781
+ * what they send). Node reports this as `aborted`/`ECONNRESET` even though
2782
+ * the data may be complete and usable.
2783
+ *
2784
+ * With `acceptPartialBody: true`, if response headers passed validation and
2785
+ * at least one body byte arrived, the request **resolves normally** with
2786
+ * whatever was received instead of throwing. The response is marked with
2787
+ * `truncated: true` so you can decide whether to trust it.
2788
+ *
2789
+ * Off by default: a torn connection usually means missing data, and
2790
+ * silently returning an incomplete body is the more dangerous default.
2791
+ *
2792
+ * @example
2793
+ * ```typescript
2794
+ * const res = await rezo.get(url, { acceptPartialBody: true });
2795
+ * if (res.truncated) console.warn('body may be incomplete');
2796
+ * ```
2797
+ *
2798
+ * @default false
2799
+ */
2800
+ acceptPartialBody?: boolean;
2770
2801
  /**
2771
2802
  * Whether to keep TCP connections alive for reuse across multiple requests.
2772
2803
  *
@@ -4015,6 +4046,8 @@ export interface RezoDefaultOptions {
4015
4046
  decompress?: boolean;
4016
4047
  /** Whether to keep the connection alive for reuse */
4017
4048
  keepAlive?: boolean;
4049
+ /** Accept bodies whose connection was torn down before a clean end-of-stream (response gets `truncated: true`) */
4050
+ acceptPartialBody?: boolean;
4018
4051
  /** Whether to detect and prevent redirect cycles */
4019
4052
  enableRedirectCycleDetection?: boolean;
4020
4053
  /** Whether to send cookies and authorization headers with cross-origin requests */
@@ -8583,7 +8616,7 @@ export interface RezoInstance extends Rezo, RezoCallable {
8583
8616
  *
8584
8617
  * IMPORTANT: Update these values when bumping package version.
8585
8618
  */
8586
- export declare const VERSION = "1.0.138";
8619
+ export declare const VERSION = "1.0.139";
8587
8620
  export declare const isRezoError: typeof RezoError.isRezoError;
8588
8621
  export declare const Cancel: typeof RezoError;
8589
8622
  export declare const CancelToken: {
@@ -759,6 +759,12 @@ export interface RezoResponse<T = any> {
759
759
  contentLength: number;
760
760
  urls: string[];
761
761
  config: RezoConfig;
762
+ /**
763
+ * Present (true) only when `acceptPartialBody: true` salvaged a body whose
764
+ * connection was torn down before a clean end-of-stream — the data may be
765
+ * complete or may be missing its tail.
766
+ */
767
+ truncated?: boolean;
762
768
  }
763
769
  /**
764
770
  * Platform-agnostic base interface for event-emitting responses
@@ -3035,6 +3041,8 @@ export interface RezoDefaultOptions {
3035
3041
  decompress?: boolean;
3036
3042
  /** Whether to keep the connection alive for reuse */
3037
3043
  keepAlive?: boolean;
3044
+ /** Accept bodies whose connection was torn down before a clean end-of-stream (response gets `truncated: true`) */
3045
+ acceptPartialBody?: boolean;
3038
3046
  /** Whether to detect and prevent redirect cycles */
3039
3047
  enableRedirectCycleDetection?: boolean;
3040
3048
  /** Whether to send cookies and authorization headers with cross-origin requests */
@@ -4094,6 +4102,31 @@ export interface RezoRequestConfig<D = any> {
4094
4102
  maxRedirects?: number;
4095
4103
  /** Whether to automatically decompress response data */
4096
4104
  decompress?: boolean;
4105
+ /**
4106
+ * Accept response bodies that arrive without a clean end-of-stream.
4107
+ *
4108
+ * Some servers send the complete payload and then reset the connection
4109
+ * instead of closing it cleanly (or advertise a Content-Length larger than
4110
+ * what they send). Node reports this as `aborted`/`ECONNRESET` even though
4111
+ * the data may be complete and usable.
4112
+ *
4113
+ * With `acceptPartialBody: true`, if response headers passed validation and
4114
+ * at least one body byte arrived, the request **resolves normally** with
4115
+ * whatever was received instead of throwing. The response is marked with
4116
+ * `truncated: true` so you can decide whether to trust it.
4117
+ *
4118
+ * Off by default: a torn connection usually means missing data, and
4119
+ * silently returning an incomplete body is the more dangerous default.
4120
+ *
4121
+ * @example
4122
+ * ```typescript
4123
+ * const res = await rezo.get(url, { acceptPartialBody: true });
4124
+ * if (res.truncated) console.warn('body may be incomplete');
4125
+ * ```
4126
+ *
4127
+ * @default false
4128
+ */
4129
+ acceptPartialBody?: boolean;
4097
4130
  /**
4098
4131
  * Whether to keep TCP connections alive for reuse across multiple requests.
4099
4132
  *
@@ -6098,7 +6131,7 @@ export interface RezoInstance extends Rezo, RezoCallable {
6098
6131
  *
6099
6132
  * IMPORTANT: Update these values when bumping package version.
6100
6133
  */
6101
- export declare const VERSION = "1.0.138";
6134
+ export declare const VERSION = "1.0.139";
6102
6135
  export declare const isRezoError: typeof RezoError.isRezoError;
6103
6136
  export declare const Cancel: typeof RezoError;
6104
6137
  export declare const CancelToken: {
@@ -759,6 +759,12 @@ export interface RezoResponse<T = any> {
759
759
  contentLength: number;
760
760
  urls: string[];
761
761
  config: RezoConfig;
762
+ /**
763
+ * Present (true) only when `acceptPartialBody: true` salvaged a body whose
764
+ * connection was torn down before a clean end-of-stream — the data may be
765
+ * complete or may be missing its tail.
766
+ */
767
+ truncated?: boolean;
762
768
  }
763
769
  /**
764
770
  * Platform-agnostic base interface for event-emitting responses
@@ -3035,6 +3041,8 @@ export interface RezoDefaultOptions {
3035
3041
  decompress?: boolean;
3036
3042
  /** Whether to keep the connection alive for reuse */
3037
3043
  keepAlive?: boolean;
3044
+ /** Accept bodies whose connection was torn down before a clean end-of-stream (response gets `truncated: true`) */
3045
+ acceptPartialBody?: boolean;
3038
3046
  /** Whether to detect and prevent redirect cycles */
3039
3047
  enableRedirectCycleDetection?: boolean;
3040
3048
  /** Whether to send cookies and authorization headers with cross-origin requests */
@@ -4094,6 +4102,31 @@ export interface RezoRequestConfig<D = any> {
4094
4102
  maxRedirects?: number;
4095
4103
  /** Whether to automatically decompress response data */
4096
4104
  decompress?: boolean;
4105
+ /**
4106
+ * Accept response bodies that arrive without a clean end-of-stream.
4107
+ *
4108
+ * Some servers send the complete payload and then reset the connection
4109
+ * instead of closing it cleanly (or advertise a Content-Length larger than
4110
+ * what they send). Node reports this as `aborted`/`ECONNRESET` even though
4111
+ * the data may be complete and usable.
4112
+ *
4113
+ * With `acceptPartialBody: true`, if response headers passed validation and
4114
+ * at least one body byte arrived, the request **resolves normally** with
4115
+ * whatever was received instead of throwing. The response is marked with
4116
+ * `truncated: true` so you can decide whether to trust it.
4117
+ *
4118
+ * Off by default: a torn connection usually means missing data, and
4119
+ * silently returning an incomplete body is the more dangerous default.
4120
+ *
4121
+ * @example
4122
+ * ```typescript
4123
+ * const res = await rezo.get(url, { acceptPartialBody: true });
4124
+ * if (res.truncated) console.warn('body may be incomplete');
4125
+ * ```
4126
+ *
4127
+ * @default false
4128
+ */
4129
+ acceptPartialBody?: boolean;
4097
4130
  /**
4098
4131
  * Whether to keep TCP connections alive for reuse across multiple requests.
4099
4132
  *
@@ -6173,7 +6206,7 @@ export declare function getSocketTelemetry(socket: Socket): SocketTelemetry | un
6173
6206
  *
6174
6207
  * IMPORTANT: Update these values when bumping package version.
6175
6208
  */
6176
- export declare const VERSION = "1.0.138";
6209
+ export declare const VERSION = "1.0.139";
6177
6210
  /**
6178
6211
  * Type guard to check if an error is a RezoError instance.
6179
6212
  */
@@ -760,6 +760,12 @@ export interface RezoResponse<T = any> {
760
760
  contentLength: number;
761
761
  urls: string[];
762
762
  config: RezoConfig;
763
+ /**
764
+ * Present (true) only when `acceptPartialBody: true` salvaged a body whose
765
+ * connection was torn down before a clean end-of-stream — the data may be
766
+ * complete or may be missing its tail.
767
+ */
768
+ truncated?: boolean;
763
769
  }
764
770
  /**
765
771
  * Platform-agnostic base interface for event-emitting responses
@@ -3036,6 +3042,8 @@ export interface RezoDefaultOptions {
3036
3042
  decompress?: boolean;
3037
3043
  /** Whether to keep the connection alive for reuse */
3038
3044
  keepAlive?: boolean;
3045
+ /** Accept bodies whose connection was torn down before a clean end-of-stream (response gets `truncated: true`) */
3046
+ acceptPartialBody?: boolean;
3039
3047
  /** Whether to detect and prevent redirect cycles */
3040
3048
  enableRedirectCycleDetection?: boolean;
3041
3049
  /** Whether to send cookies and authorization headers with cross-origin requests */
@@ -4095,6 +4103,31 @@ export interface RezoRequestConfig<D = any> {
4095
4103
  maxRedirects?: number;
4096
4104
  /** Whether to automatically decompress response data */
4097
4105
  decompress?: boolean;
4106
+ /**
4107
+ * Accept response bodies that arrive without a clean end-of-stream.
4108
+ *
4109
+ * Some servers send the complete payload and then reset the connection
4110
+ * instead of closing it cleanly (or advertise a Content-Length larger than
4111
+ * what they send). Node reports this as `aborted`/`ECONNRESET` even though
4112
+ * the data may be complete and usable.
4113
+ *
4114
+ * With `acceptPartialBody: true`, if response headers passed validation and
4115
+ * at least one body byte arrived, the request **resolves normally** with
4116
+ * whatever was received instead of throwing. The response is marked with
4117
+ * `truncated: true` so you can decide whether to trust it.
4118
+ *
4119
+ * Off by default: a torn connection usually means missing data, and
4120
+ * silently returning an incomplete body is the more dangerous default.
4121
+ *
4122
+ * @example
4123
+ * ```typescript
4124
+ * const res = await rezo.get(url, { acceptPartialBody: true });
4125
+ * if (res.truncated) console.warn('body may be incomplete');
4126
+ * ```
4127
+ *
4128
+ * @default false
4129
+ */
4130
+ acceptPartialBody?: boolean;
4098
4131
  /**
4099
4132
  * Whether to keep TCP connections alive for reuse across multiple requests.
4100
4133
  *
@@ -6124,7 +6157,7 @@ export interface RezoInstance extends Rezo, RezoCallable {
6124
6157
  *
6125
6158
  * IMPORTANT: Update these values when bumping package version.
6126
6159
  */
6127
- export declare const VERSION = "1.0.138";
6160
+ export declare const VERSION = "1.0.139";
6128
6161
  export declare const isRezoError: typeof RezoError.isRezoError;
6129
6162
  export declare const Cancel: typeof RezoError;
6130
6163
  export declare const CancelToken: {
@@ -6,12 +6,12 @@ const { RezoFormData } = require('../../utils/form-data.cjs');
6
6
  const { RezoCookieJar, Cookie } = require('../../cookies/cookie-jar.cjs');
7
7
  const { createDefaultHooks, mergeHooks } = require('../../core/hooks.cjs');
8
8
  const { VERSION } = require('../../version.cjs');
9
- const _mod_uyu65l = require('../../platform/react-native-providers.cjs');
10
- exports.createFetchStreamTransport = _mod_uyu65l.createFetchStreamTransport;
11
- exports.createExpoFileSystemAdapter = _mod_uyu65l.createExpoFileSystemAdapter;
12
- exports.createReactNativeFsAdapter = _mod_uyu65l.createReactNativeFsAdapter;
13
- exports.createNetInfoProvider = _mod_uyu65l.createNetInfoProvider;
14
- exports.createExpoBackgroundTaskProvider = _mod_uyu65l.createExpoBackgroundTaskProvider;;
9
+ const _mod_hxyeij = require('../../platform/react-native-providers.cjs');
10
+ exports.createFetchStreamTransport = _mod_hxyeij.createFetchStreamTransport;
11
+ exports.createExpoFileSystemAdapter = _mod_hxyeij.createExpoFileSystemAdapter;
12
+ exports.createReactNativeFsAdapter = _mod_hxyeij.createReactNativeFsAdapter;
13
+ exports.createNetInfoProvider = _mod_hxyeij.createNetInfoProvider;
14
+ exports.createExpoBackgroundTaskProvider = _mod_hxyeij.createExpoBackgroundTaskProvider;;
15
15
  exports.Rezo = Rezo;
16
16
  exports.RezoError = RezoError;
17
17
  exports.RezoErrorCode = RezoErrorCode;
@@ -759,6 +759,12 @@ export interface RezoResponse<T = any> {
759
759
  contentLength: number;
760
760
  urls: string[];
761
761
  config: RezoConfig;
762
+ /**
763
+ * Present (true) only when `acceptPartialBody: true` salvaged a body whose
764
+ * connection was torn down before a clean end-of-stream — the data may be
765
+ * complete or may be missing its tail.
766
+ */
767
+ truncated?: boolean;
762
768
  }
763
769
  /**
764
770
  * Platform-agnostic base interface for event-emitting responses
@@ -3035,6 +3041,8 @@ export interface RezoDefaultOptions {
3035
3041
  decompress?: boolean;
3036
3042
  /** Whether to keep the connection alive for reuse */
3037
3043
  keepAlive?: boolean;
3044
+ /** Accept bodies whose connection was torn down before a clean end-of-stream (response gets `truncated: true`) */
3045
+ acceptPartialBody?: boolean;
3038
3046
  /** Whether to detect and prevent redirect cycles */
3039
3047
  enableRedirectCycleDetection?: boolean;
3040
3048
  /** Whether to send cookies and authorization headers with cross-origin requests */
@@ -4094,6 +4102,31 @@ export interface RezoRequestConfig<D = any> {
4094
4102
  maxRedirects?: number;
4095
4103
  /** Whether to automatically decompress response data */
4096
4104
  decompress?: boolean;
4105
+ /**
4106
+ * Accept response bodies that arrive without a clean end-of-stream.
4107
+ *
4108
+ * Some servers send the complete payload and then reset the connection
4109
+ * instead of closing it cleanly (or advertise a Content-Length larger than
4110
+ * what they send). Node reports this as `aborted`/`ECONNRESET` even though
4111
+ * the data may be complete and usable.
4112
+ *
4113
+ * With `acceptPartialBody: true`, if response headers passed validation and
4114
+ * at least one body byte arrived, the request **resolves normally** with
4115
+ * whatever was received instead of throwing. The response is marked with
4116
+ * `truncated: true` so you can decide whether to trust it.
4117
+ *
4118
+ * Off by default: a torn connection usually means missing data, and
4119
+ * silently returning an incomplete body is the more dangerous default.
4120
+ *
4121
+ * @example
4122
+ * ```typescript
4123
+ * const res = await rezo.get(url, { acceptPartialBody: true });
4124
+ * if (res.truncated) console.warn('body may be incomplete');
4125
+ * ```
4126
+ *
4127
+ * @default false
4128
+ */
4129
+ acceptPartialBody?: boolean;
4097
4130
  /**
4098
4131
  * Whether to keep TCP connections alive for reuse across multiple requests.
4099
4132
  *
@@ -6098,7 +6131,7 @@ export interface RezoInstance extends Rezo, RezoCallable {
6098
6131
  *
6099
6132
  * IMPORTANT: Update these values when bumping package version.
6100
6133
  */
6101
- export declare const VERSION = "1.0.138";
6134
+ export declare const VERSION = "1.0.139";
6102
6135
  export interface ExpoFileSystemFileLike {
6103
6136
  uri?: string;
6104
6137
  size?: number;
@@ -759,6 +759,12 @@ export interface RezoResponse<T = any> {
759
759
  contentLength: number;
760
760
  urls: string[];
761
761
  config: RezoConfig;
762
+ /**
763
+ * Present (true) only when `acceptPartialBody: true` salvaged a body whose
764
+ * connection was torn down before a clean end-of-stream — the data may be
765
+ * complete or may be missing its tail.
766
+ */
767
+ truncated?: boolean;
762
768
  }
763
769
  /**
764
770
  * Platform-agnostic base interface for event-emitting responses
@@ -3035,6 +3041,8 @@ export interface RezoDefaultOptions {
3035
3041
  decompress?: boolean;
3036
3042
  /** Whether to keep the connection alive for reuse */
3037
3043
  keepAlive?: boolean;
3044
+ /** Accept bodies whose connection was torn down before a clean end-of-stream (response gets `truncated: true`) */
3045
+ acceptPartialBody?: boolean;
3038
3046
  /** Whether to detect and prevent redirect cycles */
3039
3047
  enableRedirectCycleDetection?: boolean;
3040
3048
  /** Whether to send cookies and authorization headers with cross-origin requests */
@@ -4094,6 +4102,31 @@ export interface RezoRequestConfig<D = any> {
4094
4102
  maxRedirects?: number;
4095
4103
  /** Whether to automatically decompress response data */
4096
4104
  decompress?: boolean;
4105
+ /**
4106
+ * Accept response bodies that arrive without a clean end-of-stream.
4107
+ *
4108
+ * Some servers send the complete payload and then reset the connection
4109
+ * instead of closing it cleanly (or advertise a Content-Length larger than
4110
+ * what they send). Node reports this as `aborted`/`ECONNRESET` even though
4111
+ * the data may be complete and usable.
4112
+ *
4113
+ * With `acceptPartialBody: true`, if response headers passed validation and
4114
+ * at least one body byte arrived, the request **resolves normally** with
4115
+ * whatever was received instead of throwing. The response is marked with
4116
+ * `truncated: true` so you can decide whether to trust it.
4117
+ *
4118
+ * Off by default: a torn connection usually means missing data, and
4119
+ * silently returning an incomplete body is the more dangerous default.
4120
+ *
4121
+ * @example
4122
+ * ```typescript
4123
+ * const res = await rezo.get(url, { acceptPartialBody: true });
4124
+ * if (res.truncated) console.warn('body may be incomplete');
4125
+ * ```
4126
+ *
4127
+ * @default false
4128
+ */
4129
+ acceptPartialBody?: boolean;
4097
4130
  /**
4098
4131
  * Whether to keep TCP connections alive for reuse across multiple requests.
4099
4132
  *
@@ -6098,7 +6131,7 @@ export interface RezoInstance extends Rezo, RezoCallable {
6098
6131
  *
6099
6132
  * IMPORTANT: Update these values when bumping package version.
6100
6133
  */
6101
- export declare const VERSION = "1.0.138";
6134
+ export declare const VERSION = "1.0.139";
6102
6135
  export declare const isRezoError: typeof RezoError.isRezoError;
6103
6136
  export declare const Cancel: typeof RezoError;
6104
6137
  export declare const CancelToken: {
@@ -12,6 +12,7 @@ const { isSameDomain, RezoPerformance } = require('../utils/tools.cjs');
12
12
  const { ResponseCache } = require('../cache/universal-response-cache.cjs');
13
13
  const { handleRateLimitWait, shouldWaitOnStatus } = require('../utils/rate-limit-wait.cjs');
14
14
  const { resolveTimeoutMs } = require('../utils/staged-timeout.cjs');
15
+ const { debugErrorDump } = require('../utils/debug-error-dump.cjs');
15
16
  const { importNodeModule } = require('../utils/node-runtime.cjs');
16
17
  const Environment = {
17
18
  isNode: typeof process !== "undefined" && process.versions?.node,
@@ -476,16 +477,19 @@ async function executeRequest(options, defaultOptions, jar) {
476
477
  const res = executeFetchRequest(fetchOptions, mainConfig, options, perform, streamResponse, downloadResponse, uploadResponse, jar);
477
478
  if (streamResponse) {
478
479
  res.catch((err) => {
480
+ debugErrorDump(mainConfig, err);
479
481
  streamResponse.emit("error", err);
480
482
  });
481
483
  return streamResponse;
482
484
  } else if (downloadResponse) {
483
485
  res.catch((err) => {
486
+ debugErrorDump(mainConfig, err);
484
487
  downloadResponse.emit("error", err);
485
488
  });
486
489
  return downloadResponse;
487
490
  } else if (uploadResponse) {
488
491
  res.catch((err) => {
492
+ debugErrorDump(mainConfig, err);
489
493
  uploadResponse.emit("error", err);
490
494
  });
491
495
  return uploadResponse;
@@ -506,6 +510,7 @@ async function executeRequest(options, defaultOptions, jar) {
506
510
  }
507
511
  return response;
508
512
  } catch (error) {
513
+ debugErrorDump(mainConfig, error);
509
514
  throw error;
510
515
  }
511
516
  }
@@ -12,6 +12,7 @@ import { isSameDomain, RezoPerformance } from '../utils/tools.js';
12
12
  import { ResponseCache } from '../cache/universal-response-cache.js';
13
13
  import { handleRateLimitWait, shouldWaitOnStatus } from '../utils/rate-limit-wait.js';
14
14
  import { resolveTimeoutMs } from '../utils/staged-timeout.js';
15
+ import { debugErrorDump } from '../utils/debug-error-dump.js';
15
16
  import { importNodeModule } from '../utils/node-runtime.js';
16
17
  const Environment = {
17
18
  isNode: typeof process !== "undefined" && process.versions?.node,
@@ -476,16 +477,19 @@ export async function executeRequest(options, defaultOptions, jar) {
476
477
  const res = executeFetchRequest(fetchOptions, mainConfig, options, perform, streamResponse, downloadResponse, uploadResponse, jar);
477
478
  if (streamResponse) {
478
479
  res.catch((err) => {
480
+ debugErrorDump(mainConfig, err);
479
481
  streamResponse.emit("error", err);
480
482
  });
481
483
  return streamResponse;
482
484
  } else if (downloadResponse) {
483
485
  res.catch((err) => {
486
+ debugErrorDump(mainConfig, err);
484
487
  downloadResponse.emit("error", err);
485
488
  });
486
489
  return downloadResponse;
487
490
  } else if (uploadResponse) {
488
491
  res.catch((err) => {
492
+ debugErrorDump(mainConfig, err);
489
493
  uploadResponse.emit("error", err);
490
494
  });
491
495
  return uploadResponse;
@@ -506,6 +510,7 @@ export async function executeRequest(options, defaultOptions, jar) {
506
510
  }
507
511
  return response;
508
512
  } catch (error) {
513
+ debugErrorDump(mainConfig, error);
509
514
  throw error;
510
515
  }
511
516
  }
@@ -21,6 +21,7 @@ const { ResponseCache } = require('../cache/response-cache.cjs');
21
21
  const { getGlobalAgentPool } = require('../utils/agent-pool.cjs');
22
22
  const { buildTlsOptions } = require('../stealth/tls-fingerprint.cjs');
23
23
  const { StagedTimeoutManager, parseStagedTimeouts, resolveTimeoutMs } = require('../utils/staged-timeout.cjs');
24
+ const { debugErrorDump } = require('../utils/debug-error-dump.cjs');
24
25
  const { handleRateLimitWait, shouldWaitOnStatus } = require('../utils/rate-limit-wait.cjs');
25
26
  const { getSocketTelemetry, beginRequestContext } = require('../utils/socket-telemetry.cjs');
26
27
  const dns = require("node:dns");
@@ -70,6 +71,7 @@ const debugLog = {
70
71
  console.log(`[Rezo Track] ✗ Max retries reached`);
71
72
  }
72
73
  },
74
+ errorDump: (config, error) => debugErrorDump(config, error),
73
75
  response: (config, status, statusText, duration) => {
74
76
  if (config.debug) {
75
77
  console.log(`[Rezo Debug] Response: ${status} ${statusText} (${duration.toFixed(2)}ms)`);
@@ -312,16 +314,19 @@ async function executeRequest(options, defaultOptions, jar) {
312
314
  const res = executeHttp1Request(config.fetchOptions, mainConfig, config.options, perform, d_options.fs, streamResponse, downloadResponse, uploadResponse, jar);
313
315
  if (streamResponse) {
314
316
  res.catch((err) => {
317
+ debugErrorDump(mainConfig, err);
315
318
  streamResponse.emit("error", err);
316
319
  });
317
320
  return streamResponse;
318
321
  } else if (downloadResponse) {
319
322
  res.catch((err) => {
323
+ debugErrorDump(mainConfig, err);
320
324
  downloadResponse.emit("error", err);
321
325
  });
322
326
  return downloadResponse;
323
327
  } else if (uploadResponse) {
324
328
  res.catch((err) => {
329
+ debugErrorDump(mainConfig, err);
325
330
  uploadResponse.emit("error", err);
326
331
  });
327
332
  return uploadResponse;
@@ -366,6 +371,7 @@ async function executeRequest(options, defaultOptions, jar) {
366
371
  }
367
372
  }
368
373
  }
374
+ debugErrorDump(mainConfig, error);
369
375
  throw error;
370
376
  }
371
377
  }
@@ -1106,6 +1112,16 @@ async function request(config, fetchOptions, requestCount, timing, _stats, _resp
1106
1112
  resolve(partialResponse);
1107
1113
  return;
1108
1114
  }
1115
+ if (fetchOptions.acceptPartialBody && data.length > 0 && statusCode) {
1116
+ const _validateStatus = fetchOptions.validateStatus ?? ((s) => s >= 200 && s < 300);
1117
+ if (fetchOptions.validateStatus === null || _validateStatus(statusCode)) {
1118
+ _stats.statusOnNext = "success";
1119
+ const salvagedResponse = buildResponseFromIncoming(res, data, config, url.toString(), buildUrlTree(config, url.toString()), undefined, undefined, contentLengthCounter);
1120
+ salvagedResponse.truncated = true;
1121
+ resolve(salvagedResponse);
1122
+ return;
1123
+ }
1124
+ }
1109
1125
  const isNetworkError = err.code && ["ECONNRESET", "ECONNABORTED", "ETIMEDOUT", "EPIPE", "ENOTFOUND", "ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ERR_STREAM_PREMATURE_CLOSE"].includes(err.code);
1110
1126
  if (isNetworkError) {
1111
1127
  const partialResponse = buildResponseFromIncoming(res, data, config, url.toString(), buildUrlTree(config, url.toString()), undefined, undefined, contentLengthCounter);
@@ -21,6 +21,7 @@ import { ResponseCache } from '../cache/response-cache.js';
21
21
  import { getGlobalAgentPool } from '../utils/agent-pool.js';
22
22
  import { buildTlsOptions } from '../stealth/tls-fingerprint.js';
23
23
  import { StagedTimeoutManager, parseStagedTimeouts, resolveTimeoutMs } from '../utils/staged-timeout.js';
24
+ import { debugErrorDump } from '../utils/debug-error-dump.js';
24
25
  import { handleRateLimitWait, shouldWaitOnStatus } from '../utils/rate-limit-wait.js';
25
26
  import { getSocketTelemetry, beginRequestContext } from '../utils/socket-telemetry.js';
26
27
  import dns from "node:dns";
@@ -70,6 +71,7 @@ const debugLog = {
70
71
  console.log(`[Rezo Track] ✗ Max retries reached`);
71
72
  }
72
73
  },
74
+ errorDump: (config, error) => debugErrorDump(config, error),
73
75
  response: (config, status, statusText, duration) => {
74
76
  if (config.debug) {
75
77
  console.log(`[Rezo Debug] Response: ${status} ${statusText} (${duration.toFixed(2)}ms)`);
@@ -312,16 +314,19 @@ export async function executeRequest(options, defaultOptions, jar) {
312
314
  const res = executeHttp1Request(config.fetchOptions, mainConfig, config.options, perform, d_options.fs, streamResponse, downloadResponse, uploadResponse, jar);
313
315
  if (streamResponse) {
314
316
  res.catch((err) => {
317
+ debugErrorDump(mainConfig, err);
315
318
  streamResponse.emit("error", err);
316
319
  });
317
320
  return streamResponse;
318
321
  } else if (downloadResponse) {
319
322
  res.catch((err) => {
323
+ debugErrorDump(mainConfig, err);
320
324
  downloadResponse.emit("error", err);
321
325
  });
322
326
  return downloadResponse;
323
327
  } else if (uploadResponse) {
324
328
  res.catch((err) => {
329
+ debugErrorDump(mainConfig, err);
325
330
  uploadResponse.emit("error", err);
326
331
  });
327
332
  return uploadResponse;
@@ -366,6 +371,7 @@ export async function executeRequest(options, defaultOptions, jar) {
366
371
  }
367
372
  }
368
373
  }
374
+ debugErrorDump(mainConfig, error);
369
375
  throw error;
370
376
  }
371
377
  }
@@ -1106,6 +1112,16 @@ async function request(config, fetchOptions, requestCount, timing, _stats, _resp
1106
1112
  resolve(partialResponse);
1107
1113
  return;
1108
1114
  }
1115
+ if (fetchOptions.acceptPartialBody && data.length > 0 && statusCode) {
1116
+ const _validateStatus = fetchOptions.validateStatus ?? ((s) => s >= 200 && s < 300);
1117
+ if (fetchOptions.validateStatus === null || _validateStatus(statusCode)) {
1118
+ _stats.statusOnNext = "success";
1119
+ const salvagedResponse = buildResponseFromIncoming(res, data, config, url.toString(), buildUrlTree(config, url.toString()), undefined, undefined, contentLengthCounter);
1120
+ salvagedResponse.truncated = true;
1121
+ resolve(salvagedResponse);
1122
+ return;
1123
+ }
1124
+ }
1109
1125
  const isNetworkError = err.code && ["ECONNRESET", "ECONNABORTED", "ETIMEDOUT", "EPIPE", "ENOTFOUND", "ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ERR_STREAM_PREMATURE_CLOSE"].includes(err.code);
1110
1126
  if (isNetworkError) {
1111
1127
  const partialResponse = buildResponseFromIncoming(res, data, config, url.toString(), buildUrlTree(config, url.toString()), undefined, undefined, contentLengthCounter);