rezo 1.0.27 → 1.0.29

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.
@@ -1158,9 +1158,11 @@ class CurlCommandBuilder {
1158
1158
  case "oauth1":
1159
1159
  case "aws4":
1160
1160
  case "custom":
1161
- if (auth.custom) {
1161
+ if (auth?.custom && typeof auth.custom === "object") {
1162
1162
  for (const [key, value] of Object.entries(auth.custom)) {
1163
- this.addArg("-H", `${key}: ${value}`);
1163
+ if (key && value !== undefined) {
1164
+ this.addArg("-H", `${key}: ${value}`);
1165
+ }
1164
1166
  }
1165
1167
  }
1166
1168
  break;
@@ -1158,9 +1158,11 @@ class CurlCommandBuilder {
1158
1158
  case "oauth1":
1159
1159
  case "aws4":
1160
1160
  case "custom":
1161
- if (auth.custom) {
1161
+ if (auth?.custom && typeof auth.custom === "object") {
1162
1162
  for (const [key, value] of Object.entries(auth.custom)) {
1163
- this.addArg("-H", `${key}: ${value}`);
1163
+ if (key && value !== undefined) {
1164
+ this.addArg("-H", `${key}: ${value}`);
1165
+ }
1164
1166
  }
1165
1167
  }
1166
1168
  break;
@@ -4,7 +4,7 @@ import { EventEmitter } from 'node:events';
4
4
  import { Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
5
5
  import { Agent as HttpsAgent } from 'node:https';
6
6
  import { Socket } from 'node:net';
7
- import { Readable, Writable, WritableOptions } from 'node:stream';
7
+ import { Readable, Readable as ReadableType, Writable, WritableOptions } from 'node:stream';
8
8
  import { SecureContext, TLSSocket } from 'node:tls';
9
9
  import { Cookie as TouchCookie, CookieJar as TouchCookieJar, CreateCookieOptions } from 'tough-cookie';
10
10
 
@@ -140,7 +140,6 @@ export declare class RezoHeaders extends Headers {
140
140
  string,
141
141
  string | string[]
142
142
  ]>;
143
- [util.inspect.custom](_depth: number, options: util.InspectOptionsStylized): string;
144
143
  get [Symbol.toStringTag](): string;
145
144
  }
146
145
  export interface SerializedCookie {
@@ -314,8 +313,8 @@ export interface ReadableOptions {
314
313
  highWaterMark?: number;
315
314
  encoding?: string;
316
315
  objectMode?: boolean;
317
- read?(this: Readable, size: number): void;
318
- destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void;
316
+ read?(this: ReadableType, size: number): void;
317
+ destroy?(this: ReadableType, error: Error | null, callback: (error: Error | null) => void): void;
319
318
  autoDestroy?: boolean;
320
319
  }
321
320
  export interface Options extends ReadableOptions {
@@ -4,7 +4,7 @@ import { EventEmitter } from 'node:events';
4
4
  import { Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
5
5
  import { Agent as HttpsAgent } from 'node:https';
6
6
  import { Socket } from 'node:net';
7
- import { Readable, Writable, WritableOptions } from 'node:stream';
7
+ import { Readable, Readable as ReadableType, Writable, WritableOptions } from 'node:stream';
8
8
  import { SecureContext, TLSSocket } from 'node:tls';
9
9
  import { Cookie as TouchCookie, CookieJar as TouchCookieJar, CreateCookieOptions } from 'tough-cookie';
10
10
 
@@ -140,7 +140,6 @@ export declare class RezoHeaders extends Headers {
140
140
  string,
141
141
  string | string[]
142
142
  ]>;
143
- [util.inspect.custom](_depth: number, options: util.InspectOptionsStylized): string;
144
143
  get [Symbol.toStringTag](): string;
145
144
  }
146
145
  export interface SerializedCookie {
@@ -314,8 +313,8 @@ export interface ReadableOptions {
314
313
  highWaterMark?: number;
315
314
  encoding?: string;
316
315
  objectMode?: boolean;
317
- read?(this: Readable, size: number): void;
318
- destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void;
316
+ read?(this: ReadableType, size: number): void;
317
+ destroy?(this: ReadableType, error: Error | null, callback: (error: Error | null) => void): void;
319
318
  autoDestroy?: boolean;
320
319
  }
321
320
  export interface Options extends ReadableOptions {
@@ -4,7 +4,7 @@ import { EventEmitter } from 'node:events';
4
4
  import { Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
5
5
  import { Agent as HttpsAgent } from 'node:https';
6
6
  import { Socket } from 'node:net';
7
- import { Readable, Writable, WritableOptions } from 'node:stream';
7
+ import { Readable, Readable as ReadableType, Writable, WritableOptions } from 'node:stream';
8
8
  import { SecureContext, TLSSocket } from 'node:tls';
9
9
  import { Cookie as TouchCookie, CookieJar as TouchCookieJar, CreateCookieOptions } from 'tough-cookie';
10
10
 
@@ -140,7 +140,6 @@ export declare class RezoHeaders extends Headers {
140
140
  string,
141
141
  string | string[]
142
142
  ]>;
143
- [util.inspect.custom](_depth: number, options: util.InspectOptionsStylized): string;
144
143
  get [Symbol.toStringTag](): string;
145
144
  }
146
145
  export interface SerializedCookie {
@@ -314,8 +313,8 @@ export interface ReadableOptions {
314
313
  highWaterMark?: number;
315
314
  encoding?: string;
316
315
  objectMode?: boolean;
317
- read?(this: Readable, size: number): void;
318
- destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void;
316
+ read?(this: ReadableType, size: number): void;
317
+ destroy?(this: ReadableType, error: Error | null, callback: (error: Error | null) => void): void;
319
318
  autoDestroy?: boolean;
320
319
  }
321
320
  export interface Options extends ReadableOptions {
@@ -4,7 +4,7 @@ import { EventEmitter } from 'node:events';
4
4
  import { Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
5
5
  import { Agent as HttpsAgent } from 'node:https';
6
6
  import { Socket } from 'node:net';
7
- import { Readable, Writable, WritableOptions } from 'node:stream';
7
+ import { Readable, Readable as ReadableType, Writable, WritableOptions } from 'node:stream';
8
8
  import { SecureContext, TLSSocket } from 'node:tls';
9
9
  import { Cookie as TouchCookie, CookieJar as TouchCookieJar, CreateCookieOptions } from 'tough-cookie';
10
10
 
@@ -140,7 +140,6 @@ export declare class RezoHeaders extends Headers {
140
140
  string,
141
141
  string | string[]
142
142
  ]>;
143
- [util.inspect.custom](_depth: number, options: util.InspectOptionsStylized): string;
144
143
  get [Symbol.toStringTag](): string;
145
144
  }
146
145
  export interface SerializedCookie {
@@ -314,8 +313,8 @@ export interface ReadableOptions {
314
313
  highWaterMark?: number;
315
314
  encoding?: string;
316
315
  objectMode?: boolean;
317
- read?(this: Readable, size: number): void;
318
- destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void;
316
+ read?(this: ReadableType, size: number): void;
317
+ destroy?(this: ReadableType, error: Error | null, callback: (error: Error | null) => void): void;
319
318
  autoDestroy?: boolean;
320
319
  }
321
320
  export interface Options extends ReadableOptions {
@@ -4,7 +4,7 @@ import { EventEmitter } from 'node:events';
4
4
  import { Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
5
5
  import { Agent as HttpsAgent } from 'node:https';
6
6
  import { Socket } from 'node:net';
7
- import { Readable, Writable, WritableOptions } from 'node:stream';
7
+ import { Readable, Readable as ReadableType, Writable, WritableOptions } from 'node:stream';
8
8
  import { SecureContext, TLSSocket } from 'node:tls';
9
9
  import { Cookie as TouchCookie, CookieJar as TouchCookieJar, CreateCookieOptions } from 'tough-cookie';
10
10
 
@@ -140,7 +140,6 @@ export declare class RezoHeaders extends Headers {
140
140
  string,
141
141
  string | string[]
142
142
  ]>;
143
- [util.inspect.custom](_depth: number, options: util.InspectOptionsStylized): string;
144
143
  get [Symbol.toStringTag](): string;
145
144
  }
146
145
  export interface SerializedCookie {
@@ -314,8 +313,8 @@ export interface ReadableOptions {
314
313
  highWaterMark?: number;
315
314
  encoding?: string;
316
315
  objectMode?: boolean;
317
- read?(this: Readable, size: number): void;
318
- destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void;
316
+ read?(this: ReadableType, size: number): void;
317
+ destroy?(this: ReadableType, error: Error | null, callback: (error: Error | null) => void): void;
319
318
  autoDestroy?: boolean;
320
319
  }
321
320
  export interface Options extends ReadableOptions {
@@ -4,7 +4,7 @@ import { EventEmitter } from 'node:events';
4
4
  import { Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
5
5
  import { Agent as HttpsAgent } from 'node:https';
6
6
  import { Socket } from 'node:net';
7
- import { Readable, Writable, WritableOptions } from 'node:stream';
7
+ import { Readable, Readable as ReadableType, Writable, WritableOptions } from 'node:stream';
8
8
  import { SecureContext, TLSSocket } from 'node:tls';
9
9
  import { Cookie as TouchCookie, CookieJar as TouchCookieJar, CreateCookieOptions } from 'tough-cookie';
10
10
 
@@ -140,7 +140,6 @@ export declare class RezoHeaders extends Headers {
140
140
  string,
141
141
  string | string[]
142
142
  ]>;
143
- [util.inspect.custom](_depth: number, options: util.InspectOptionsStylized): string;
144
143
  get [Symbol.toStringTag](): string;
145
144
  }
146
145
  export interface SerializedCookie {
@@ -314,8 +313,8 @@ export interface ReadableOptions {
314
313
  highWaterMark?: number;
315
314
  encoding?: string;
316
315
  objectMode?: boolean;
317
- read?(this: Readable, size: number): void;
318
- destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void;
316
+ read?(this: ReadableType, size: number): void;
317
+ destroy?(this: ReadableType, error: Error | null, callback: (error: Error | null) => void): void;
319
318
  autoDestroy?: boolean;
320
319
  }
321
320
  export interface Options extends ReadableOptions {
@@ -1,4 +1,3 @@
1
- const { URL } = require("node:url");
2
1
  const { RezoError } = require('../errors/rezo-error.cjs');
3
2
  const { buildSmartError, builErrorFromResponse, buildDownloadError } = require('../responses/buildError.cjs');
4
3
  const { RezoCookieJar } = require('../utils/cookies.cjs');
@@ -28,6 +27,85 @@ const Environment = {
28
27
  return typeof AbortController !== "undefined";
29
28
  }
30
29
  };
30
+ const debugLog = {
31
+ requestStart: (config, url, method) => {
32
+ if (config.debug) {
33
+ console.log(`
34
+ [Rezo Debug] ─────────────────────────────────────`);
35
+ console.log(`[Rezo Debug] ${method} ${url}`);
36
+ console.log(`[Rezo Debug] Request ID: ${config.requestId}`);
37
+ console.log(`[Rezo Debug] Adapter: fetch`);
38
+ if (config.originalRequest?.headers) {
39
+ const headers = config.originalRequest.headers instanceof RezoHeaders ? config.originalRequest.headers.toObject() : config.originalRequest.headers;
40
+ console.log(`[Rezo Debug] Request Headers:`, JSON.stringify(headers, null, 2));
41
+ }
42
+ }
43
+ if (config.trackUrl) {
44
+ console.log(`[Rezo Track] → ${method} ${url}`);
45
+ }
46
+ },
47
+ retry: (config, attempt, maxRetries, statusCode, delay) => {
48
+ if (config.debug) {
49
+ console.log(`[Rezo Debug] Retry ${attempt}/${maxRetries} after status ${statusCode}${delay > 0 ? ` (waiting ${delay}ms)` : ""}`);
50
+ }
51
+ if (config.trackUrl) {
52
+ console.log(`[Rezo Track] ⟳ Retry ${attempt}/${maxRetries} (status ${statusCode})`);
53
+ }
54
+ },
55
+ maxRetries: (config, maxRetries) => {
56
+ if (config.debug) {
57
+ console.log(`[Rezo Debug] Max retries (${maxRetries}) reached, throwing error`);
58
+ }
59
+ if (config.trackUrl) {
60
+ console.log(`[Rezo Track] ✗ Max retries reached`);
61
+ }
62
+ },
63
+ response: (config, status, statusText, duration) => {
64
+ if (config.debug) {
65
+ console.log(`[Rezo Debug] Response: ${status} ${statusText} (${duration.toFixed(2)}ms)`);
66
+ }
67
+ if (config.trackUrl) {
68
+ console.log(`[Rezo Track] ✓ ${status} ${statusText}`);
69
+ }
70
+ },
71
+ responseHeaders: (config, headers) => {
72
+ if (config.debug) {
73
+ console.log(`[Rezo Debug] Response Headers:`, JSON.stringify(headers, null, 2));
74
+ }
75
+ },
76
+ cookies: (config, cookieCount) => {
77
+ if (config.debug && cookieCount > 0) {
78
+ console.log(`[Rezo Debug] Cookies received: ${cookieCount}`);
79
+ }
80
+ },
81
+ timing: (config, timing) => {
82
+ if (config.debug) {
83
+ const parts = [];
84
+ if (timing.ttfb)
85
+ parts.push(`TTFB: ${timing.ttfb.toFixed(2)}ms`);
86
+ if (timing.total)
87
+ parts.push(`Total: ${timing.total.toFixed(2)}ms`);
88
+ if (parts.length > 0) {
89
+ console.log(`[Rezo Debug] Timing: ${parts.join(" | ")}`);
90
+ }
91
+ }
92
+ },
93
+ complete: (config, url) => {
94
+ if (config.debug) {
95
+ console.log(`[Rezo Debug] Request complete: ${url}`);
96
+ console.log(`[Rezo Debug] ─────────────────────────────────────
97
+ `);
98
+ }
99
+ },
100
+ error: (config, error) => {
101
+ if (config.debug) {
102
+ console.log(`[Rezo Debug] Error: ${error instanceof Error ? error.message : error}`);
103
+ }
104
+ if (config.trackUrl) {
105
+ console.log(`[Rezo Track] ✗ Error: ${error instanceof Error ? error.message : error}`);
106
+ }
107
+ }
108
+ };
31
109
  function updateTiming(config, timing, bodySize) {
32
110
  const now = performance.now();
33
111
  config.timing.domainLookupStart = config.timing.startTime;
@@ -554,6 +632,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
554
632
  } else if (config.transfer.requestSize === undefined) {
555
633
  config.transfer.requestSize = 0;
556
634
  }
635
+ debugLog.requestStart(config, url.href, fetchOptions.method?.toUpperCase() || "GET");
557
636
  }
558
637
  const reqHeaders = fetchOptions.headers instanceof RezoHeaders ? fetchOptions.headers.toObject() : fetchOptions.headers || {};
559
638
  const headers = toFetchHeaders(reqHeaders);
@@ -722,6 +801,14 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
722
801
  config.statusText = statusText;
723
802
  _stats.statusOnNext = status >= 400 ? "error" : "success";
724
803
  const mergedCookies = mergeRequestAndResponseCookies(config, cookies, url.href);
804
+ const duration = performance.now() - timing.startTime;
805
+ debugLog.response(config, status, statusText, duration);
806
+ debugLog.responseHeaders(config, responseHeaders.toObject());
807
+ debugLog.cookies(config, mergedCookies.array.length);
808
+ debugLog.timing(config, {
809
+ ttfb: timing.firstByteTime ? timing.firstByteTime - timing.startTime : undefined,
810
+ total: duration
811
+ });
725
812
  const finalResponse = {
726
813
  data: responseData,
727
814
  status,
@@ -805,6 +892,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
805
892
  uploadResult.emit("done", uploadFinishEvent);
806
893
  uploadResult._markFinished();
807
894
  }
895
+ debugLog.complete(config, url.href);
808
896
  return finalResponse;
809
897
  } catch (error) {
810
898
  _stats.statusOnNext = "error";
@@ -1,4 +1,3 @@
1
- import { URL } from "node:url";
2
1
  import { RezoError } from '../errors/rezo-error.js';
3
2
  import { buildSmartError, builErrorFromResponse, buildDownloadError } from '../responses/buildError.js';
4
3
  import { RezoCookieJar } from '../utils/cookies.js';
@@ -28,6 +27,85 @@ const Environment = {
28
27
  return typeof AbortController !== "undefined";
29
28
  }
30
29
  };
30
+ const debugLog = {
31
+ requestStart: (config, url, method) => {
32
+ if (config.debug) {
33
+ console.log(`
34
+ [Rezo Debug] ─────────────────────────────────────`);
35
+ console.log(`[Rezo Debug] ${method} ${url}`);
36
+ console.log(`[Rezo Debug] Request ID: ${config.requestId}`);
37
+ console.log(`[Rezo Debug] Adapter: fetch`);
38
+ if (config.originalRequest?.headers) {
39
+ const headers = config.originalRequest.headers instanceof RezoHeaders ? config.originalRequest.headers.toObject() : config.originalRequest.headers;
40
+ console.log(`[Rezo Debug] Request Headers:`, JSON.stringify(headers, null, 2));
41
+ }
42
+ }
43
+ if (config.trackUrl) {
44
+ console.log(`[Rezo Track] → ${method} ${url}`);
45
+ }
46
+ },
47
+ retry: (config, attempt, maxRetries, statusCode, delay) => {
48
+ if (config.debug) {
49
+ console.log(`[Rezo Debug] Retry ${attempt}/${maxRetries} after status ${statusCode}${delay > 0 ? ` (waiting ${delay}ms)` : ""}`);
50
+ }
51
+ if (config.trackUrl) {
52
+ console.log(`[Rezo Track] ⟳ Retry ${attempt}/${maxRetries} (status ${statusCode})`);
53
+ }
54
+ },
55
+ maxRetries: (config, maxRetries) => {
56
+ if (config.debug) {
57
+ console.log(`[Rezo Debug] Max retries (${maxRetries}) reached, throwing error`);
58
+ }
59
+ if (config.trackUrl) {
60
+ console.log(`[Rezo Track] ✗ Max retries reached`);
61
+ }
62
+ },
63
+ response: (config, status, statusText, duration) => {
64
+ if (config.debug) {
65
+ console.log(`[Rezo Debug] Response: ${status} ${statusText} (${duration.toFixed(2)}ms)`);
66
+ }
67
+ if (config.trackUrl) {
68
+ console.log(`[Rezo Track] ✓ ${status} ${statusText}`);
69
+ }
70
+ },
71
+ responseHeaders: (config, headers) => {
72
+ if (config.debug) {
73
+ console.log(`[Rezo Debug] Response Headers:`, JSON.stringify(headers, null, 2));
74
+ }
75
+ },
76
+ cookies: (config, cookieCount) => {
77
+ if (config.debug && cookieCount > 0) {
78
+ console.log(`[Rezo Debug] Cookies received: ${cookieCount}`);
79
+ }
80
+ },
81
+ timing: (config, timing) => {
82
+ if (config.debug) {
83
+ const parts = [];
84
+ if (timing.ttfb)
85
+ parts.push(`TTFB: ${timing.ttfb.toFixed(2)}ms`);
86
+ if (timing.total)
87
+ parts.push(`Total: ${timing.total.toFixed(2)}ms`);
88
+ if (parts.length > 0) {
89
+ console.log(`[Rezo Debug] Timing: ${parts.join(" | ")}`);
90
+ }
91
+ }
92
+ },
93
+ complete: (config, url) => {
94
+ if (config.debug) {
95
+ console.log(`[Rezo Debug] Request complete: ${url}`);
96
+ console.log(`[Rezo Debug] ─────────────────────────────────────
97
+ `);
98
+ }
99
+ },
100
+ error: (config, error) => {
101
+ if (config.debug) {
102
+ console.log(`[Rezo Debug] Error: ${error instanceof Error ? error.message : error}`);
103
+ }
104
+ if (config.trackUrl) {
105
+ console.log(`[Rezo Track] ✗ Error: ${error instanceof Error ? error.message : error}`);
106
+ }
107
+ }
108
+ };
31
109
  function updateTiming(config, timing, bodySize) {
32
110
  const now = performance.now();
33
111
  config.timing.domainLookupStart = config.timing.startTime;
@@ -554,6 +632,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
554
632
  } else if (config.transfer.requestSize === undefined) {
555
633
  config.transfer.requestSize = 0;
556
634
  }
635
+ debugLog.requestStart(config, url.href, fetchOptions.method?.toUpperCase() || "GET");
557
636
  }
558
637
  const reqHeaders = fetchOptions.headers instanceof RezoHeaders ? fetchOptions.headers.toObject() : fetchOptions.headers || {};
559
638
  const headers = toFetchHeaders(reqHeaders);
@@ -722,6 +801,14 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
722
801
  config.statusText = statusText;
723
802
  _stats.statusOnNext = status >= 400 ? "error" : "success";
724
803
  const mergedCookies = mergeRequestAndResponseCookies(config, cookies, url.href);
804
+ const duration = performance.now() - timing.startTime;
805
+ debugLog.response(config, status, statusText, duration);
806
+ debugLog.responseHeaders(config, responseHeaders.toObject());
807
+ debugLog.cookies(config, mergedCookies.array.length);
808
+ debugLog.timing(config, {
809
+ ttfb: timing.firstByteTime ? timing.firstByteTime - timing.startTime : undefined,
810
+ total: duration
811
+ });
725
812
  const finalResponse = {
726
813
  data: responseData,
727
814
  status,
@@ -805,6 +892,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
805
892
  uploadResult.emit("done", uploadFinishEvent);
806
893
  uploadResult._markFinished();
807
894
  }
895
+ debugLog.complete(config, url.href);
808
896
  return finalResponse;
809
897
  } catch (error) {
810
898
  _stats.statusOnNext = "error";
@@ -1,6 +1,6 @@
1
- const _mod_c82agb = require('./picker.cjs');
2
- exports.detectRuntime = _mod_c82agb.detectRuntime;
3
- exports.getAdapterCapabilities = _mod_c82agb.getAdapterCapabilities;
4
- exports.buildAdapterContext = _mod_c82agb.buildAdapterContext;
5
- exports.getAvailableAdapters = _mod_c82agb.getAvailableAdapters;
6
- exports.selectAdapter = _mod_c82agb.selectAdapter;;
1
+ const _mod_qxjloy = require('./picker.cjs');
2
+ exports.detectRuntime = _mod_qxjloy.detectRuntime;
3
+ exports.getAdapterCapabilities = _mod_qxjloy.getAdapterCapabilities;
4
+ exports.buildAdapterContext = _mod_qxjloy.buildAdapterContext;
5
+ exports.getAvailableAdapters = _mod_qxjloy.getAvailableAdapters;
6
+ exports.selectAdapter = _mod_qxjloy.selectAdapter;;
@@ -1,5 +1,6 @@
1
1
  const { RezoError } = require('../errors/rezo-error.cjs');
2
2
  const { buildSmartError, builErrorFromResponse } = require('../responses/buildError.cjs');
3
+ const { RezoCookieJar } = require('../utils/cookies.cjs');
3
4
  const RezoFormData = require('../utils/form-data.cjs');
4
5
  const { getDefaultConfig, prepareHTTPOptions } = require('../utils/http-config.cjs');
5
6
  const { RezoHeaders } = require('../utils/headers.cjs');
@@ -17,6 +18,85 @@ const Environment = {
17
18
  hasFormData: typeof FormData !== "undefined",
18
19
  hasAbortController: typeof AbortController !== "undefined"
19
20
  };
21
+ const debugLog = {
22
+ requestStart: (config, url, method) => {
23
+ if (config.debug) {
24
+ console.log(`
25
+ [Rezo Debug] ─────────────────────────────────────`);
26
+ console.log(`[Rezo Debug] ${method} ${url}`);
27
+ console.log(`[Rezo Debug] Request ID: ${config.requestId}`);
28
+ console.log(`[Rezo Debug] Adapter: react-native`);
29
+ if (config.originalRequest?.headers) {
30
+ const headers = config.originalRequest.headers instanceof RezoHeaders ? config.originalRequest.headers.toObject() : config.originalRequest.headers;
31
+ console.log(`[Rezo Debug] Request Headers:`, JSON.stringify(headers, null, 2));
32
+ }
33
+ }
34
+ if (config.trackUrl) {
35
+ console.log(`[Rezo Track] → ${method} ${url}`);
36
+ }
37
+ },
38
+ retry: (config, attempt, maxRetries, statusCode, delay) => {
39
+ if (config.debug) {
40
+ console.log(`[Rezo Debug] Retry ${attempt}/${maxRetries} after status ${statusCode}${delay > 0 ? ` (waiting ${delay}ms)` : ""}`);
41
+ }
42
+ if (config.trackUrl) {
43
+ console.log(`[Rezo Track] ⟳ Retry ${attempt}/${maxRetries} (status ${statusCode})`);
44
+ }
45
+ },
46
+ maxRetries: (config, maxRetries) => {
47
+ if (config.debug) {
48
+ console.log(`[Rezo Debug] Max retries (${maxRetries}) reached, throwing error`);
49
+ }
50
+ if (config.trackUrl) {
51
+ console.log(`[Rezo Track] ✗ Max retries reached`);
52
+ }
53
+ },
54
+ response: (config, status, statusText, duration) => {
55
+ if (config.debug) {
56
+ console.log(`[Rezo Debug] Response: ${status} ${statusText} (${duration.toFixed(2)}ms)`);
57
+ }
58
+ if (config.trackUrl) {
59
+ console.log(`[Rezo Track] ✓ ${status} ${statusText}`);
60
+ }
61
+ },
62
+ responseHeaders: (config, headers) => {
63
+ if (config.debug) {
64
+ console.log(`[Rezo Debug] Response Headers:`, JSON.stringify(headers, null, 2));
65
+ }
66
+ },
67
+ cookies: (config, cookieCount) => {
68
+ if (config.debug && cookieCount > 0) {
69
+ console.log(`[Rezo Debug] Cookies received: ${cookieCount}`);
70
+ }
71
+ },
72
+ timing: (config, timing) => {
73
+ if (config.debug) {
74
+ const parts = [];
75
+ if (timing.ttfb)
76
+ parts.push(`TTFB: ${timing.ttfb.toFixed(2)}ms`);
77
+ if (timing.total)
78
+ parts.push(`Total: ${timing.total.toFixed(2)}ms`);
79
+ if (parts.length > 0) {
80
+ console.log(`[Rezo Debug] Timing: ${parts.join(" | ")}`);
81
+ }
82
+ }
83
+ },
84
+ complete: (config, url) => {
85
+ if (config.debug) {
86
+ console.log(`[Rezo Debug] Request complete: ${url}`);
87
+ console.log(`[Rezo Debug] ─────────────────────────────────────
88
+ `);
89
+ }
90
+ },
91
+ error: (config, error) => {
92
+ if (config.debug) {
93
+ console.log(`[Rezo Debug] Error: ${error instanceof Error ? error.message : error}`);
94
+ }
95
+ if (config.trackUrl) {
96
+ console.log(`[Rezo Track] ✗ Error: ${error instanceof Error ? error.message : error}`);
97
+ }
98
+ }
99
+ };
20
100
  function updateTiming(config, timing, bodySize) {
21
101
  const now = performance.now();
22
102
  config.timing.domainLookupStart = config.timing.startTime;
@@ -291,11 +371,25 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
291
371
  throw response;
292
372
  }
293
373
  if (maxRetries <= retries) {
374
+ debugLog.maxRetries(config, maxRetries);
294
375
  throw response;
295
376
  }
296
377
  retries++;
297
- if (retryDelay > 0) {
298
- await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
378
+ const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
379
+ debugLog.retry(config, retries, maxRetries, response.status || 0, currentDelay);
380
+ if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
381
+ for (const hook of config.hooks.beforeRetry) {
382
+ try {
383
+ await hook(config, response, retries);
384
+ } catch (hookErr) {
385
+ if (config.debug) {
386
+ console.log("[Rezo Debug] beforeRetry hook error:", hookErr);
387
+ }
388
+ }
389
+ }
390
+ }
391
+ if (currentDelay > 0) {
392
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
299
393
  }
300
394
  }
301
395
  config.retryAttempts++;
@@ -319,6 +413,7 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
319
413
  config.isSecure = isSecure;
320
414
  config.finalUrl = url;
321
415
  config.network.protocol = isSecure ? "https" : "http";
416
+ debugLog.requestStart(config, url, fetchOptions.method?.toUpperCase() || "GET");
322
417
  const reqHeaders = fetchOptions.headers instanceof RezoHeaders ? fetchOptions.headers.toObject() : fetchOptions.headers || {};
323
418
  const headers = toFetchHeaders(reqHeaders);
324
419
  const eventEmitter = streamResult || downloadResult || uploadResult;
@@ -380,13 +475,68 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
380
475
  const responseHeaders = fromFetchHeaders(response.headers);
381
476
  const contentType = response.headers.get("content-type") || "";
382
477
  const contentLength = response.headers.get("content-length");
383
- const cookies = {
478
+ let cookies = {
384
479
  array: [],
385
480
  serialized: [],
386
481
  netscape: "",
387
482
  string: "",
388
483
  setCookiesString: []
389
484
  };
485
+ const setCookieHeader = response.headers.get("set-cookie");
486
+ if (setCookieHeader && config.useCookies) {
487
+ const cookieStrings = setCookieHeader.split(/,(?=[^;]+=[^;]+)/).map((s) => s.trim());
488
+ const tempJar = new RezoCookieJar;
489
+ tempJar.setCookiesSync(cookieStrings, url);
490
+ const parsedCookies = tempJar.cookies();
491
+ const acceptedCookies = [];
492
+ let hookError = null;
493
+ if (config.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
494
+ for (const cookie of parsedCookies.array) {
495
+ let shouldAccept = true;
496
+ for (const hook of config.hooks.beforeCookie) {
497
+ try {
498
+ const result = await hook({
499
+ cookie,
500
+ source: "response",
501
+ url,
502
+ isValid: true
503
+ }, config);
504
+ if (result === false) {
505
+ shouldAccept = false;
506
+ break;
507
+ }
508
+ } catch (err) {
509
+ hookError = err;
510
+ if (config.debug) {
511
+ console.log("[Rezo Debug] beforeCookie hook error:", err);
512
+ }
513
+ }
514
+ }
515
+ if (shouldAccept) {
516
+ acceptedCookies.push(cookie);
517
+ }
518
+ }
519
+ } else {
520
+ acceptedCookies.push(...parsedCookies.array);
521
+ }
522
+ const acceptedCookieStrings = acceptedCookies.map((c) => c.toSetCookieString());
523
+ if (config.enableCookieJar && config.cookieJar) {
524
+ config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
525
+ }
526
+ const cookieJar = new RezoCookieJar(acceptedCookies, url);
527
+ cookies = cookieJar.cookies();
528
+ if (!hookError && config.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
529
+ for (const hook of config.hooks.afterCookie) {
530
+ try {
531
+ await hook(acceptedCookies, config);
532
+ } catch (err) {
533
+ if (config.debug) {
534
+ console.log("[Rezo Debug] afterCookie hook error:", err);
535
+ }
536
+ }
537
+ }
538
+ }
539
+ }
390
540
  config.responseCookies = cookies;
391
541
  if (eventEmitter) {
392
542
  const headersEvent = {
@@ -464,6 +614,14 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
464
614
  eventEmitter.emit("error", error);
465
615
  return error;
466
616
  }
617
+ const duration = performance.now() - timing.startTime;
618
+ debugLog.response(config, status, statusText, duration);
619
+ debugLog.responseHeaders(config, responseHeaders.toObject());
620
+ debugLog.cookies(config, cookies.array.length);
621
+ debugLog.timing(config, {
622
+ ttfb: timing.firstByteTime ? timing.firstByteTime - timing.startTime : undefined,
623
+ total: duration
624
+ });
467
625
  const finalResponse = {
468
626
  data: responseData,
469
627
  status,
@@ -476,6 +634,7 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
476
634
  finalUrl: url,
477
635
  urls: buildUrlTree(config, url)
478
636
  };
637
+ debugLog.complete(config, url);
479
638
  if (streamResult) {
480
639
  const streamFinishEvent = {
481
640
  status,