lifecycleion 0.0.20 → 0.0.21
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/README.md +39 -36
- package/dist/lib/event-emitter.cjs +195 -9
- package/dist/lib/event-emitter.cjs.map +1 -1
- package/dist/lib/event-emitter.js +195 -9
- package/dist/lib/event-emitter.js.map +1 -1
- package/dist/lib/global-event-target.cjs +217 -0
- package/dist/lib/global-event-target.cjs.map +1 -0
- package/dist/lib/global-event-target.d.cts +70 -0
- package/dist/lib/global-event-target.d.ts +70 -0
- package/dist/lib/global-event-target.js +189 -0
- package/dist/lib/global-event-target.js.map +1 -0
- package/dist/lib/http-client/index.cjs +554 -193
- package/dist/lib/http-client/index.cjs.map +1 -1
- package/dist/lib/http-client/index.d.cts +9 -3
- package/dist/lib/http-client/index.d.ts +9 -3
- package/dist/lib/http-client/index.js +554 -193
- package/dist/lib/http-client/index.js.map +1 -1
- package/dist/lib/http-client-mock/index.cjs +71 -10
- package/dist/lib/http-client-mock/index.cjs.map +1 -1
- package/dist/lib/http-client-mock/index.d.cts +50 -3
- package/dist/lib/http-client-mock/index.d.ts +50 -3
- package/dist/lib/http-client-mock/index.js +71 -10
- package/dist/lib/http-client-mock/index.js.map +1 -1
- package/dist/lib/http-client-node/index.cjs +98 -19
- package/dist/lib/http-client-node/index.cjs.map +1 -1
- package/dist/lib/http-client-node/index.d.cts +2 -2
- package/dist/lib/http-client-node/index.d.ts +2 -2
- package/dist/lib/http-client-node/index.js +98 -19
- package/dist/lib/http-client-node/index.js.map +1 -1
- package/dist/lib/http-client-xhr/index.cjs.map +1 -1
- package/dist/lib/http-client-xhr/index.d.cts +2 -2
- package/dist/lib/http-client-xhr/index.d.ts +2 -2
- package/dist/lib/http-client-xhr/index.js.map +1 -1
- package/dist/lib/lifecycle-manager/index.cjs +199 -13
- package/dist/lib/lifecycle-manager/index.cjs.map +1 -1
- package/dist/lib/lifecycle-manager/index.js +199 -13
- package/dist/lib/lifecycle-manager/index.js.map +1 -1
- package/dist/lib/logger/index.cjs +203 -21
- package/dist/lib/logger/index.cjs.map +1 -1
- package/dist/lib/logger/index.d.cts +5 -1
- package/dist/lib/logger/index.d.ts +5 -1
- package/dist/lib/logger/index.js +203 -21
- package/dist/lib/logger/index.js.map +1 -1
- package/dist/lib/lru-cache/index.cjs +195 -9
- package/dist/lib/lru-cache/index.cjs.map +1 -1
- package/dist/lib/lru-cache/index.js +195 -9
- package/dist/lib/lru-cache/index.js.map +1 -1
- package/dist/lib/process-signal-manager.cjs +199 -13
- package/dist/lib/process-signal-manager.cjs.map +1 -1
- package/dist/lib/process-signal-manager.js +199 -13
- package/dist/lib/process-signal-manager.js.map +1 -1
- package/dist/lib/promise-protected-resolver.cjs +195 -9
- package/dist/lib/promise-protected-resolver.cjs.map +1 -1
- package/dist/lib/promise-protected-resolver.js +195 -9
- package/dist/lib/promise-protected-resolver.js.map +1 -1
- package/dist/lib/retry-utils/index.cjs +195 -9
- package/dist/lib/retry-utils/index.cjs.map +1 -1
- package/dist/lib/retry-utils/index.js +195 -9
- package/dist/lib/retry-utils/index.js.map +1 -1
- package/dist/lib/safe-handle-callback.cjs +196 -18
- package/dist/lib/safe-handle-callback.cjs.map +1 -1
- package/dist/lib/safe-handle-callback.d.cts +14 -4
- package/dist/lib/safe-handle-callback.d.ts +14 -4
- package/dist/lib/safe-handle-callback.js +196 -18
- package/dist/lib/safe-handle-callback.js.map +1 -1
- package/dist/lib/single-event-observer.cjs +195 -9
- package/dist/lib/single-event-observer.cjs.map +1 -1
- package/dist/lib/single-event-observer.js +195 -9
- package/dist/lib/single-event-observer.js.map +1 -1
- package/dist/{types-6G59m8U9.d.cts → types-BFvpJPMt.d.cts} +71 -10
- package/dist/{types-CG10j6Lc.d.ts → types-BONtIhQ5.d.ts} +71 -10
- package/package.json +12 -2
|
@@ -1227,18 +1227,204 @@ function isFunction(value) {
|
|
|
1227
1227
|
return typeof value === "function" || value instanceof Function;
|
|
1228
1228
|
}
|
|
1229
1229
|
|
|
1230
|
+
// src/lib/global-event-target.ts
|
|
1231
|
+
var GLOBAL_KEY = "__lifecycleion_global_event_target__";
|
|
1232
|
+
var METHOD_NAMES = [
|
|
1233
|
+
"addEventListener",
|
|
1234
|
+
"removeEventListener",
|
|
1235
|
+
"dispatchEvent"
|
|
1236
|
+
];
|
|
1237
|
+
var g = globalThis;
|
|
1238
|
+
function getState() {
|
|
1239
|
+
const value = readGlobal(GLOBAL_KEY);
|
|
1240
|
+
return value === UNREADABLE ? void 0 : asUsableState(value);
|
|
1241
|
+
}
|
|
1242
|
+
function asUsableState(value) {
|
|
1243
|
+
if (typeof value !== "object" || value === null) {
|
|
1244
|
+
return void 0;
|
|
1245
|
+
}
|
|
1246
|
+
return asUsableTarget(readMember(value, "target")) === null ? void 0 : value;
|
|
1247
|
+
}
|
|
1248
|
+
function asUsableTarget(value) {
|
|
1249
|
+
if (typeof value !== "object" || value === null) {
|
|
1250
|
+
return null;
|
|
1251
|
+
}
|
|
1252
|
+
for (const name of METHOD_NAMES) {
|
|
1253
|
+
if (typeof readMember(value, name) !== "function") {
|
|
1254
|
+
return null;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
return value;
|
|
1258
|
+
}
|
|
1259
|
+
function bindTargetMethods(target) {
|
|
1260
|
+
const bound = {};
|
|
1261
|
+
for (const name of METHOD_NAMES) {
|
|
1262
|
+
const method = readMember(target, name);
|
|
1263
|
+
if (typeof method !== "function") {
|
|
1264
|
+
return null;
|
|
1265
|
+
}
|
|
1266
|
+
let boundMethod;
|
|
1267
|
+
try {
|
|
1268
|
+
boundMethod = method.bind(target);
|
|
1269
|
+
} catch {
|
|
1270
|
+
return null;
|
|
1271
|
+
}
|
|
1272
|
+
if (typeof boundMethod !== "function") {
|
|
1273
|
+
return null;
|
|
1274
|
+
}
|
|
1275
|
+
bound[name] = boundMethod;
|
|
1276
|
+
}
|
|
1277
|
+
return bound;
|
|
1278
|
+
}
|
|
1279
|
+
function isStateInstalled(state) {
|
|
1280
|
+
return state !== void 0 && readMember(state, "isInstalled") === true;
|
|
1281
|
+
}
|
|
1282
|
+
function readStateTarget(state) {
|
|
1283
|
+
if (state === void 0) {
|
|
1284
|
+
return null;
|
|
1285
|
+
}
|
|
1286
|
+
return asUsableTarget(readMember(state, "target"));
|
|
1287
|
+
}
|
|
1288
|
+
var UNREADABLE = /* @__PURE__ */ Symbol("lifecycleion.unreadable");
|
|
1289
|
+
function readGlobal(name) {
|
|
1290
|
+
try {
|
|
1291
|
+
return g[name];
|
|
1292
|
+
} catch {
|
|
1293
|
+
return UNREADABLE;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
function readMember(source, key) {
|
|
1297
|
+
try {
|
|
1298
|
+
return source[key];
|
|
1299
|
+
} catch {
|
|
1300
|
+
return UNREADABLE;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
function probeMember(name) {
|
|
1304
|
+
const value = readGlobal(name);
|
|
1305
|
+
if (value === UNREADABLE) {
|
|
1306
|
+
return "hostile";
|
|
1307
|
+
}
|
|
1308
|
+
if (typeof value === "function") {
|
|
1309
|
+
return "usable";
|
|
1310
|
+
}
|
|
1311
|
+
return value === void 0 ? "absent" : "occupied";
|
|
1312
|
+
}
|
|
1313
|
+
function canDefineProperty(key) {
|
|
1314
|
+
const descriptor = Object.getOwnPropertyDescriptor(g, key);
|
|
1315
|
+
if (descriptor === void 0) {
|
|
1316
|
+
return Object.isExtensible(g);
|
|
1317
|
+
}
|
|
1318
|
+
return descriptor.configurable === true;
|
|
1319
|
+
}
|
|
1320
|
+
function installGlobalEventTarget() {
|
|
1321
|
+
const members = METHOD_NAMES.map((name) => probeMember(name));
|
|
1322
|
+
if (members.every((member) => member === "usable")) {
|
|
1323
|
+
return isStateInstalled(getState()) ? "already-installed" : "native";
|
|
1324
|
+
}
|
|
1325
|
+
if (members.some((member) => member !== "absent")) {
|
|
1326
|
+
return "partial";
|
|
1327
|
+
}
|
|
1328
|
+
const eventTargetConstructor = readGlobal("EventTarget");
|
|
1329
|
+
if (typeof eventTargetConstructor !== "function") {
|
|
1330
|
+
return "unsupported";
|
|
1331
|
+
}
|
|
1332
|
+
const isDefinable = [...METHOD_NAMES, GLOBAL_KEY].every(
|
|
1333
|
+
(key) => canDefineProperty(key)
|
|
1334
|
+
);
|
|
1335
|
+
if (!isDefinable) {
|
|
1336
|
+
return "blocked";
|
|
1337
|
+
}
|
|
1338
|
+
const existingState = getState();
|
|
1339
|
+
const defined = [];
|
|
1340
|
+
const priorStateDescriptor = Object.getOwnPropertyDescriptor(g, GLOBAL_KEY);
|
|
1341
|
+
const rollback = () => {
|
|
1342
|
+
for (const key of defined) {
|
|
1343
|
+
if (key === GLOBAL_KEY && priorStateDescriptor !== void 0) {
|
|
1344
|
+
try {
|
|
1345
|
+
Object.defineProperty(g, GLOBAL_KEY, priorStateDescriptor);
|
|
1346
|
+
} catch {
|
|
1347
|
+
}
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
try {
|
|
1351
|
+
Reflect.deleteProperty(g, key);
|
|
1352
|
+
} catch {
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
const reusableTarget = readStateTarget(existingState);
|
|
1357
|
+
const reusableMethods = reusableTarget === null ? null : bindTargetMethods(reusableTarget);
|
|
1358
|
+
let state;
|
|
1359
|
+
let methods;
|
|
1360
|
+
try {
|
|
1361
|
+
if (existingState === void 0 || reusableMethods === null) {
|
|
1362
|
+
let target;
|
|
1363
|
+
try {
|
|
1364
|
+
target = new eventTargetConstructor();
|
|
1365
|
+
} catch {
|
|
1366
|
+
return "unsupported";
|
|
1367
|
+
}
|
|
1368
|
+
const freshMethods = bindTargetMethods(target);
|
|
1369
|
+
if (freshMethods === null) {
|
|
1370
|
+
return "unsupported";
|
|
1371
|
+
}
|
|
1372
|
+
state = { target, isInstalled: false };
|
|
1373
|
+
methods = freshMethods;
|
|
1374
|
+
Object.defineProperty(g, GLOBAL_KEY, {
|
|
1375
|
+
value: state,
|
|
1376
|
+
enumerable: false,
|
|
1377
|
+
writable: false,
|
|
1378
|
+
configurable: true
|
|
1379
|
+
});
|
|
1380
|
+
defined.push(GLOBAL_KEY);
|
|
1381
|
+
} else {
|
|
1382
|
+
state = existingState;
|
|
1383
|
+
methods = reusableMethods;
|
|
1384
|
+
}
|
|
1385
|
+
for (const name of METHOD_NAMES) {
|
|
1386
|
+
Object.defineProperty(g, name, {
|
|
1387
|
+
value: methods[name],
|
|
1388
|
+
enumerable: false,
|
|
1389
|
+
writable: true,
|
|
1390
|
+
configurable: true
|
|
1391
|
+
});
|
|
1392
|
+
defined.push(name);
|
|
1393
|
+
}
|
|
1394
|
+
if (readMember(state, "isInstalled") !== true) {
|
|
1395
|
+
state.isInstalled = true;
|
|
1396
|
+
}
|
|
1397
|
+
} catch {
|
|
1398
|
+
rollback();
|
|
1399
|
+
return "blocked";
|
|
1400
|
+
}
|
|
1401
|
+
return "installed";
|
|
1402
|
+
}
|
|
1403
|
+
function isGlobalEventTargetAvailable() {
|
|
1404
|
+
return METHOD_NAMES.every((name) => probeMember(name) === "usable") && probeMember("ErrorEvent") === "usable";
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1230
1407
|
// src/lib/safe-handle-callback.ts
|
|
1408
|
+
installGlobalEventTarget();
|
|
1409
|
+
function reportCallbackError(callbackName, error) {
|
|
1410
|
+
installGlobalEventTarget();
|
|
1411
|
+
if (!isGlobalEventTargetAvailable()) {
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
try {
|
|
1415
|
+
globalThis.dispatchEvent(
|
|
1416
|
+
new ErrorEvent("reportError", {
|
|
1417
|
+
error: new Error(
|
|
1418
|
+
`Error in a callback ${callbackName}: ${DOUBLE_EOL}${errorToString(error)}`
|
|
1419
|
+
)
|
|
1420
|
+
})
|
|
1421
|
+
);
|
|
1422
|
+
} catch {
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1231
1425
|
async function safeHandleCallbackAndWait(callbackName, callback, ...args) {
|
|
1232
1426
|
const handleError = (error) => {
|
|
1233
|
-
|
|
1234
|
-
globalThis.dispatchEvent(
|
|
1235
|
-
new ErrorEvent("reportError", {
|
|
1236
|
-
error: new Error(
|
|
1237
|
-
`Error in a callback ${callbackName}: ${DOUBLE_EOL}${errorToString(error)}`
|
|
1238
|
-
)
|
|
1239
|
-
})
|
|
1240
|
-
);
|
|
1241
|
-
}
|
|
1427
|
+
reportCallbackError(callbackName, error);
|
|
1242
1428
|
return { success: false, error };
|
|
1243
1429
|
};
|
|
1244
1430
|
if (isFunction(callback)) {
|
|
@@ -2003,6 +2189,74 @@ function matchesFilter(filter, context, phaseType, kind) {
|
|
|
2003
2189
|
return true;
|
|
2004
2190
|
}
|
|
2005
2191
|
|
|
2192
|
+
// src/lib/http-client/internal/tls-error-utils.ts
|
|
2193
|
+
var CERT_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
2194
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
2195
|
+
"CERT_HAS_EXPIRED",
|
|
2196
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
2197
|
+
"ERR_TLS_CERT_ALTNAME_INVALID",
|
|
2198
|
+
"ERR_SSL_TLSV13_ALERT_CERTIFICATE_REQUIRED",
|
|
2199
|
+
"ERR_SSL_PEER_DID_NOT_RETURN_A_CERTIFICATE",
|
|
2200
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
2201
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
2202
|
+
"CERT_REVOKED"
|
|
2203
|
+
]);
|
|
2204
|
+
var CRL_CODE_PATTERN = /(?:^|_)CRLS?(?:_|$)/;
|
|
2205
|
+
var TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
2206
|
+
"ENOTFOUND",
|
|
2207
|
+
"EAI_AGAIN",
|
|
2208
|
+
"ECONNREFUSED",
|
|
2209
|
+
"ECONNRESET",
|
|
2210
|
+
"ECONNABORTED",
|
|
2211
|
+
"ETIMEDOUT",
|
|
2212
|
+
"EPIPE",
|
|
2213
|
+
"EHOSTUNREACH",
|
|
2214
|
+
"EHOSTDOWN",
|
|
2215
|
+
"ENETUNREACH",
|
|
2216
|
+
"ENETDOWN",
|
|
2217
|
+
"EADDRNOTAVAIL"
|
|
2218
|
+
]);
|
|
2219
|
+
var UNDICI_TRANSPORT_ERROR_PREFIX = "UND_ERR_";
|
|
2220
|
+
function isTLSCertificateError(error) {
|
|
2221
|
+
if (isTLSCertificateErrorSelf(error)) {
|
|
2222
|
+
return true;
|
|
2223
|
+
}
|
|
2224
|
+
const cause = readMember2(error, "cause");
|
|
2225
|
+
return isErrorValue(cause) ? isTLSCertificateErrorSelf(cause) : false;
|
|
2226
|
+
}
|
|
2227
|
+
function isErrorValue(value) {
|
|
2228
|
+
try {
|
|
2229
|
+
return value instanceof Error;
|
|
2230
|
+
} catch {
|
|
2231
|
+
return false;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
function isTLSCertificateErrorSelf(error) {
|
|
2235
|
+
const rawCode = readMember2(error, "code");
|
|
2236
|
+
const code = typeof rawCode === "string" ? rawCode : "";
|
|
2237
|
+
if (CERT_ERROR_CODES.has(code)) {
|
|
2238
|
+
return true;
|
|
2239
|
+
}
|
|
2240
|
+
if (CRL_CODE_PATTERN.test(code)) {
|
|
2241
|
+
return true;
|
|
2242
|
+
}
|
|
2243
|
+
if ((code.startsWith("ERR_TLS_") || code.startsWith("ERR_SSL_")) && code.includes("CERT")) {
|
|
2244
|
+
return true;
|
|
2245
|
+
}
|
|
2246
|
+
if (TRANSPORT_ERROR_CODES.has(code) || code.startsWith(UNDICI_TRANSPORT_ERROR_PREFIX)) {
|
|
2247
|
+
return false;
|
|
2248
|
+
}
|
|
2249
|
+
const message = readMember2(error, "message");
|
|
2250
|
+
return typeof message === "string" ? /certificate|self signed|unable to verify|altname/i.test(message) : false;
|
|
2251
|
+
}
|
|
2252
|
+
function readMember2(error, key) {
|
|
2253
|
+
try {
|
|
2254
|
+
return error[key];
|
|
2255
|
+
} catch {
|
|
2256
|
+
return void 0;
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2006
2260
|
// src/lib/http-client/consts.ts
|
|
2007
2261
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([
|
|
2008
2262
|
// 0: Browser/XHR-style "no response" status.
|
|
@@ -2038,6 +2292,7 @@ var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([
|
|
|
2038
2292
|
// 599 Network Connect Timeout Error (non-standard)
|
|
2039
2293
|
599
|
|
2040
2294
|
]);
|
|
2295
|
+
var NON_IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["POST", "PATCH"]);
|
|
2041
2296
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
2042
2297
|
var DEFAULT_REQUEST_ID_HEADER = "x-local-client-request-id";
|
|
2043
2298
|
var DEFAULT_REQUEST_ATTEMPT_HEADER = "x-local-client-request-attempt";
|
|
@@ -2123,12 +2378,23 @@ var FetchAdapter = class {
|
|
|
2123
2378
|
if (isAbortError(error) || signal?.aborted) {
|
|
2124
2379
|
throw error;
|
|
2125
2380
|
}
|
|
2381
|
+
const normalizedError = normalizeError(error);
|
|
2382
|
+
if (isTLSCertificateError(normalizedError)) {
|
|
2383
|
+
return {
|
|
2384
|
+
status: 495,
|
|
2385
|
+
isTransportError: true,
|
|
2386
|
+
isRetryable: false,
|
|
2387
|
+
headers: {},
|
|
2388
|
+
body: null,
|
|
2389
|
+
errorCause: normalizedError
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2126
2392
|
return {
|
|
2127
2393
|
status: 0,
|
|
2128
2394
|
isTransportError: true,
|
|
2129
2395
|
headers: {},
|
|
2130
2396
|
body: null,
|
|
2131
|
-
errorCause:
|
|
2397
|
+
errorCause: normalizedError
|
|
2132
2398
|
};
|
|
2133
2399
|
}
|
|
2134
2400
|
if (response.type === "opaqueredirect") {
|
|
@@ -2142,13 +2408,43 @@ var FetchAdapter = class {
|
|
|
2142
2408
|
};
|
|
2143
2409
|
}
|
|
2144
2410
|
request.onUploadProgress?.({ loaded: 1, total: 1, progress: 1 });
|
|
2145
|
-
const
|
|
2411
|
+
const responseHeadersForBody = extractFetchHeaders(response.headers);
|
|
2412
|
+
let rawBody;
|
|
2413
|
+
try {
|
|
2414
|
+
rawBody = await readResponseBody(method, response);
|
|
2415
|
+
} catch (error) {
|
|
2416
|
+
if (isAbortError(error) || signal?.aborted) {
|
|
2417
|
+
throw markResponseStreamAbort(
|
|
2418
|
+
error,
|
|
2419
|
+
response.status,
|
|
2420
|
+
responseHeadersForBody
|
|
2421
|
+
);
|
|
2422
|
+
}
|
|
2423
|
+
const detectedRedirectURL2 = resolveDetectedRedirectURL(
|
|
2424
|
+
requestURL,
|
|
2425
|
+
response.status,
|
|
2426
|
+
responseHeadersForBody
|
|
2427
|
+
);
|
|
2428
|
+
return {
|
|
2429
|
+
status: response.status,
|
|
2430
|
+
wasRedirectDetected: detectedRedirectURL2 !== void 0 || REDIRECT_STATUS_CODES.has(response.status),
|
|
2431
|
+
...detectedRedirectURL2 ? { detectedRedirectURL: detectedRedirectURL2 } : {},
|
|
2432
|
+
headers: responseHeadersForBody,
|
|
2433
|
+
body: null,
|
|
2434
|
+
isStreamError: true,
|
|
2435
|
+
// fetch buffers the body for us, so there is no per-chunk delivery to
|
|
2436
|
+
// distinguish a local write failure from an upstream stream failure.
|
|
2437
|
+
// Everything reaching here is an upstream/transfer failure.
|
|
2438
|
+
streamErrorCode: "stream_response_error",
|
|
2439
|
+
errorCause: normalizeError(error)
|
|
2440
|
+
};
|
|
2441
|
+
}
|
|
2146
2442
|
request.onDownloadProgress?.({
|
|
2147
2443
|
loaded: rawBody?.length ?? 0,
|
|
2148
2444
|
total: rawBody?.length ?? 0,
|
|
2149
2445
|
progress: 1
|
|
2150
2446
|
});
|
|
2151
|
-
const responseHeaders =
|
|
2447
|
+
const responseHeaders = responseHeadersForBody;
|
|
2152
2448
|
const detectedRedirectURL = resolveDetectedRedirectURL(
|
|
2153
2449
|
requestURL,
|
|
2154
2450
|
response.status,
|
|
@@ -2173,7 +2469,33 @@ async function readResponseBody(method, response) {
|
|
|
2173
2469
|
return new Uint8Array(buffer);
|
|
2174
2470
|
}
|
|
2175
2471
|
function isAbortError(error) {
|
|
2176
|
-
|
|
2472
|
+
const normalized = asError(error);
|
|
2473
|
+
return normalized !== void 0 && readObjectMember(normalized, "name") === "AbortError";
|
|
2474
|
+
}
|
|
2475
|
+
function asError(value) {
|
|
2476
|
+
try {
|
|
2477
|
+
return value instanceof Error ? value : void 0;
|
|
2478
|
+
} catch {
|
|
2479
|
+
return void 0;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
function normalizeError(value) {
|
|
2483
|
+
const existing = asError(value);
|
|
2484
|
+
if (existing !== void 0) {
|
|
2485
|
+
return existing;
|
|
2486
|
+
}
|
|
2487
|
+
try {
|
|
2488
|
+
return new Error(String(value));
|
|
2489
|
+
} catch {
|
|
2490
|
+
return new Error("Unknown error");
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
function readObjectMember(source, key) {
|
|
2494
|
+
try {
|
|
2495
|
+
return source[key];
|
|
2496
|
+
} catch {
|
|
2497
|
+
return void 0;
|
|
2498
|
+
}
|
|
2177
2499
|
}
|
|
2178
2500
|
function materializeFetchHeaders(headers) {
|
|
2179
2501
|
let shouldUseHeadersObject = false;
|
|
@@ -2202,6 +2524,22 @@ function materializeFetchHeaders(headers) {
|
|
|
2202
2524
|
}
|
|
2203
2525
|
return materialized;
|
|
2204
2526
|
}
|
|
2527
|
+
function markResponseStreamAbort(error, status, headers) {
|
|
2528
|
+
const original = asError(error);
|
|
2529
|
+
const originalMessage = original === void 0 ? void 0 : readObjectMember(original, "message");
|
|
2530
|
+
const originalName = original === void 0 ? void 0 : readObjectMember(original, "name");
|
|
2531
|
+
const tagged = new Error(
|
|
2532
|
+
typeof originalMessage === "string" ? originalMessage : "Request aborted"
|
|
2533
|
+
);
|
|
2534
|
+
tagged.name = typeof originalName === "string" ? originalName : "AbortError";
|
|
2535
|
+
Object.assign(tagged, {
|
|
2536
|
+
[RESPONSE_STREAM_ABORT_FLAG]: true,
|
|
2537
|
+
streamAbortStatus: status,
|
|
2538
|
+
streamAbortHeaders: headers,
|
|
2539
|
+
cause: error
|
|
2540
|
+
});
|
|
2541
|
+
return tagged;
|
|
2542
|
+
}
|
|
2205
2543
|
|
|
2206
2544
|
// src/lib/http-client/internal/header-utils.ts
|
|
2207
2545
|
function isBrowserRestrictedHeader(key, value) {
|
|
@@ -2361,6 +2699,7 @@ var HTTPRequestBuilder = class {
|
|
|
2361
2699
|
_timeout;
|
|
2362
2700
|
_signal;
|
|
2363
2701
|
_retryPolicy;
|
|
2702
|
+
_retryNonIdempotentMethods;
|
|
2364
2703
|
_label;
|
|
2365
2704
|
_onUploadProgress;
|
|
2366
2705
|
_onDownloadProgress;
|
|
@@ -2445,6 +2784,15 @@ var HTTPRequestBuilder = class {
|
|
|
2445
2784
|
this._retryPolicy = options;
|
|
2446
2785
|
return this;
|
|
2447
2786
|
}
|
|
2787
|
+
/**
|
|
2788
|
+
* Allow or forbid retrying this request when its method is not idempotent
|
|
2789
|
+
* (`POST`, `PATCH`). Overrides the client config for this request only.
|
|
2790
|
+
*/
|
|
2791
|
+
retryNonIdempotentMethods(allow) {
|
|
2792
|
+
this._assertNotSent("retryNonIdempotentMethods");
|
|
2793
|
+
this._retryNonIdempotentMethods = allow;
|
|
2794
|
+
return this;
|
|
2795
|
+
}
|
|
2448
2796
|
onUploadProgress(fn) {
|
|
2449
2797
|
this._assertNotSent("onUploadProgress");
|
|
2450
2798
|
this._onUploadProgress = fn;
|
|
@@ -2573,6 +2921,7 @@ var HTTPRequestBuilder = class {
|
|
|
2573
2921
|
timeout: this._timeout,
|
|
2574
2922
|
signal: this._signal,
|
|
2575
2923
|
retryPolicy: this._retryPolicy,
|
|
2924
|
+
retryNonIdempotentMethods: this._retryNonIdempotentMethods,
|
|
2576
2925
|
label: this._label,
|
|
2577
2926
|
onUploadProgress: this._onUploadProgress,
|
|
2578
2927
|
onDownloadProgress: this._onDownloadProgress,
|
|
@@ -2632,6 +2981,9 @@ var HTTPRequestBuilder = class {
|
|
|
2632
2981
|
if (opts.retryPolicy !== void 0) {
|
|
2633
2982
|
this.retryPolicy(opts.retryPolicy);
|
|
2634
2983
|
}
|
|
2984
|
+
if (opts.retryNonIdempotentMethods !== void 0) {
|
|
2985
|
+
this.retryNonIdempotentMethods(opts.retryNonIdempotentMethods);
|
|
2986
|
+
}
|
|
2635
2987
|
if (opts.label !== void 0) {
|
|
2636
2988
|
this.label(opts.label);
|
|
2637
2989
|
}
|
|
@@ -2830,6 +3182,7 @@ var BaseHTTPClient = class {
|
|
|
2830
3182
|
timeout: config.timeout ?? DEFAULT_TIMEOUT_MS,
|
|
2831
3183
|
cookieJar: config.cookieJar,
|
|
2832
3184
|
retryPolicy: config.retryPolicy,
|
|
3185
|
+
retryNonIdempotentMethods: config.retryNonIdempotentMethods ?? false,
|
|
2833
3186
|
includeRequestID: config.includeRequestID ?? false,
|
|
2834
3187
|
includeAttemptHeader: config.includeAttemptHeader ?? false,
|
|
2835
3188
|
userAgent: config.userAgent,
|
|
@@ -3109,7 +3462,7 @@ var BaseHTTPClient = class {
|
|
|
3109
3462
|
requestID,
|
|
3110
3463
|
false,
|
|
3111
3464
|
"interceptor_error",
|
|
3112
|
-
|
|
3465
|
+
normalizeError2(error)
|
|
3113
3466
|
);
|
|
3114
3467
|
callbacks.setError(normalizedError);
|
|
3115
3468
|
trackedCallbacks.setState("failed");
|
|
@@ -3214,7 +3567,14 @@ var BaseHTTPClient = class {
|
|
|
3214
3567
|
body: null
|
|
3215
3568
|
},
|
|
3216
3569
|
requestID,
|
|
3570
|
+
// Provably false: a cancel settles with no adapter response, and
|
|
3571
|
+
// this branch is guarded on having one.
|
|
3217
3572
|
wasCancelled: false,
|
|
3573
|
+
// Hardcoded even when a per-attempt timeout struck mid-body. The
|
|
3574
|
+
// request ends at the redirect either way, so `redirect_disabled`
|
|
3575
|
+
// is the outcome the caller acts on; surfacing the timeout would
|
|
3576
|
+
// reclassify the error code on whether the body happened to
|
|
3577
|
+
// finish. See docs/http-client.md.
|
|
3218
3578
|
wasTimeout: false,
|
|
3219
3579
|
adapterType: this._adapter.getType(),
|
|
3220
3580
|
initialURL: finalRequest.requestURL,
|
|
@@ -3225,7 +3585,7 @@ var BaseHTTPClient = class {
|
|
|
3225
3585
|
errorCode = "redirect_disabled";
|
|
3226
3586
|
break;
|
|
3227
3587
|
}
|
|
3228
|
-
if (this._config.followRedirects && adapterResponse && REDIRECT_STATUS_CODES.has(adapterResponse.status)) {
|
|
3588
|
+
if (this._config.followRedirects && adapterResponse && !adapterResponse.isStreamError && REDIRECT_STATUS_CODES.has(adapterResponse.status)) {
|
|
3229
3589
|
hopCount++;
|
|
3230
3590
|
if (hopCount > this._config.maxRedirects) {
|
|
3231
3591
|
response = this._buildResponse({
|
|
@@ -3340,7 +3700,7 @@ var BaseHTTPClient = class {
|
|
|
3340
3700
|
isNetworkErrorOverride: false
|
|
3341
3701
|
});
|
|
3342
3702
|
errorCode = "interceptor_error";
|
|
3343
|
-
adapterCause =
|
|
3703
|
+
adapterCause = normalizeError2(error);
|
|
3344
3704
|
break;
|
|
3345
3705
|
}
|
|
3346
3706
|
if ("cancel" in redirectIntercept) {
|
|
@@ -3418,7 +3778,7 @@ var BaseHTTPClient = class {
|
|
|
3418
3778
|
requestID,
|
|
3419
3779
|
false,
|
|
3420
3780
|
"request_setup_error",
|
|
3421
|
-
|
|
3781
|
+
normalizeError2(error)
|
|
3422
3782
|
);
|
|
3423
3783
|
callbacks.setAttemptCount(completedAttemptCount);
|
|
3424
3784
|
callbacks.setNextRetryDelayMS(null);
|
|
@@ -3555,11 +3915,28 @@ var BaseHTTPClient = class {
|
|
|
3555
3915
|
const startAttempt = params.startAttemptNumber ?? 1;
|
|
3556
3916
|
const redirectHistory = params.redirectHistory ?? [];
|
|
3557
3917
|
const cookieJar = params.cookieJar ?? null;
|
|
3918
|
+
const isRetryAvailable = () => policy !== null && policy.errors.length < policy.maxRetryAttempts;
|
|
3919
|
+
const allowNonIdempotentRetry = options.retryNonIdempotentMethods ?? this._config.retryNonIdempotentMethods;
|
|
3558
3920
|
let attemptNumber = startAttempt - 1;
|
|
3559
3921
|
let isRetriesExhausted = false;
|
|
3560
3922
|
while (true) {
|
|
3561
3923
|
attemptNumber++;
|
|
3562
3924
|
const isRetry = attemptNumber > startAttempt;
|
|
3925
|
+
const emitAttemptEnd = (outcome) => {
|
|
3926
|
+
options.onAttemptEnd?.({
|
|
3927
|
+
attemptNumber,
|
|
3928
|
+
isRetry,
|
|
3929
|
+
nextRetryDelayMS: void 0,
|
|
3930
|
+
nextRetryAt: void 0,
|
|
3931
|
+
...outcome,
|
|
3932
|
+
requestID,
|
|
3933
|
+
initialURL,
|
|
3934
|
+
...hopContext ? {
|
|
3935
|
+
hopNumber: hopContext.hopNumber,
|
|
3936
|
+
redirect: hopContext.redirect
|
|
3937
|
+
} : {}
|
|
3938
|
+
});
|
|
3939
|
+
};
|
|
3563
3940
|
if (attemptNumber === 1) {
|
|
3564
3941
|
callbacks.setStartedAt(Date.now());
|
|
3565
3942
|
} else {
|
|
@@ -3621,19 +3998,11 @@ var BaseHTTPClient = class {
|
|
|
3621
3998
|
}
|
|
3622
3999
|
} catch (error) {
|
|
3623
4000
|
clearTimeout(timeoutID);
|
|
3624
|
-
|
|
3625
|
-
attemptNumber,
|
|
3626
|
-
isRetry,
|
|
4001
|
+
emitAttemptEnd({
|
|
3627
4002
|
willRetry: false,
|
|
3628
4003
|
nextRetryDelayMS: void 0,
|
|
3629
4004
|
nextRetryAt: void 0,
|
|
3630
|
-
status: 0
|
|
3631
|
-
requestID,
|
|
3632
|
-
initialURL,
|
|
3633
|
-
...hopContext ? {
|
|
3634
|
-
hopNumber: hopContext.hopNumber,
|
|
3635
|
-
redirect: hopContext.redirect
|
|
3636
|
-
} : {}
|
|
4005
|
+
status: 0
|
|
3637
4006
|
});
|
|
3638
4007
|
return {
|
|
3639
4008
|
adapterResponse: null,
|
|
@@ -3647,24 +4016,16 @@ var BaseHTTPClient = class {
|
|
|
3647
4016
|
wasTimeout: false,
|
|
3648
4017
|
isRetriesExhausted: false,
|
|
3649
4018
|
errorCode: "interceptor_error",
|
|
3650
|
-
adapterCause:
|
|
4019
|
+
adapterCause: normalizeError2(error)
|
|
3651
4020
|
};
|
|
3652
4021
|
}
|
|
3653
4022
|
if ("cancel" in retryIntercept) {
|
|
3654
4023
|
clearTimeout(timeoutID);
|
|
3655
|
-
|
|
3656
|
-
attemptNumber,
|
|
3657
|
-
isRetry,
|
|
4024
|
+
emitAttemptEnd({
|
|
3658
4025
|
willRetry: false,
|
|
3659
4026
|
nextRetryDelayMS: void 0,
|
|
3660
4027
|
nextRetryAt: void 0,
|
|
3661
|
-
status: 0
|
|
3662
|
-
requestID,
|
|
3663
|
-
initialURL,
|
|
3664
|
-
...hopContext ? {
|
|
3665
|
-
hopNumber: hopContext.hopNumber,
|
|
3666
|
-
redirect: hopContext.redirect
|
|
3667
|
-
} : {}
|
|
4028
|
+
status: 0
|
|
3668
4029
|
});
|
|
3669
4030
|
return {
|
|
3670
4031
|
adapterResponse: null,
|
|
@@ -3737,19 +4098,11 @@ var BaseHTTPClient = class {
|
|
|
3737
4098
|
);
|
|
3738
4099
|
}
|
|
3739
4100
|
if (adapterResponse.wasRedirectDetected && adapterResponse.status === 0 && !this._config.followRedirects) {
|
|
3740
|
-
|
|
3741
|
-
attemptNumber,
|
|
3742
|
-
isRetry,
|
|
4101
|
+
emitAttemptEnd({
|
|
3743
4102
|
willRetry: false,
|
|
3744
4103
|
nextRetryDelayMS: void 0,
|
|
3745
4104
|
nextRetryAt: void 0,
|
|
3746
|
-
status: 0
|
|
3747
|
-
requestID,
|
|
3748
|
-
initialURL,
|
|
3749
|
-
...hopContext ? {
|
|
3750
|
-
hopNumber: hopContext.hopNumber,
|
|
3751
|
-
redirect: hopContext.redirect
|
|
3752
|
-
} : {}
|
|
4105
|
+
status: 0
|
|
3753
4106
|
});
|
|
3754
4107
|
return {
|
|
3755
4108
|
adapterResponse,
|
|
@@ -3761,7 +4114,10 @@ var BaseHTTPClient = class {
|
|
|
3761
4114
|
errorCode: "redirect_disabled"
|
|
3762
4115
|
};
|
|
3763
4116
|
}
|
|
3764
|
-
|
|
4117
|
+
const isTransportOutcome = adapterResponse.isTransportError === true;
|
|
4118
|
+
const isMethodReplayable = allowNonIdempotentRetry || !NON_IDEMPOTENT_METHODS.has(sentRequest.method) || isTransportOutcome && adapterResponse.wasDefinitelyNotSent === true;
|
|
4119
|
+
const retrySuppressedReason = isRetryAvailable() && RETRYABLE_STATUS_CODES.has(adapterResponse.status) && !cancelSignal.aborted ? adapterResponse.isRetryable === false ? "adapter_veto" : adapterResponse.isStreamError ? "stream_error" : !isMethodReplayable ? "non_idempotent_method" : void 0 : void 0;
|
|
4120
|
+
if (policy && adapterResponse.isRetryable !== false && !adapterResponse.isStreamError && isMethodReplayable && RETRYABLE_STATUS_CODES.has(adapterResponse.status) && !cancelSignal.aborted) {
|
|
3765
4121
|
const { shouldRetry, delayMS } = policy.shouldRetry(
|
|
3766
4122
|
new Error(`HTTP ${adapterResponse.status}`)
|
|
3767
4123
|
);
|
|
@@ -3771,19 +4127,11 @@ var BaseHTTPClient = class {
|
|
|
3771
4127
|
callbacks.setNextRetryAt(nextRetryAt ?? null);
|
|
3772
4128
|
callbacks.setState("waiting_for_retry");
|
|
3773
4129
|
}
|
|
3774
|
-
|
|
3775
|
-
attemptNumber,
|
|
3776
|
-
isRetry,
|
|
4130
|
+
emitAttemptEnd({
|
|
3777
4131
|
willRetry: shouldRetry,
|
|
3778
4132
|
nextRetryDelayMS: shouldRetry ? delayMS : void 0,
|
|
3779
4133
|
nextRetryAt,
|
|
3780
|
-
status: adapterResponse.status
|
|
3781
|
-
requestID,
|
|
3782
|
-
initialURL,
|
|
3783
|
-
...hopContext ? {
|
|
3784
|
-
hopNumber: hopContext.hopNumber,
|
|
3785
|
-
redirect: hopContext.redirect
|
|
3786
|
-
} : {}
|
|
4134
|
+
status: adapterResponse.status
|
|
3787
4135
|
});
|
|
3788
4136
|
if (shouldRetry) {
|
|
3789
4137
|
const retryHTTPResponse = this._buildResponse({
|
|
@@ -3822,22 +4170,18 @@ var BaseHTTPClient = class {
|
|
|
3822
4170
|
}
|
|
3823
4171
|
isRetriesExhausted = true;
|
|
3824
4172
|
} else {
|
|
3825
|
-
|
|
3826
|
-
attemptNumber,
|
|
3827
|
-
isRetry,
|
|
4173
|
+
emitAttemptEnd({
|
|
3828
4174
|
willRetry: false,
|
|
4175
|
+
...retrySuppressedReason ? { retrySuppressedReason } : {},
|
|
3829
4176
|
nextRetryDelayMS: void 0,
|
|
3830
4177
|
nextRetryAt: void 0,
|
|
3831
|
-
status: adapterResponse.status
|
|
3832
|
-
requestID,
|
|
3833
|
-
initialURL,
|
|
3834
|
-
...hopContext ? {
|
|
3835
|
-
hopNumber: hopContext.hopNumber,
|
|
3836
|
-
redirect: hopContext.redirect
|
|
3837
|
-
} : {}
|
|
4178
|
+
status: adapterResponse.status
|
|
3838
4179
|
});
|
|
3839
4180
|
}
|
|
3840
|
-
const
|
|
4181
|
+
const responseCauseValue = adapterResponse.errorCause;
|
|
4182
|
+
const responseCause = asErrorValue(
|
|
4183
|
+
responseCauseValue
|
|
4184
|
+
) ? responseCauseValue : void 0;
|
|
3841
4185
|
const streamErrorCode = adapterResponse.isStreamError ? adapterResponse.streamErrorCode ?? "stream_write_error" : void 0;
|
|
3842
4186
|
return {
|
|
3843
4187
|
adapterResponse,
|
|
@@ -3851,20 +4195,19 @@ var BaseHTTPClient = class {
|
|
|
3851
4195
|
};
|
|
3852
4196
|
} catch (error) {
|
|
3853
4197
|
clearTimeout(timeoutID);
|
|
4198
|
+
const abortedResponse = isResponseStreamAbortError(error) ? getResponseStreamAbortInfo(error) : void 0;
|
|
4199
|
+
if (cookieJar && abortedResponse) {
|
|
4200
|
+
cookieJar.processResponseHeaders(
|
|
4201
|
+
abortedResponse.headers,
|
|
4202
|
+
sentRequest.requestURL
|
|
4203
|
+
);
|
|
4204
|
+
}
|
|
3854
4205
|
if (cancelSignal.aborted && !isAbortError2(error)) {
|
|
3855
|
-
|
|
3856
|
-
attemptNumber,
|
|
3857
|
-
isRetry,
|
|
4206
|
+
emitAttemptEnd({
|
|
3858
4207
|
willRetry: false,
|
|
3859
4208
|
nextRetryDelayMS: void 0,
|
|
3860
4209
|
nextRetryAt: void 0,
|
|
3861
|
-
status: 0
|
|
3862
|
-
requestID,
|
|
3863
|
-
initialURL,
|
|
3864
|
-
...hopContext ? {
|
|
3865
|
-
hopNumber: hopContext.hopNumber,
|
|
3866
|
-
redirect: hopContext.redirect
|
|
3867
|
-
} : {}
|
|
4210
|
+
status: 0
|
|
3868
4211
|
});
|
|
3869
4212
|
const signalReason = getSignalCancelReason(cancelSignal);
|
|
3870
4213
|
return {
|
|
@@ -3877,21 +4220,26 @@ var BaseHTTPClient = class {
|
|
|
3877
4220
|
...signalReason !== void 0 ? { cancelReason: signalReason } : {}
|
|
3878
4221
|
};
|
|
3879
4222
|
}
|
|
3880
|
-
if (
|
|
4223
|
+
if (isResponseStreamAbortError(error)) {
|
|
4224
|
+
const streamCause = normalizeError2(error);
|
|
4225
|
+
const streamSuppressionReason = (status) => isRetryAvailable() && RETRYABLE_STATUS_CODES.has(status) && !cancelSignal.aborted ? "stream_error" : void 0;
|
|
4226
|
+
const redirectFieldsFor = (status, headers) => {
|
|
4227
|
+
const detectedRedirectURL = resolveDetectedRedirectURL(
|
|
4228
|
+
sentRequest.requestURL,
|
|
4229
|
+
status,
|
|
4230
|
+
headers
|
|
4231
|
+
);
|
|
4232
|
+
return {
|
|
4233
|
+
wasRedirectDetected: detectedRedirectURL !== void 0 || REDIRECT_STATUS_CODES.has(status),
|
|
4234
|
+
...detectedRedirectURL ? { detectedRedirectURL } : {}
|
|
4235
|
+
};
|
|
4236
|
+
};
|
|
3881
4237
|
if (cancelSignal.aborted) {
|
|
3882
|
-
|
|
3883
|
-
attemptNumber,
|
|
3884
|
-
isRetry,
|
|
4238
|
+
emitAttemptEnd({
|
|
3885
4239
|
willRetry: false,
|
|
3886
4240
|
nextRetryDelayMS: void 0,
|
|
3887
4241
|
nextRetryAt: void 0,
|
|
3888
|
-
status: 0
|
|
3889
|
-
requestID,
|
|
3890
|
-
initialURL,
|
|
3891
|
-
...hopContext ? {
|
|
3892
|
-
hopNumber: hopContext.hopNumber,
|
|
3893
|
-
redirect: hopContext.redirect
|
|
3894
|
-
} : {}
|
|
4242
|
+
status: 0
|
|
3895
4243
|
});
|
|
3896
4244
|
const signalReason = getSignalCancelReason(cancelSignal);
|
|
3897
4245
|
return {
|
|
@@ -3908,30 +4256,29 @@ var BaseHTTPClient = class {
|
|
|
3908
4256
|
...signalReason !== void 0 ? { cancelReason: signalReason } : {}
|
|
3909
4257
|
};
|
|
3910
4258
|
}
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
4259
|
+
if (isTimedOut && abortedResponse) {
|
|
4260
|
+
const suppressedReason = streamSuppressionReason(
|
|
4261
|
+
abortedResponse.status
|
|
4262
|
+
);
|
|
4263
|
+
emitAttemptEnd({
|
|
3916
4264
|
willRetry: false,
|
|
4265
|
+
...suppressedReason ? { retrySuppressedReason: suppressedReason } : {},
|
|
3917
4266
|
nextRetryDelayMS: void 0,
|
|
3918
4267
|
nextRetryAt: void 0,
|
|
3919
|
-
status:
|
|
3920
|
-
requestID,
|
|
3921
|
-
initialURL,
|
|
3922
|
-
...hopContext ? {
|
|
3923
|
-
hopNumber: hopContext.hopNumber,
|
|
3924
|
-
redirect: hopContext.redirect
|
|
3925
|
-
} : {}
|
|
4268
|
+
status: abortedResponse.status
|
|
3926
4269
|
});
|
|
3927
4270
|
return {
|
|
3928
4271
|
adapterResponse: {
|
|
3929
|
-
status:
|
|
3930
|
-
|
|
4272
|
+
status: abortedResponse.status,
|
|
4273
|
+
...redirectFieldsFor(
|
|
4274
|
+
abortedResponse.status,
|
|
4275
|
+
abortedResponse.headers
|
|
4276
|
+
),
|
|
4277
|
+
headers: abortedResponse.headers,
|
|
3931
4278
|
body: null,
|
|
3932
4279
|
isStreamError: true,
|
|
3933
4280
|
streamErrorCode: "stream_response_error",
|
|
3934
|
-
errorCause:
|
|
4281
|
+
errorCause: streamCause,
|
|
3935
4282
|
effectiveRequestHeaders: getEffectiveRequestHeadersFromError(error)
|
|
3936
4283
|
},
|
|
3937
4284
|
sentRequest: sentRequestForObservedAdapterError(
|
|
@@ -3944,31 +4291,30 @@ var BaseHTTPClient = class {
|
|
|
3944
4291
|
wasTimeout: true,
|
|
3945
4292
|
isRetriesExhausted: false,
|
|
3946
4293
|
errorCode: "stream_response_error",
|
|
3947
|
-
adapterCause:
|
|
4294
|
+
adapterCause: streamCause
|
|
3948
4295
|
};
|
|
3949
4296
|
}
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
4297
|
+
const fallbackSuppressedReason = streamSuppressionReason(
|
|
4298
|
+
abortedResponse?.status ?? 0
|
|
4299
|
+
);
|
|
4300
|
+
emitAttemptEnd({
|
|
3953
4301
|
willRetry: false,
|
|
4302
|
+
...fallbackSuppressedReason ? { retrySuppressedReason: fallbackSuppressedReason } : {},
|
|
3954
4303
|
nextRetryDelayMS: void 0,
|
|
3955
4304
|
nextRetryAt: void 0,
|
|
3956
|
-
status:
|
|
3957
|
-
requestID,
|
|
3958
|
-
initialURL,
|
|
3959
|
-
...hopContext ? {
|
|
3960
|
-
hopNumber: hopContext.hopNumber,
|
|
3961
|
-
redirect: hopContext.redirect
|
|
3962
|
-
} : {}
|
|
4305
|
+
status: abortedResponse?.status ?? 0
|
|
3963
4306
|
});
|
|
4307
|
+
const fallbackStatus = abortedResponse?.status ?? 0;
|
|
4308
|
+
const fallbackHeaders = abortedResponse?.headers ?? {};
|
|
3964
4309
|
return {
|
|
3965
4310
|
adapterResponse: {
|
|
3966
|
-
status:
|
|
3967
|
-
|
|
4311
|
+
status: fallbackStatus,
|
|
4312
|
+
...redirectFieldsFor(fallbackStatus, fallbackHeaders),
|
|
4313
|
+
headers: fallbackHeaders,
|
|
3968
4314
|
body: null,
|
|
3969
4315
|
isStreamError: true,
|
|
3970
4316
|
streamErrorCode: "stream_response_error",
|
|
3971
|
-
errorCause:
|
|
4317
|
+
errorCause: streamCause,
|
|
3972
4318
|
effectiveRequestHeaders: getEffectiveRequestHeadersFromError(error)
|
|
3973
4319
|
},
|
|
3974
4320
|
sentRequest: sentRequestForObservedAdapterError(
|
|
@@ -3981,24 +4327,16 @@ var BaseHTTPClient = class {
|
|
|
3981
4327
|
wasTimeout: isTimedOut,
|
|
3982
4328
|
isRetriesExhausted: false,
|
|
3983
4329
|
errorCode: "stream_response_error",
|
|
3984
|
-
adapterCause:
|
|
4330
|
+
adapterCause: streamCause
|
|
3985
4331
|
};
|
|
3986
4332
|
}
|
|
3987
4333
|
if (isAbortError2(error)) {
|
|
3988
4334
|
if (cancelSignal.aborted) {
|
|
3989
|
-
|
|
3990
|
-
attemptNumber,
|
|
3991
|
-
isRetry,
|
|
4335
|
+
emitAttemptEnd({
|
|
3992
4336
|
willRetry: false,
|
|
3993
4337
|
nextRetryDelayMS: void 0,
|
|
3994
4338
|
nextRetryAt: void 0,
|
|
3995
|
-
status: 0
|
|
3996
|
-
requestID,
|
|
3997
|
-
initialURL,
|
|
3998
|
-
...hopContext ? {
|
|
3999
|
-
hopNumber: hopContext.hopNumber,
|
|
4000
|
-
redirect: hopContext.redirect
|
|
4001
|
-
} : {}
|
|
4339
|
+
status: 0
|
|
4002
4340
|
});
|
|
4003
4341
|
const signalReason = getSignalCancelReason(cancelSignal);
|
|
4004
4342
|
return {
|
|
@@ -4015,21 +4353,16 @@ var BaseHTTPClient = class {
|
|
|
4015
4353
|
if (isXHRBrowserTimeout(error)) {
|
|
4016
4354
|
isTimedOut = true;
|
|
4017
4355
|
} else {
|
|
4018
|
-
const factoryCancelValue =
|
|
4356
|
+
const factoryCancelValue = readObjectMember2(
|
|
4357
|
+
error,
|
|
4358
|
+
STREAM_FACTORY_CANCEL_KEY
|
|
4359
|
+
);
|
|
4019
4360
|
const factoryCancelReason = typeof factoryCancelValue === "string" ? factoryCancelValue : void 0;
|
|
4020
|
-
|
|
4021
|
-
attemptNumber,
|
|
4022
|
-
isRetry,
|
|
4361
|
+
emitAttemptEnd({
|
|
4023
4362
|
willRetry: false,
|
|
4024
4363
|
nextRetryDelayMS: void 0,
|
|
4025
4364
|
nextRetryAt: void 0,
|
|
4026
|
-
status: 0
|
|
4027
|
-
requestID,
|
|
4028
|
-
initialURL,
|
|
4029
|
-
...hopContext ? {
|
|
4030
|
-
hopNumber: hopContext.hopNumber,
|
|
4031
|
-
redirect: hopContext.redirect
|
|
4032
|
-
} : {}
|
|
4365
|
+
status: 0
|
|
4033
4366
|
});
|
|
4034
4367
|
return {
|
|
4035
4368
|
adapterResponse: null,
|
|
@@ -4046,19 +4379,11 @@ var BaseHTTPClient = class {
|
|
|
4046
4379
|
const didTimeoutThisAttempt = isAbortError2(error) && isTimedOut;
|
|
4047
4380
|
const isNonRetryableClientCallbackFailure = isNonRetryableClientCallbackError(error);
|
|
4048
4381
|
if (isNonRetryableClientCallbackFailure) {
|
|
4049
|
-
|
|
4050
|
-
attemptNumber,
|
|
4051
|
-
isRetry,
|
|
4382
|
+
emitAttemptEnd({
|
|
4052
4383
|
willRetry: false,
|
|
4053
4384
|
nextRetryDelayMS: void 0,
|
|
4054
4385
|
nextRetryAt: void 0,
|
|
4055
|
-
status: 0
|
|
4056
|
-
requestID,
|
|
4057
|
-
initialURL,
|
|
4058
|
-
...hopContext ? {
|
|
4059
|
-
hopNumber: hopContext.hopNumber,
|
|
4060
|
-
redirect: hopContext.redirect
|
|
4061
|
-
} : {}
|
|
4386
|
+
status: 0
|
|
4062
4387
|
});
|
|
4063
4388
|
const isStreamFactoryError = isStreamFactoryClientCallbackError(error);
|
|
4064
4389
|
return {
|
|
@@ -4073,12 +4398,12 @@ var BaseHTTPClient = class {
|
|
|
4073
4398
|
wasTimeout: didTimeoutThisAttempt,
|
|
4074
4399
|
isRetriesExhausted: false,
|
|
4075
4400
|
errorCode: isStreamFactoryError ? "stream_setup_error" : "interceptor_error",
|
|
4076
|
-
adapterCause:
|
|
4401
|
+
adapterCause: normalizeError2(error)
|
|
4077
4402
|
};
|
|
4078
4403
|
}
|
|
4079
|
-
if (policy && !cancelSignal.aborted) {
|
|
4404
|
+
if (policy && !cancelSignal.aborted && (allowNonIdempotentRetry || !NON_IDEMPOTENT_METHODS.has(sentRequest.method))) {
|
|
4080
4405
|
const { shouldRetry, delayMS } = policy.shouldRetry(
|
|
4081
|
-
|
|
4406
|
+
normalizeError2(error)
|
|
4082
4407
|
);
|
|
4083
4408
|
const nextRetryAt = shouldRetry ? Date.now() + delayMS : void 0;
|
|
4084
4409
|
if (shouldRetry) {
|
|
@@ -4086,19 +4411,11 @@ var BaseHTTPClient = class {
|
|
|
4086
4411
|
callbacks.setNextRetryAt(nextRetryAt ?? null);
|
|
4087
4412
|
callbacks.setState("waiting_for_retry");
|
|
4088
4413
|
}
|
|
4089
|
-
|
|
4090
|
-
attemptNumber,
|
|
4091
|
-
isRetry,
|
|
4414
|
+
emitAttemptEnd({
|
|
4092
4415
|
willRetry: shouldRetry,
|
|
4093
4416
|
nextRetryDelayMS: shouldRetry ? delayMS : void 0,
|
|
4094
4417
|
nextRetryAt,
|
|
4095
|
-
status: 0
|
|
4096
|
-
requestID,
|
|
4097
|
-
initialURL,
|
|
4098
|
-
...hopContext ? {
|
|
4099
|
-
hopNumber: hopContext.hopNumber,
|
|
4100
|
-
redirect: hopContext.redirect
|
|
4101
|
-
} : {}
|
|
4418
|
+
status: 0
|
|
4102
4419
|
});
|
|
4103
4420
|
if (shouldRetry) {
|
|
4104
4421
|
const failedAttemptResponse = this._buildResponse({
|
|
@@ -4117,7 +4434,7 @@ var BaseHTTPClient = class {
|
|
|
4117
4434
|
requestID,
|
|
4118
4435
|
false,
|
|
4119
4436
|
"adapter_error",
|
|
4120
|
-
|
|
4437
|
+
normalizeError2(error)
|
|
4121
4438
|
);
|
|
4122
4439
|
await this._runErrorObservers(
|
|
4123
4440
|
retryError,
|
|
@@ -4145,19 +4462,13 @@ var BaseHTTPClient = class {
|
|
|
4145
4462
|
}
|
|
4146
4463
|
isRetriesExhausted = true;
|
|
4147
4464
|
} else {
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
isRetry,
|
|
4465
|
+
const isSuppressedByMethod = isRetryAvailable() && !cancelSignal.aborted && !allowNonIdempotentRetry && NON_IDEMPOTENT_METHODS.has(sentRequest.method);
|
|
4466
|
+
emitAttemptEnd({
|
|
4151
4467
|
willRetry: false,
|
|
4468
|
+
...isSuppressedByMethod ? { retrySuppressedReason: "non_idempotent_method" } : {},
|
|
4152
4469
|
nextRetryDelayMS: void 0,
|
|
4153
4470
|
nextRetryAt: void 0,
|
|
4154
|
-
status: 0
|
|
4155
|
-
requestID,
|
|
4156
|
-
initialURL,
|
|
4157
|
-
...hopContext ? {
|
|
4158
|
-
hopNumber: hopContext.hopNumber,
|
|
4159
|
-
redirect: hopContext.redirect
|
|
4160
|
-
} : {}
|
|
4471
|
+
status: 0
|
|
4161
4472
|
});
|
|
4162
4473
|
}
|
|
4163
4474
|
return {
|
|
@@ -4168,7 +4479,7 @@ var BaseHTTPClient = class {
|
|
|
4168
4479
|
wasTimeout: didTimeoutThisAttempt,
|
|
4169
4480
|
isRetriesExhausted,
|
|
4170
4481
|
errorCode: "adapter_error",
|
|
4171
|
-
adapterCause:
|
|
4482
|
+
adapterCause: normalizeError2(error)
|
|
4172
4483
|
};
|
|
4173
4484
|
}
|
|
4174
4485
|
}
|
|
@@ -4538,7 +4849,7 @@ var BaseHTTPClient = class {
|
|
|
4538
4849
|
return AbortSignal.any([a, b]);
|
|
4539
4850
|
}
|
|
4540
4851
|
const controller = new AbortController();
|
|
4541
|
-
const abort = (signal) => controller.abort(signal
|
|
4852
|
+
const abort = (signal) => controller.abort(readObjectMember2(signal, "reason"));
|
|
4542
4853
|
if (a.aborted) {
|
|
4543
4854
|
abort(a);
|
|
4544
4855
|
} else if (b.aborted) {
|
|
@@ -4622,7 +4933,24 @@ function cloneBodyValue(body) {
|
|
|
4622
4933
|
return body;
|
|
4623
4934
|
}
|
|
4624
4935
|
function isAbortError2(err) {
|
|
4625
|
-
return err
|
|
4936
|
+
return asErrorValue(err) && readObjectMember2(err, "name") === "AbortError";
|
|
4937
|
+
}
|
|
4938
|
+
function asErrorValue(value) {
|
|
4939
|
+
try {
|
|
4940
|
+
return value instanceof Error;
|
|
4941
|
+
} catch {
|
|
4942
|
+
return false;
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
function normalizeError2(value) {
|
|
4946
|
+
if (asErrorValue(value)) {
|
|
4947
|
+
return value;
|
|
4948
|
+
}
|
|
4949
|
+
try {
|
|
4950
|
+
return new Error(String(value));
|
|
4951
|
+
} catch {
|
|
4952
|
+
return new Error("Unknown error");
|
|
4953
|
+
}
|
|
4626
4954
|
}
|
|
4627
4955
|
function sentRequestForNonRetryableAdapterCallbackError(sentRequest, error, observedAfterAdapterResolve) {
|
|
4628
4956
|
return sentRequestForObservedAdapterError(
|
|
@@ -4632,12 +4960,10 @@ function sentRequestForNonRetryableAdapterCallbackError(sentRequest, error, obse
|
|
|
4632
4960
|
);
|
|
4633
4961
|
}
|
|
4634
4962
|
function isNonRetryableClientCallbackError(err) {
|
|
4635
|
-
return
|
|
4636
|
-
err && typeof err === "object" && NON_RETRYABLE_HTTP_CLIENT_CALLBACK_ERROR_FLAG in err && err[NON_RETRYABLE_HTTP_CLIENT_CALLBACK_ERROR_FLAG] === true
|
|
4637
|
-
);
|
|
4963
|
+
return readObjectMember2(err, NON_RETRYABLE_HTTP_CLIENT_CALLBACK_ERROR_FLAG) === true;
|
|
4638
4964
|
}
|
|
4639
4965
|
function isStreamFactoryClientCallbackError(err) {
|
|
4640
|
-
return err
|
|
4966
|
+
return readObjectMember2(err, STREAM_FACTORY_ERROR_FLAG) === true;
|
|
4641
4967
|
}
|
|
4642
4968
|
function sentRequestForObservedAdapterError(sentRequest, error, observedAfterAdapterResolve) {
|
|
4643
4969
|
const eff = getEffectiveRequestHeadersFromError(error);
|
|
@@ -4650,24 +4976,58 @@ function sentRequestForObservedAdapterError(sentRequest, error, observedAfterAda
|
|
|
4650
4976
|
};
|
|
4651
4977
|
}
|
|
4652
4978
|
function getEffectiveRequestHeadersFromError(error) {
|
|
4653
|
-
|
|
4654
|
-
|
|
4979
|
+
return snapshotHeaderRecord(
|
|
4980
|
+
readObjectMember2(error, "effectiveRequestHeaders")
|
|
4981
|
+
);
|
|
4982
|
+
}
|
|
4983
|
+
function readObjectMember2(source, key) {
|
|
4984
|
+
if (typeof source !== "object" && typeof source !== "function" || source === null) {
|
|
4985
|
+
return void 0;
|
|
4986
|
+
}
|
|
4987
|
+
try {
|
|
4988
|
+
return source[key];
|
|
4989
|
+
} catch {
|
|
4990
|
+
return void 0;
|
|
4655
4991
|
}
|
|
4656
|
-
|
|
4992
|
+
}
|
|
4993
|
+
function snapshotHeaderRecord(value) {
|
|
4994
|
+
if (typeof value !== "object" || value === null) {
|
|
4995
|
+
return void 0;
|
|
4996
|
+
}
|
|
4997
|
+
try {
|
|
4998
|
+
const snapshot = {};
|
|
4999
|
+
for (const [name, headerValue] of Object.entries(value)) {
|
|
5000
|
+
if (typeof headerValue === "string") {
|
|
5001
|
+
snapshot[name] = headerValue;
|
|
5002
|
+
} else if (Array.isArray(headerValue) && headerValue.every((item) => typeof item === "string")) {
|
|
5003
|
+
snapshot[name] = [...headerValue];
|
|
5004
|
+
} else {
|
|
5005
|
+
return void 0;
|
|
5006
|
+
}
|
|
5007
|
+
}
|
|
5008
|
+
return snapshot;
|
|
5009
|
+
} catch {
|
|
5010
|
+
return void 0;
|
|
5011
|
+
}
|
|
5012
|
+
}
|
|
5013
|
+
function hasAdapterMarker(err, flag) {
|
|
5014
|
+
return readObjectMember2(err, flag) === true;
|
|
4657
5015
|
}
|
|
4658
5016
|
function isResponseStreamAbortError(err) {
|
|
4659
|
-
return err
|
|
5017
|
+
return hasAdapterMarker(err, RESPONSE_STREAM_ABORT_FLAG);
|
|
4660
5018
|
}
|
|
4661
5019
|
function isXHRBrowserTimeout(err) {
|
|
4662
|
-
return err
|
|
5020
|
+
return hasAdapterMarker(err, XHR_BROWSER_TIMEOUT_FLAG);
|
|
4663
5021
|
}
|
|
4664
5022
|
function getResponseStreamAbortInfo(err) {
|
|
4665
|
-
|
|
5023
|
+
const status = readObjectMember2(err, "streamAbortStatus");
|
|
5024
|
+
if (typeof status !== "number") {
|
|
4666
5025
|
return void 0;
|
|
4667
5026
|
}
|
|
4668
|
-
const
|
|
4669
|
-
|
|
4670
|
-
|
|
5027
|
+
const headers = snapshotHeaderRecord(
|
|
5028
|
+
readObjectMember2(err, "streamAbortHeaders")
|
|
5029
|
+
);
|
|
5030
|
+
if (headers === void 0) {
|
|
4671
5031
|
return void 0;
|
|
4672
5032
|
}
|
|
4673
5033
|
return {
|
|
@@ -4676,7 +5036,8 @@ function getResponseStreamAbortInfo(err) {
|
|
|
4676
5036
|
};
|
|
4677
5037
|
}
|
|
4678
5038
|
function getSignalCancelReason(signal) {
|
|
4679
|
-
|
|
5039
|
+
const reason = readObjectMember2(signal, "reason");
|
|
5040
|
+
return typeof reason === "string" ? reason : void 0;
|
|
4680
5041
|
}
|
|
4681
5042
|
|
|
4682
5043
|
// src/lib/http-client/cookie-jar.ts
|