rezo 1.0.21 → 1.0.23

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.
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
1934
1934
  * ```
1935
1935
  */
1936
1936
  beforeRedirect?: RezoRequestConfig["beforeRedirect"];
1937
+ /** Alias for beforeRedirect */
1938
+ onRedirect?: RezoRequestConfig["beforeRedirect"];
1937
1939
  /** Character encoding for request body and response data */
1938
1940
  encoding?: BufferEncoding;
1939
1941
  /**
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
2684
2686
  * ```
2685
2687
  */
2686
2688
  beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2689
+ /**
2690
+ * Alias for beforeRedirect - callback invoked when a redirect response is received.
2691
+ * @see beforeRedirect
2692
+ */
2693
+ onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2687
2694
  /** Whether to send cookies and authorization headers with cross-origin requests */
2688
2695
  withCredentials?: boolean;
2689
2696
  /** Proxy configuration (URL string or detailed options) */
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
3233
3240
  * ```
3234
3241
  */
3235
3242
  beforeRedirect?: RezoHttpRequest["beforeRedirect"];
3243
+ /** Alias for beforeRedirect */
3244
+ onRedirect?: RezoHttpRequest["onRedirect"];
3236
3245
  /** Array of functions to transform request data */
3237
3246
  transformRequest?: RezoHttpRequest["transformRequest"];
3238
3247
  /** Array of functions to transform response data */
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
1934
1934
  * ```
1935
1935
  */
1936
1936
  beforeRedirect?: RezoRequestConfig["beforeRedirect"];
1937
+ /** Alias for beforeRedirect */
1938
+ onRedirect?: RezoRequestConfig["beforeRedirect"];
1937
1939
  /** Character encoding for request body and response data */
1938
1940
  encoding?: BufferEncoding;
1939
1941
  /**
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
2684
2686
  * ```
2685
2687
  */
2686
2688
  beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2689
+ /**
2690
+ * Alias for beforeRedirect - callback invoked when a redirect response is received.
2691
+ * @see beforeRedirect
2692
+ */
2693
+ onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2687
2694
  /** Whether to send cookies and authorization headers with cross-origin requests */
2688
2695
  withCredentials?: boolean;
2689
2696
  /** Proxy configuration (URL string or detailed options) */
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
3233
3240
  * ```
3234
3241
  */
3235
3242
  beforeRedirect?: RezoHttpRequest["beforeRedirect"];
3243
+ /** Alias for beforeRedirect */
3244
+ onRedirect?: RezoHttpRequest["onRedirect"];
3236
3245
  /** Array of functions to transform request data */
3237
3246
  transformRequest?: RezoHttpRequest["transformRequest"];
3238
3247
  /** Array of functions to transform response data */
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
1934
1934
  * ```
1935
1935
  */
1936
1936
  beforeRedirect?: RezoRequestConfig["beforeRedirect"];
1937
+ /** Alias for beforeRedirect */
1938
+ onRedirect?: RezoRequestConfig["beforeRedirect"];
1937
1939
  /** Character encoding for request body and response data */
1938
1940
  encoding?: BufferEncoding;
1939
1941
  /**
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
2684
2686
  * ```
2685
2687
  */
2686
2688
  beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2689
+ /**
2690
+ * Alias for beforeRedirect - callback invoked when a redirect response is received.
2691
+ * @see beforeRedirect
2692
+ */
2693
+ onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2687
2694
  /** Whether to send cookies and authorization headers with cross-origin requests */
2688
2695
  withCredentials?: boolean;
2689
2696
  /** Proxy configuration (URL string or detailed options) */
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
3233
3240
  * ```
3234
3241
  */
3235
3242
  beforeRedirect?: RezoHttpRequest["beforeRedirect"];
3243
+ /** Alias for beforeRedirect */
3244
+ onRedirect?: RezoHttpRequest["onRedirect"];
3236
3245
  /** Array of functions to transform request data */
3237
3246
  transformRequest?: RezoHttpRequest["transformRequest"];
3238
3247
  /** Array of functions to transform response data */
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
1934
1934
  * ```
1935
1935
  */
1936
1936
  beforeRedirect?: RezoRequestConfig["beforeRedirect"];
