rezo 1.0.36 → 1.0.37
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.
- package/dist/adapters/curl.cjs +320 -9
- package/dist/adapters/curl.js +320 -9
- package/dist/adapters/entries/curl.d.ts +20 -2
- package/dist/adapters/entries/fetch.d.ts +20 -2
- package/dist/adapters/entries/http.d.ts +20 -2
- package/dist/adapters/entries/http2.d.ts +20 -2
- package/dist/adapters/entries/react-native.d.ts +20 -2
- package/dist/adapters/entries/xhr.d.ts +20 -2
- package/dist/adapters/fetch.cjs +10 -2
- package/dist/adapters/fetch.js +10 -2
- package/dist/adapters/http.cjs +204 -35
- package/dist/adapters/http.js +204 -35
- package/dist/adapters/http2.cjs +10 -2
- package/dist/adapters/http2.js +10 -2
- package/dist/adapters/index.cjs +6 -6
- package/dist/adapters/react-native.cjs +10 -2
- package/dist/adapters/react-native.js +10 -2
- package/dist/adapters/xhr.cjs +9 -1
- package/dist/adapters/xhr.js +9 -1
- package/dist/cache/index.cjs +13 -13
- package/dist/crawler.d.ts +20 -2
- package/dist/entries/crawler.cjs +5 -5
- package/dist/index.cjs +24 -24
- package/dist/index.d.ts +20 -2
- package/dist/platform/browser.d.ts +20 -2
- package/dist/platform/bun.d.ts +20 -2
- package/dist/platform/deno.d.ts +20 -2
- package/dist/platform/node.d.ts +20 -2
- package/dist/platform/react-native.d.ts +20 -2
- package/dist/platform/worker.d.ts +20 -2
- package/dist/plugin/index.cjs +36 -36
- package/dist/proxy/index.cjs +4 -4
- package/dist/queue/index.cjs +8 -8
- package/dist/responses/universal/index.cjs +11 -11
- package/dist/utils/agent-pool.cjs +204 -0
- package/dist/utils/agent-pool.js +201 -0
- package/dist/utils/http-config.cjs +24 -7
- package/dist/utils/http-config.js +24 -7
- package/dist/utils/index.cjs +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/staged-timeout.cjs +143 -0
- package/dist/utils/staged-timeout.js +139 -0
- package/package.json +1 -1
package/dist/adapters/curl.cjs
CHANGED
|
@@ -16,6 +16,251 @@ const { StreamResponse } = require('../responses/stream.cjs');
|
|
|
16
16
|
const { DownloadResponse } = require('../responses/download.cjs');
|
|
17
17
|
const { UploadResponse } = require('../responses/upload.cjs');
|
|
18
18
|
const { RezoPerformance } = require('../utils/tools.cjs');
|
|
19
|
+
const { ResponseCache } = require('../cache/response-cache.cjs');
|
|
20
|
+
const debugLog = {
|
|
21
|
+
requestStart: (config, url, method) => {
|
|
22
|
+
if (config.debug) {
|
|
23
|
+
console.log(`
|
|
24
|
+
[Rezo Debug] ─────────────────────────────────────`);
|
|
25
|
+
console.log(`[Rezo Debug] ${method} ${url}`);
|
|
26
|
+
console.log(`[Rezo Debug] Request ID: ${config.requestId}`);
|
|
27
|
+
if (config.originalRequest?.headers) {
|
|
28
|
+
const headers = config.originalRequest.headers instanceof RezoHeaders ? config.originalRequest.headers.toObject() : config.originalRequest.headers;
|
|
29
|
+
console.log(`[Rezo Debug] Request Headers:`, JSON.stringify(headers, null, 2));
|
|
30
|
+
}
|
|
31
|
+
if (config.proxy && typeof config.proxy === "object") {
|
|
32
|
+
console.log(`[Rezo Debug] Proxy: ${config.proxy.protocol}://${config.proxy.host}:${config.proxy.port}`);
|
|
33
|
+
} else if (config.proxy && typeof config.proxy === "string") {
|
|
34
|
+
console.log(`[Rezo Debug] Proxy: ${config.proxy}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (config.trackUrl) {
|
|
38
|
+
console.log(`[Rezo Track] → ${method} ${url}`);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
redirect: (config, fromUrl, toUrl, statusCode, method) => {
|
|
42
|
+
if (config.debug) {
|
|
43
|
+
console.log(`[Rezo Debug] Redirect ${statusCode}: ${fromUrl}`);
|
|
44
|
+
console.log(`[Rezo Debug] → ${toUrl} (${method})`);
|
|
45
|
+
}
|
|
46
|
+
if (config.trackUrl) {
|
|
47
|
+
console.log(`[Rezo Track] ↳ ${statusCode} → ${toUrl}`);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
retry: (config, attempt, maxRetries, statusCode, delay) => {
|
|
51
|
+
if (config.debug) {
|
|
52
|
+
console.log(`[Rezo Debug] Retry ${attempt}/${maxRetries} after status ${statusCode}${delay > 0 ? ` (waiting ${delay}ms)` : ""}`);
|
|
53
|
+
}
|
|
54
|
+
if (config.trackUrl) {
|
|
55
|
+
console.log(`[Rezo Track] ⟳ Retry ${attempt}/${maxRetries} (status ${statusCode})`);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
maxRetries: (config, maxRetries) => {
|
|
59
|
+
if (config.debug) {
|
|
60
|
+
console.log(`[Rezo Debug] Max retries (${maxRetries}) reached, throwing error`);
|
|
61
|
+
}
|
|
62
|
+
if (config.trackUrl) {
|
|
63
|
+
console.log(`[Rezo Track] ✗ Max retries reached`);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
response: (config, status, statusText, duration) => {
|
|
67
|
+
if (config.debug) {
|
|
68
|
+
console.log(`[Rezo Debug] Response: ${status} ${statusText} (${duration.toFixed(2)}ms)`);
|
|
69
|
+
}
|
|
70
|
+
if (config.trackUrl) {
|
|
71
|
+
console.log(`[Rezo Track] ✓ ${status} ${statusText}`);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
responseHeaders: (config, headers) => {
|
|
75
|
+
if (config.debug) {
|
|
76
|
+
console.log(`[Rezo Debug] Response Headers:`, JSON.stringify(headers, null, 2));
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
cookies: (config, cookieCount) => {
|
|
80
|
+
if (config.debug && cookieCount > 0) {
|
|
81
|
+
console.log(`[Rezo Debug] Cookies received: ${cookieCount}`);
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
timing: (config, timing) => {
|
|
85
|
+
if (config.debug) {
|
|
86
|
+
const parts = [];
|
|
87
|
+
if (timing.dns)
|
|
88
|
+
parts.push(`DNS: ${timing.dns.toFixed(2)}ms`);
|
|
89
|
+
if (timing.connect)
|
|
90
|
+
parts.push(`Connect: ${timing.connect.toFixed(2)}ms`);
|
|
91
|
+
if (timing.tls)
|
|
92
|
+
parts.push(`TLS: ${timing.tls.toFixed(2)}ms`);
|
|
93
|
+
if (timing.ttfb)
|
|
94
|
+
parts.push(`TTFB: ${timing.ttfb.toFixed(2)}ms`);
|
|
95
|
+
if (timing.total)
|
|
96
|
+
parts.push(`Total: ${timing.total.toFixed(2)}ms`);
|
|
97
|
+
if (parts.length > 0) {
|
|
98
|
+
console.log(`[Rezo Debug] Timing: ${parts.join(" | ")}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
complete: (config, finalUrl, redirectCount, duration) => {
|
|
103
|
+
if (config.debug) {
|
|
104
|
+
console.log(`[Rezo Debug] Complete: ${finalUrl}`);
|
|
105
|
+
if (redirectCount > 0) {
|
|
106
|
+
console.log(`[Rezo Debug] Redirects: ${redirectCount}`);
|
|
107
|
+
}
|
|
108
|
+
console.log(`[Rezo Debug] Total Duration: ${duration.toFixed(2)}ms`);
|
|
109
|
+
console.log(`[Rezo Debug] ─────────────────────────────────────
|
|
110
|
+
`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const responseCacheInstances = new Map;
|
|
115
|
+
function getCacheConfigKey(option) {
|
|
116
|
+
if (option === true)
|
|
117
|
+
return "default";
|
|
118
|
+
if (option === false)
|
|
119
|
+
return "disabled";
|
|
120
|
+
const cfg = option;
|
|
121
|
+
return JSON.stringify({
|
|
122
|
+
cacheDir: cfg.cacheDir || null,
|
|
123
|
+
ttl: cfg.ttl || 300000,
|
|
124
|
+
maxEntries: cfg.maxEntries || 500,
|
|
125
|
+
methods: cfg.methods || ["GET", "HEAD"],
|
|
126
|
+
respectHeaders: cfg.respectHeaders !== false
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function getResponseCache(option) {
|
|
130
|
+
const key = getCacheConfigKey(option);
|
|
131
|
+
let cache = responseCacheInstances.get(key);
|
|
132
|
+
if (!cache) {
|
|
133
|
+
cache = new ResponseCache(option);
|
|
134
|
+
const existing = responseCacheInstances.get(key);
|
|
135
|
+
if (existing) {
|
|
136
|
+
return existing;
|
|
137
|
+
}
|
|
138
|
+
responseCacheInstances.set(key, cache);
|
|
139
|
+
}
|
|
140
|
+
return cache;
|
|
141
|
+
}
|
|
142
|
+
function parseCacheControlFromHeaders(headers) {
|
|
143
|
+
const cacheControl = headers["cache-control"] || "";
|
|
144
|
+
return {
|
|
145
|
+
noCache: cacheControl.includes("no-cache"),
|
|
146
|
+
mustRevalidate: cacheControl.includes("must-revalidate")
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function buildCachedRezoResponse(cached, config) {
|
|
150
|
+
const headers = new RezoHeaders(cached.headers);
|
|
151
|
+
return {
|
|
152
|
+
data: cached.data,
|
|
153
|
+
status: cached.status,
|
|
154
|
+
statusText: cached.statusText,
|
|
155
|
+
headers,
|
|
156
|
+
finalUrl: cached.url,
|
|
157
|
+
urls: [cached.url],
|
|
158
|
+
contentType: cached.headers["content-type"],
|
|
159
|
+
contentLength: parseInt(cached.headers["content-length"] || "0", 10) || 0,
|
|
160
|
+
cookies: {
|
|
161
|
+
array: [],
|
|
162
|
+
serialized: [],
|
|
163
|
+
netscape: "",
|
|
164
|
+
string: "",
|
|
165
|
+
setCookiesString: []
|
|
166
|
+
},
|
|
167
|
+
config: {
|
|
168
|
+
...config,
|
|
169
|
+
url: cached.url,
|
|
170
|
+
method: "GET",
|
|
171
|
+
headers,
|
|
172
|
+
adapterUsed: "curl",
|
|
173
|
+
fromCache: true
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function buildUrlTree(config, finalUrl) {
|
|
178
|
+
const urls = [];
|
|
179
|
+
if (config.rawUrl) {
|
|
180
|
+
urls.push(config.rawUrl);
|
|
181
|
+
} else if (config.url) {
|
|
182
|
+
const urlStr = typeof config.url === "string" ? config.url : config.url.toString();
|
|
183
|
+
urls.push(urlStr);
|
|
184
|
+
}
|
|
185
|
+
if (config.redirectHistory && config.redirectHistory.length > 0) {
|
|
186
|
+
for (const redirect of config.redirectHistory) {
|
|
187
|
+
const redirectUrl = typeof redirect.url === "string" ? redirect.url : redirect.url?.toString?.() || "";
|
|
188
|
+
if (redirectUrl && urls[urls.length - 1] !== redirectUrl) {
|
|
189
|
+
urls.push(redirectUrl);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (finalUrl && (urls.length === 0 || urls[urls.length - 1] !== finalUrl)) {
|
|
194
|
+
urls.push(finalUrl);
|
|
195
|
+
}
|
|
196
|
+
return urls.length > 0 ? urls : [finalUrl];
|
|
197
|
+
}
|
|
198
|
+
async function updateCookies(config, cookieStrings, url) {
|
|
199
|
+
if (!cookieStrings || cookieStrings.length === 0)
|
|
200
|
+
return;
|
|
201
|
+
const tempJar = new RezoCookieJar;
|
|
202
|
+
tempJar.setCookiesSync(cookieStrings, url);
|
|
203
|
+
const parsedCookies = tempJar.cookies();
|
|
204
|
+
const acceptedCookies = [];
|
|
205
|
+
let hookError = null;
|
|
206
|
+
if (config.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
|
|
207
|
+
for (const cookie of parsedCookies.array) {
|
|
208
|
+
let shouldAccept = true;
|
|
209
|
+
for (const hook of config.hooks.beforeCookie) {
|
|
210
|
+
try {
|
|
211
|
+
const result = await hook({
|
|
212
|
+
cookie,
|
|
213
|
+
source: "response",
|
|
214
|
+
url,
|
|
215
|
+
isValid: true
|
|
216
|
+
}, config);
|
|
217
|
+
if (result === false) {
|
|
218
|
+
shouldAccept = false;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
} catch (err) {
|
|
222
|
+
hookError = err;
|
|
223
|
+
if (config.debug) {
|
|
224
|
+
console.log("[Rezo Debug] beforeCookie hook error:", err);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (shouldAccept) {
|
|
229
|
+
acceptedCookies.push(cookie);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
acceptedCookies.push(...parsedCookies.array);
|
|
234
|
+
}
|
|
235
|
+
const acceptedCookieStrings = acceptedCookies.map((c) => c.toSetCookieString());
|
|
236
|
+
if (!config.disableCookieJar && config.cookieJar) {
|
|
237
|
+
config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
|
|
238
|
+
}
|
|
239
|
+
if (config.useCookies) {
|
|
240
|
+
const existingArray = config.responseCookies?.array || [];
|
|
241
|
+
for (const cookie of acceptedCookies) {
|
|
242
|
+
const existingIndex = existingArray.findIndex((c) => c.key === cookie.key && c.domain === cookie.domain);
|
|
243
|
+
if (existingIndex >= 0) {
|
|
244
|
+
existingArray[existingIndex] = cookie;
|
|
245
|
+
} else {
|
|
246
|
+
existingArray.push(cookie);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const mergedJar = new RezoCookieJar(existingArray, url);
|
|
250
|
+
config.responseCookies = mergedJar.cookies();
|
|
251
|
+
}
|
|
252
|
+
if (!hookError && config.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
|
|
253
|
+
for (const hook of config.hooks.afterCookie) {
|
|
254
|
+
try {
|
|
255
|
+
await hook(acceptedCookies, config);
|
|
256
|
+
} catch (err) {
|
|
257
|
+
if (config.debug) {
|
|
258
|
+
console.log("[Rezo Debug] afterCookie hook error:", err);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
19
264
|
function mergeRequestAndResponseCookies(requestCookies, responseCookies) {
|
|
20
265
|
if (!requestCookies || requestCookies.length === 0) {
|
|
21
266
|
return responseCookies;
|
|
@@ -1282,7 +1527,7 @@ class CurlCommandBuilder {
|
|
|
1282
1527
|
}
|
|
1283
1528
|
}
|
|
1284
1529
|
buildCookieConfig(config) {
|
|
1285
|
-
if (
|
|
1530
|
+
if (config.disableCookieJar) {
|
|
1286
1531
|
return;
|
|
1287
1532
|
}
|
|
1288
1533
|
const cookieJarFile = this.tempFiles.createTempFile("cookies", ".txt");
|
|
@@ -1483,10 +1728,18 @@ class CurlResponseParser {
|
|
|
1483
1728
|
config.transfer.bodySize = responseBody.length;
|
|
1484
1729
|
config.transfer.headerSize = headerSection.length;
|
|
1485
1730
|
config.responseCookies = cookies;
|
|
1486
|
-
const
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1731
|
+
const finalUrl = stats["redirect_url"] || config.url || "";
|
|
1732
|
+
const urls = buildUrlTree(config, finalUrl);
|
|
1733
|
+
const timingDurations = getTimingDurations(config);
|
|
1734
|
+
debugLog.responseHeaders(config, headers);
|
|
1735
|
+
debugLog.timing(config, {
|
|
1736
|
+
dns: timingDurations.dns,
|
|
1737
|
+
connect: timingDurations.tcp,
|
|
1738
|
+
tls: timingDurations.tls,
|
|
1739
|
+
ttfb: timingDurations.firstByte,
|
|
1740
|
+
total: timingDurations.total
|
|
1741
|
+
});
|
|
1742
|
+
debugLog.cookies(config, cookies.array?.length || 0);
|
|
1490
1743
|
return {
|
|
1491
1744
|
data,
|
|
1492
1745
|
status,
|
|
@@ -1496,7 +1749,7 @@ class CurlResponseParser {
|
|
|
1496
1749
|
config,
|
|
1497
1750
|
contentType: contentType || undefined,
|
|
1498
1751
|
contentLength: parseInt(stats["size_download"]) || responseBody.length,
|
|
1499
|
-
finalUrl
|
|
1752
|
+
finalUrl,
|
|
1500
1753
|
urls
|
|
1501
1754
|
};
|
|
1502
1755
|
}
|
|
@@ -1859,9 +2112,43 @@ async function executeRequest(options, defaultOptions, jar) {
|
|
|
1859
2112
|
throw new RezoError("No proxy available: All proxies exhausted or URL did not match whitelist/blacklist", config, "UNQ_NO_PROXY_AVAILABLE", originalRequest);
|
|
1860
2113
|
}
|
|
1861
2114
|
}
|
|
1862
|
-
const
|
|
1863
|
-
const
|
|
1864
|
-
const
|
|
2115
|
+
const cacheOption = options.cache;
|
|
2116
|
+
const method = (options.method || "GET").toUpperCase();
|
|
2117
|
+
const requestUrl = typeof originalRequest.url === "string" ? originalRequest.url : originalRequest.url?.toString() || "";
|
|
2118
|
+
let cache;
|
|
2119
|
+
let requestHeaders;
|
|
2120
|
+
let cachedEntry;
|
|
2121
|
+
let needsRevalidation = false;
|
|
2122
|
+
const isStream = options._isStream || options.responseType === "stream";
|
|
2123
|
+
const isDownload = options._isDownload || !!options.fileName || !!options.saveTo || options.responseType === "download";
|
|
2124
|
+
const isUpload = options._isUpload || options.responseType === "upload";
|
|
2125
|
+
if (cacheOption && !isStream && !isDownload && !isUpload) {
|
|
2126
|
+
cache = getResponseCache(cacheOption);
|
|
2127
|
+
requestHeaders = originalRequest.headers instanceof RezoHeaders ? Object.fromEntries(originalRequest.headers.entries()) : originalRequest.headers;
|
|
2128
|
+
cachedEntry = cache.get(method, requestUrl, requestHeaders);
|
|
2129
|
+
if (cachedEntry) {
|
|
2130
|
+
const cacheControl = parseCacheControlFromHeaders(cachedEntry.headers);
|
|
2131
|
+
if (cacheControl.noCache || cacheControl.mustRevalidate) {
|
|
2132
|
+
needsRevalidation = true;
|
|
2133
|
+
} else {
|
|
2134
|
+
return buildCachedRezoResponse(cachedEntry, config);
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
const conditionalHeaders = cache.getConditionalHeaders(method, requestUrl, requestHeaders);
|
|
2138
|
+
if (conditionalHeaders) {
|
|
2139
|
+
if (originalRequest.headers instanceof RezoHeaders) {
|
|
2140
|
+
for (const [key, value] of Object.entries(conditionalHeaders)) {
|
|
2141
|
+
originalRequest.headers.set(key, value);
|
|
2142
|
+
}
|
|
2143
|
+
} else {
|
|
2144
|
+
originalRequest.headers = {
|
|
2145
|
+
...originalRequest.headers,
|
|
2146
|
+
...conditionalHeaders
|
|
2147
|
+
};
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
debugLog.requestStart(config, requestUrl, method);
|
|
1865
2152
|
let streamResponse;
|
|
1866
2153
|
let downloadResponse;
|
|
1867
2154
|
let uploadResponse;
|
|
@@ -1911,6 +2198,23 @@ async function executeRequest(options, defaultOptions, jar) {
|
|
|
1911
2198
|
if (proxyManager && selectedProxy) {
|
|
1912
2199
|
proxyManager.reportSuccess(selectedProxy);
|
|
1913
2200
|
}
|
|
2201
|
+
const duration = perform.now();
|
|
2202
|
+
debugLog.response(config, response.status, response.statusText, duration);
|
|
2203
|
+
debugLog.cookies(config, response.cookies?.array?.length || 0);
|
|
2204
|
+
if (cache) {
|
|
2205
|
+
if (response.status === 304 && cachedEntry) {
|
|
2206
|
+
const responseHeaders = response.headers instanceof RezoHeaders ? Object.fromEntries(response.headers.entries()) : response.headers;
|
|
2207
|
+
const updatedCached = cache.updateRevalidated(method, requestUrl, responseHeaders, requestHeaders);
|
|
2208
|
+
if (updatedCached) {
|
|
2209
|
+
return buildCachedRezoResponse(updatedCached, config);
|
|
2210
|
+
}
|
|
2211
|
+
return buildCachedRezoResponse(cachedEntry, config);
|
|
2212
|
+
}
|
|
2213
|
+
if (response.status >= 200 && response.status < 300) {
|
|
2214
|
+
cache.set(method, requestUrl, response, requestHeaders);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
debugLog.complete(config, response.finalUrl || requestUrl, config.redirectHistory?.length || 0, duration);
|
|
1914
2218
|
if (response.status >= 400) {
|
|
1915
2219
|
const httpError = builErrorFromResponse(`Request failed with status code ${response.status}`, response, config, originalRequest);
|
|
1916
2220
|
if (config.retry) {
|
|
@@ -1920,12 +2224,19 @@ async function executeRequest(options, defaultOptions, jar) {
|
|
|
1920
2224
|
const retryDelay = config.retry.retryDelay || 0;
|
|
1921
2225
|
const incrementDelay = config.retry.incrementDelay || false;
|
|
1922
2226
|
const delay = incrementDelay ? retryDelay * (config.retryAttempts + 1) : retryDelay;
|
|
2227
|
+
debugLog.retry(config, config.retryAttempts + 1, maxRetries, response.status, delay);
|
|
2228
|
+
if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
|
|
2229
|
+
for (const hook of config.hooks.beforeRetry) {
|
|
2230
|
+
await hook(config, httpError, config.retryAttempts + 1);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
1923
2233
|
if (delay > 0) {
|
|
1924
2234
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1925
2235
|
}
|
|
1926
2236
|
config.retryAttempts++;
|
|
1927
2237
|
return executeRequest(options, defaultOptions, jar);
|
|
1928
2238
|
}
|
|
2239
|
+
debugLog.maxRetries(config, maxRetries);
|
|
1929
2240
|
}
|
|
1930
2241
|
throw httpError;
|
|
1931
2242
|
}
|