1937
+ /** Alias for beforeRedirect */
1938
+ onRedirect?: RezoRequestConfig["beforeRedirect"];
1937
1939
  /** Character encoding for request body and response data */
1938
1940
  encoding?: BufferEncoding;
1939
1941
  /**
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
2684
2686
  * ```
2685
2687
  */
2686
2688
  beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2689
+ /**
2690
+ * Alias for beforeRedirect - callback invoked when a redirect response is received.
2691
+ * @see beforeRedirect
2692
+ */
2693
+ onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2687
2694
  /** Whether to send cookies and authorization headers with cross-origin requests */
2688
2695
  withCredentials?: boolean;
2689
2696
  /** Proxy configuration (URL string or detailed options) */
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
3233
3240
  * ```
3234
3241
  */
3235
3242
  beforeRedirect?: RezoHttpRequest["beforeRedirect"];
3243
+ /** Alias for beforeRedirect */
3244
+ onRedirect?: RezoHttpRequest["onRedirect"];
3236
3245
  /** Array of functions to transform request data */
3237
3246
  transformRequest?: RezoHttpRequest["transformRequest"];
3238
3247
  /** Array of functions to transform response data */
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
1934
1934
  * ```
1935
1935
  */
1936
1936
  beforeRedirect?: RezoRequestConfig["beforeRedirect"];
1937
+ /** Alias for beforeRedirect */
1938
+ onRedirect?: RezoRequestConfig["beforeRedirect"];
1937
1939
  /** Character encoding for request body and response data */
1938
1940
  encoding?: BufferEncoding;
1939
1941
  /**
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
2684
2686
  * ```
2685
2687
  */
2686
2688
  beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2689
+ /**
2690
+ * Alias for beforeRedirect - callback invoked when a redirect response is received.
2691
+ * @see beforeRedirect
2692
+ */
2693
+ onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2687
2694
  /** Whether to send cookies and authorization headers with cross-origin requests */
2688
2695
  withCredentials?: boolean;
2689
2696
  /** Proxy configuration (URL string or detailed options) */
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
3233
3240
  * ```
3234
3241
  */
3235
3242
  beforeRedirect?: RezoHttpRequest["beforeRedirect"];
3243
+ /** Alias for beforeRedirect */
3244
+ onRedirect?: RezoHttpRequest["onRedirect"];
3236
3245
  /** Array of functions to transform request data */
3237
3246
  transformRequest?: RezoHttpRequest["transformRequest"];
3238
3247
  /** Array of functions to transform response data */
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
1934
1934
  * ```
1935
1935
  */
1936
1936
  beforeRedirect?: RezoRequestConfig["beforeRedirect"];
1937
+ /** Alias for beforeRedirect */
1938
+ onRedirect?: RezoRequestConfig["beforeRedirect"];
1937
1939
  /** Character encoding for request body and response data */
1938
1940
  encoding?: BufferEncoding;
1939
1941
  /**
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
2684
2686
  * ```
2685
2687
  */
2686
2688
  beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2689
+ /**
2690
+ * Alias for beforeRedirect - callback invoked when a redirect response is received.
2691
+ * @see beforeRedirect
2692
+ */
2693
+ onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
2687
2694
  /** Whether to send cookies and authorization headers with cross-origin requests */
2688
2695
  withCredentials?: boolean;
2689
2696
  /** Proxy configuration (URL string or detailed options) */
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
3233
3240
  * ```
3234
3241
  */
3235
3242
  beforeRedirect?: RezoHttpRequest["beforeRedirect"];
3243
+ /** Alias for beforeRedirect */
3244
+ onRedirect?: RezoHttpRequest["onRedirect"];
3236
3245
  /** Array of functions to transform request data */
3237
3246
  transformRequest?: RezoHttpRequest["transformRequest"];
3238
3247
  /** Array of functions to transform response data */
@@ -129,7 +129,7 @@ function sanitizeConfig(config) {
129
129
  delete sanitized.data;
130
130
  return sanitized;
131
131
  }
132
- function parseCookiesFromHeaders(headers, url, config) {
132
+ async function parseCookiesFromHeaders(headers, url, config) {
133
133
  let setCookieHeaders = [];
134
134
  if (typeof headers.getSetCookie === "function") {
135
135
  setCookieHeaders = headers.getSetCookie() || [];
@@ -149,13 +149,59 @@ function parseCookiesFromHeaders(headers, url, config) {
149
149
  setCookiesString: []
150
150
  };
151
151
  }
152
+ const tempJar = new RezoCookieJar;
153
+ tempJar.setCookiesSync(setCookieHeaders, url);
154
+ const parsedCookies = tempJar.cookies();
155
+ const acceptedCookies = [];
156
+ let hookError = null;
157
+ if (config?.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
158
+ for (const cookie of parsedCookies.array) {
159
+ let shouldAccept = true;
160
+ for (const hook of config.hooks.beforeCookie) {
161
+ try {
162
+ const result = await hook({
163
+ cookie,
164
+ source: "response",
165
+ url,
166
+ isValid: true
167
+ }, config);
168
+ if (result === false) {
169
+ shouldAccept = false;
170
+ break;
171
+ }
172
+ } catch (err) {
173
+ hookError = err;
174
+ if (config.debug) {
175
+ console.log("[Rezo Debug] beforeCookie hook error:", err);
176
+ }
177
+ }
178
+ }
179
+ if (shouldAccept) {
180
+ acceptedCookies.push(cookie);
181
+ }
182
+ }
183
+ } else {
184
+ acceptedCookies.push(...parsedCookies.array);
185
+ }
186
+ const acceptedCookieStrings = acceptedCookies.map((c) => c.cookieString());
152
187
  const jar = new RezoCookieJar;
153
- jar.setCookiesSync(setCookieHeaders, url);
188
+ jar.setCookiesSync(acceptedCookieStrings, url);
154
189
  if (config?.enableCookieJar && config?.cookieJar) {
155
- config.cookieJar.setCookiesSync(setCookieHeaders, url);
190
+ config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
156
191
  }
157
192
  const cookies = jar.cookies();
158
193
  cookies.setCookiesString = setCookieHeaders;
194
+ if (!hookError && config?.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
195
+ for (const hook of config.hooks.afterCookie) {
196
+ try {
197
+ await hook(acceptedCookies, config);
198
+ } catch (err) {
199
+ if (config.debug) {
200
+ console.log("[Rezo Debug] afterCookie hook error:", err);
201
+ }
202
+ }
203
+ }
204
+ }
159
205
  return cookies;
160
206
  }
161
207
  function mergeRequestAndResponseCookies(config, responseCookies, url) {
@@ -385,8 +431,14 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
385
431
  }
386
432
  retries++;
387
433
  config.retryAttempts++;
434
+ const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
435
+ if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
436
+ for (const hook of config.hooks.beforeRetry) {
437
+ await hook(config, response, retries);
438
+ }
439
+ }
388
440
  if (retryDelay > 0) {
389
- await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
441
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
390
442
  }
391
443
  }
392
444
  continue;
@@ -435,7 +487,8 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
435
487
  visitedUrls.add(normalizedRedirectUrl);
436
488
  }
437
489
  const redirectCode = response.status;
438
- const onRedirect = config.beforeRedirect ? config.beforeRedirect({
490
+ const redirectCallback = config.beforeRedirect || config.onRedirect;
491
+ const onRedirect = redirectCallback ? redirectCallback({
439
492
  url: new URL(location),
440
493
  status: response.status,
441
494
  headers: response.headers,
@@ -583,7 +636,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
583
636
  const responseHeaders = fromFetchHeaders(response.headers);
584
637
  const contentType = response.headers.get("content-type") || "";
585
638
  const contentLength = response.headers.get("content-length");
586
- const cookies = parseCookiesFromHeaders(response.headers, url.href, config);
639
+ const cookies = await parseCookiesFromHeaders(response.headers, url.href, config);
587
640
  config.responseCookies = cookies;
588
641
  const location = response.headers.get("location");
589
642
  const isRedirect = status >= 300 && status < 400 && location;
@@ -129,7 +129,7 @@ function sanitizeConfig(config) {
129
129
  delete sanitized.data;
130
130
  return sanitized;
131
131
  }
132
- function parseCookiesFromHeaders(headers, url, config) {
132
+ async function parseCookiesFromHeaders(headers, url, config) {
133
133
  let setCookieHeaders = [];
134
134
  if (typeof headers.getSetCookie === "function") {
135
135
  setCookieHeaders = headers.getSetCookie() || [];
@@ -149,13 +149,59 @@ function parseCookiesFromHeaders(headers, url, config) {
149
149
  setCookiesString: []
150
150
  };
151
151
  }
152
+ const tempJar = new RezoCookieJar;
153
+ tempJar.setCookiesSync(setCookieHeaders, url);
154
+ const parsedCookies = tempJar.cookies();
155
+ const acceptedCookies = [];
156
+ let hookError = null;
157
+ if (config?.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
158
+ for (const cookie of parsedCookies.array) {
159
+ let shouldAccept = true;
160
+ for (const hook of config.hooks.beforeCookie) {
161
+ try {
162
+ const result = await hook({
163
+ cookie,
164
+ source: "response",
165
+ url,
166
+ isValid: true
167
+ }, config);
168
+ if (result === false) {
169
+ shouldAccept = false;
170
+ break;
171
+ }
172
+ } catch (err) {
173
+ hookError = err;
174
+ if (config.debug) {
175
+ console.log("[Rezo Debug] beforeCookie hook error:", err);
176
+ }
177
+ }
178
+ }
179
+ if (shouldAccept) {
180
+ acceptedCookies.push(cookie);
181
+ }
182
+ }
183
+ } else {
184
+ acceptedCookies.push(...parsedCookies.array);
185
+ }
186
+ const acceptedCookieStrings = acceptedCookies.map((c) => c.cookieString());
152
187
  const jar = new RezoCookieJar;
153
- jar.setCookiesSync(setCookieHeaders, url);
188
+ jar.setCookiesSync(acceptedCookieStrings, url);
154
189
  if (config?.enableCookieJar && config?.cookieJar) {
155
- config.cookieJar.setCookiesSync(setCookieHeaders, url);
190
+ config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
156
191
  }
157
192
  const cookies = jar.cookies();
158
193
  cookies.setCookiesString = setCookieHeaders;
194
+ if (!hookError && config?.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
195
+ for (const hook of config.hooks.afterCookie) {
196
+ try {
197
+ await hook(acceptedCookies, config);
198
+ } catch (err) {
199
+ if (config.debug) {
200
+ console.log("[Rezo Debug] afterCookie hook error:", err);
201
+ }
202
+ }
203
+ }
204
+ }
159
205
  return cookies;
160
206
  }
161
207
  function mergeRequestAndResponseCookies(config, responseCookies, url) {
@@ -385,8 +431,14 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
385
431
  }
386
432
  retries++;
387
433
  config.retryAttempts++;
434
+ const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
435
+ if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
436
+ for (const hook of config.hooks.beforeRetry) {
437
+ await hook(config, response, retries);
438
+ }
439
+ }
388
440
  if (retryDelay > 0) {
389
- await new Promise((resolve) => setTimeout(resolve, incrementDelay ? retryDelay * retries : retryDelay));
441
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
390
442
  }
391
443
  }
392
444
  continue;
@@ -435,7 +487,8 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
435
487
  visitedUrls.add(normalizedRedirectUrl);
436
488
  }
437
489
  const redirectCode = response.status;
438
- const onRedirect = config.beforeRedirect ? config.beforeRedirect({
490
+ const redirectCallback = config.beforeRedirect || config.onRedirect;
491
+ const onRedirect = redirectCallback ? redirectCallback({
439
492
  url: new URL(location),
440
493
  status: response.status,
441
494
  headers: response.headers,
@@ -583,7 +636,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
583
636
  const responseHeaders = fromFetchHeaders(response.headers);
584
637
  const contentType = response.headers.get("content-type") || "";
585
638
  const contentLength = response.headers.get("content-length");
586
- const cookies = parseCookiesFromHeaders(response.headers, url.href, config);
639
+ const cookies = await parseCookiesFromHeaders(response.headers, url.href, config);
587
640
  config.responseCookies = cookies;
588
641
  const location = response.headers.get("location");
589
642
  const isRedirect = status >= 300 && status < 400 && location;
@@ -386,6 +386,11 @@ async function executeHttp1Request(fetchOptions, config, options, perform, fs, s
386
386
  retries++;
387
387
  const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
388
388
  debugLog.retry(config, retries, maxRetries, responseStatusCode, currentDelay);
389
+ if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
390
+ for (const hook of config.hooks.beforeRetry) {
391
+ await hook(config, response, retries);
392
+ }
393
+ }
389
394
  if (retryDelay > 0) {
390
395
  await new Promise((resolve) => setTimeout(resolve, currentDelay));
391
396
  }
@@ -427,7 +432,8 @@ async function executeHttp1Request(fetchOptions, config, options, perform, fs, s
427
432
  }
428
433
  const redirectCode = response.status;
429
434
  const customHeaders = undefined;
430
- const onRedirect = config.beforeRedirect ? config.beforeRedirect({
435
+ const redirectCallback = config.beforeRedirect || config.onRedirect;
436
+ const onRedirect = redirectCallback ? redirectCallback({
431
437
  url: new URL(_stats.redirectUrl),
432
438
  status: response.status,
433
439
  headers: response.headers,
@@ -573,7 +579,7 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
573
579
  const location = headers["location"] || headers["Location"];
574
580
  const contentLength = headers["content-length"];
575
581
  const cookies = headers["set-cookie"];
576
- updateCookies(config, headers, url.href);
582
+ await updateCookies(config, headers, url.href);
577
583
  const cookieArray = config.responseCookies?.array || [];
578
584
  delete headers["set-cookie"];
579
585
  _stats.redirectUrl = undefined;
@@ -876,13 +882,31 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
876
882
  }
877
883
  timing.dnsStart = performance.now();
878
884
  config.timing.domainLookupStart = timing.dnsStart;
879
- socket.on("lookup", () => {
885
+ socket.on("lookup", (err, address, family) => {
880
886
  if (!timing.dnsEnd) {
881
887
  timing.dnsEnd = performance.now();
882
888
  config.timing.domainLookupEnd = timing.dnsEnd;
883
889
  timing.tcpStart = performance.now();
884
890
  config.timing.connectStart = timing.tcpStart;
885
891
  }
892
+ if (config.hooks?.onDns && config.hooks.onDns.length > 0) {
893
+ const familyNum = typeof family === "number" ? family : family === "IPv6" ? 6 : 4;
894
+ for (const hook of config.hooks.onDns) {
895
+ try {
896
+ hook({
897
+ hostname: url.hostname,
898
+ address: address || "",
899
+ family: familyNum,
900
+ duration: timing.dnsEnd - timing.dnsStart,
901
+ timestamp: Date.now()
902
+ }, config);
903
+ } catch (err) {
904
+ if (config.debug) {
905
+ console.log("[Rezo Debug] onDns hook error:", err);
906
+ }
907
+ }
908
+ }
909
+ }
886
910
  });
887
911
  socket.on("secureConnect", () => {
888
912
  if (!timing.tlsEnd && timing.tlsStart) {
@@ -909,6 +933,31 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
909
933
  hostnameMatch: cert.subject?.CN === url.hostname,
910
934
  chainValid: true
911
935
  };
936
+ if (config.hooks?.onTls && config.hooks.onTls.length > 0) {
937
+ for (const hook of config.hooks.onTls) {
938
+ try {
939
+ hook({
940
+ protocol: tlsVersion,
941
+ cipher: cipher?.name || "",
942
+ authorized: !socket.authorizationError,
943
+ authorizationError: socket.authorizationError,
944
+ certificate: cert ? {
945
+ subject: cert.subject?.CN || "",
946
+ issuer: cert.issuer?.CN || "",
947
+ validFrom: cert.valid_from || "",
948
+ validTo: cert.valid_to || "",
949
+ fingerprint: cert.fingerprint || ""
950
+ } : undefined,
951
+ duration: timing.tlsEnd - timing.tlsStart,
952
+ timestamp: Date.now()
953
+ }, config);
954
+ } catch (err) {
955
+ if (config.debug) {
956
+ console.log("[Rezo Debug] onTls hook error:", err);
957
+ }
958
+ }
959
+ }
960
+ }
912
961
  });
913
962
  socket.on("connect", () => {
914
963
  if (!timing.tcpEnd) {
@@ -927,6 +976,24 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
927
976
  config.network.localPort = localPort;
928
977
  config.network.family = remoteFamily;
929
978
  }
979
+ if (config.hooks?.onSocket && config.hooks.onSocket.length > 0) {
980
+ for (const hook of config.hooks.onSocket) {
981
+ try {
982
+ hook({
983
+ type: "connect",
984
+ localAddress,
985
+ localPort,
986
+ remoteAddress,
987
+ remotePort,
988
+ timestamp: Date.now()
989
+ }, socket);
990
+ } catch (err) {
991
+ if (config.debug) {
992
+ console.log("[Rezo Debug] onSocket hook error:", err);
993
+ }
994
+ }
995
+ }
996
+ }
930
997
  });
931
998
  });
932
999
  req.on("error", (error) => {
@@ -1322,18 +1389,52 @@ function parseProxy(proxy, isScure = true, rejectUnauthorized = false) {
1322
1389
  }
1323
1390
  return rezoProxy(proxy);
1324
1391
  }
1325
- function updateCookies(config, headers, url) {
1392
+ async function updateCookies(config, headers, url) {
1326
1393
  const cookies = headers["set-cookie"];
1327
1394
  if (cookies) {
1328
1395
  const jar = new RezoCookieJar;
1396
+ const tempJar = new RezoCookieJar;
1397
+ tempJar.setCookiesSync(cookies, url);
1398
+ const parsedCookies = tempJar.cookies();
1399
+ const acceptedCookies = [];
1400
+ let hookError = null;
1401
+ if (config.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
1402
+ for (const cookie of parsedCookies.array) {
1403
+ let shouldAccept = true;
1404
+ for (const hook of config.hooks.beforeCookie) {
1405
+ try {
1406
+ const result = await hook({
1407
+ cookie,
1408
+ source: "response",
1409
+ url,
1410
+ isValid: true
1411
+ }, config);
1412
+ if (result === false) {
1413
+ shouldAccept = false;
1414
+ break;
1415
+ }
1416
+ } catch (err) {
1417
+ hookError = err;
1418
+ if (config.debug) {
1419
+ console.log("[Rezo Debug] beforeCookie hook error:", err);
1420
+ }
1421
+ }
1422
+ }
1423
+ if (shouldAccept) {
1424
+ acceptedCookies.push(cookie);
1425
+ }
1426
+ }
1427
+ } else {
1428
+ acceptedCookies.push(...parsedCookies.array);
1429
+ }
1430
+ const acceptedCookieStrings = acceptedCookies.map((c) => c.cookieString());
1329
1431
  if (config.enableCookieJar && config.cookieJar) {
1330
- config.cookieJar.setCookiesSync(cookies, url);
1432
+ config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
1331
1433
  }
1332
- jar.setCookiesSync(cookies, url);
1434
+ jar.setCookiesSync(acceptedCookieStrings, url);
1333
1435
  if (config.useCookies) {
1334
- const parsedCookies = jar.cookies();
1335
1436
  const existingArray = config.responseCookies?.array || [];
1336
- for (const cookie of parsedCookies.array) {
1437
+ for (const cookie of acceptedCookies) {
1337
1438
  const existingIndex = existingArray.findIndex((c) => c.key === cookie.key && c.domain === cookie.domain);
1338
1439
  if (existingIndex >= 0) {
1339
1440
  existingArray[existingIndex] = cookie;
@@ -1344,6 +1445,17 @@ function updateCookies(config, headers, url) {
1344
1445
  const mergedJar = new RezoCookieJar(existingArray, url);
1345
1446
  config.responseCookies = mergedJar.cookies();
1346
1447
  }
1448
+ if (!hookError && config.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
1449
+ for (const hook of config.hooks.afterCookie) {
1450
+ try {
1451
+ await hook(acceptedCookies, config);
1452
+ } catch (err) {
1453
+ if (config.debug) {
1454
+ console.log("[Rezo Debug] afterCookie hook error:", err);
1455
+ }
1456
+ }
1457
+ }
1458
+ }
1347
1459
  }
1348
1460
  }
1349
1461