@plyaz/api 1.6.7 → 1.6.8
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/api/client/helpers/interceptors.d.ts.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/upload/browser.d.ts +9 -0
- package/dist/api/upload/browser.d.ts.map +1 -0
- package/dist/api/upload/config.d.ts +9 -0
- package/dist/api/upload/config.d.ts.map +1 -0
- package/dist/api/upload/constants.d.ts +23 -0
- package/dist/api/upload/constants.d.ts.map +1 -0
- package/dist/api/upload/index.d.ts +24 -0
- package/dist/api/upload/index.d.ts.map +1 -0
- package/dist/api/upload/node.d.ts +9 -0
- package/dist/api/upload/node.d.ts.map +1 -0
- package/dist/api/upload/retry.d.ts +34 -0
- package/dist/api/upload/retry.d.ts.map +1 -0
- package/dist/api/upload/uploadWithProgress.d.ts +41 -0
- package/dist/api/upload/uploadWithProgress.d.ts.map +1 -0
- package/dist/api/upload/utils.d.ts +33 -0
- package/dist/api/upload/utils.d.ts.map +1 -0
- package/dist/entry-frontend.cjs +1 -1
- package/dist/entry-frontend.cjs.map +1 -1
- package/dist/entry-frontend.mjs +2 -2
- package/dist/entry-frontend.mjs.map +1 -1
- package/dist/index.cjs +561 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +562 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -21623,7 +21623,7 @@ function createOnErrorHandler(handlers, clearTemporaryOverrides2, clearOnComplet
|
|
|
21623
21623
|
const apiError = new ApiPackageError(
|
|
21624
21624
|
"request.failed",
|
|
21625
21625
|
api.PACKAGE_STATUS_CODES.REQUEST_FAILED,
|
|
21626
|
-
error.status ?
|
|
21626
|
+
error.status ? errors$1.getErrorCodeByStatus(error.status) ?? api.API_ERROR_CODES.CLIENT_ERROR : api.API_ERROR_CODES.NETWORK_ERROR,
|
|
21627
21627
|
{
|
|
21628
21628
|
cause: error,
|
|
21629
21629
|
context: {
|
|
@@ -22249,6 +22249,546 @@ function applyQualityBasedConfiguration(resolvedConfig, quality, networkAware, n
|
|
|
22249
22249
|
}
|
|
22250
22250
|
}
|
|
22251
22251
|
__name(applyQualityBasedConfiguration, "applyQualityBasedConfiguration");
|
|
22252
|
+
var PROGRESS_CHUNK_SIZE_MULTIPLIER = 64;
|
|
22253
|
+
var UPLOAD_CONSTANTS = {
|
|
22254
|
+
DEFAULT_CHUNK_SIZE: PROGRESS_CHUNK_SIZE_MULTIPLIER * config.NUMBER_SYSTEM.BYTES_PER_KB,
|
|
22255
|
+
DEFAULT_THROTTLE_MS: config.TIME_CONSTANTS.HUNDRED_MS,
|
|
22256
|
+
DEFAULT_CONTENT_TYPE: "application/octet-stream",
|
|
22257
|
+
DEFAULT_TIMEOUT: config.TIME_CONSTANTS.TWO_MINUTES,
|
|
22258
|
+
DEFAULT_RETRY_DELAY: config.RETRY_DELAYS.SHORT,
|
|
22259
|
+
DEFAULT_RETRY_BACKOFF: config.RETRY_BACKOFF.MEDIUM,
|
|
22260
|
+
DEFAULT_RETRY_MAX_DELAY: config.RETRY_DELAYS.MAX,
|
|
22261
|
+
PROGRESS_PERCENTAGE_THRESHOLD: config.NUMERIC_CONSTANTS.FIVE,
|
|
22262
|
+
FULL_PERCENTAGE: config.MATH_CONSTANTS.PERCENTAGE_MAX,
|
|
22263
|
+
HTTPS_DEFAULT_PORT: config.TIME_CONSTANTS.HTTPS_PORT,
|
|
22264
|
+
HTTP_DEFAULT_PORT: config.TIME_CONSTANTS.HTTP_PORT,
|
|
22265
|
+
/** Max server error status code (exclusive boundary for 5xx range) */
|
|
22266
|
+
MAX_SERVER_ERROR_STATUS: 600
|
|
22267
|
+
};
|
|
22268
|
+
var RETRYABLE_ERROR_CODES = [
|
|
22269
|
+
"ETIMEDOUT",
|
|
22270
|
+
"ECONNRESET",
|
|
22271
|
+
"ECONNREFUSED",
|
|
22272
|
+
"ENOTFOUND",
|
|
22273
|
+
"ENETUNREACH",
|
|
22274
|
+
"EAI_AGAIN"
|
|
22275
|
+
];
|
|
22276
|
+
var RETRYABLE_MESSAGE_PATTERNS = [
|
|
22277
|
+
"timeout",
|
|
22278
|
+
"timed out",
|
|
22279
|
+
"network",
|
|
22280
|
+
"econnreset",
|
|
22281
|
+
"econnrefused",
|
|
22282
|
+
"etimedout",
|
|
22283
|
+
"service unavailable",
|
|
22284
|
+
"rate limit",
|
|
22285
|
+
"too many requests"
|
|
22286
|
+
];
|
|
22287
|
+
|
|
22288
|
+
// src/api/upload/config.ts
|
|
22289
|
+
function extractGlobalHeaders(globalConfig) {
|
|
22290
|
+
const globalHeaders = {};
|
|
22291
|
+
if (!globalConfig.headers || typeof globalConfig.headers !== "object") {
|
|
22292
|
+
return globalHeaders;
|
|
22293
|
+
}
|
|
22294
|
+
if (!("presets" in globalConfig.headers) && !("static" in globalConfig.headers)) {
|
|
22295
|
+
Object.entries(globalConfig.headers).forEach(([key, value]) => {
|
|
22296
|
+
if (typeof value === "string") {
|
|
22297
|
+
globalHeaders[key] = value;
|
|
22298
|
+
}
|
|
22299
|
+
});
|
|
22300
|
+
return globalHeaders;
|
|
22301
|
+
}
|
|
22302
|
+
if ("static" in globalConfig.headers) {
|
|
22303
|
+
const staticHeaders = globalConfig.headers.static;
|
|
22304
|
+
if (staticHeaders) {
|
|
22305
|
+
Object.entries(staticHeaders).forEach(([key, value]) => {
|
|
22306
|
+
if (typeof value === "string") {
|
|
22307
|
+
globalHeaders[key] = value;
|
|
22308
|
+
}
|
|
22309
|
+
});
|
|
22310
|
+
}
|
|
22311
|
+
}
|
|
22312
|
+
return globalHeaders;
|
|
22313
|
+
}
|
|
22314
|
+
__name(extractGlobalHeaders, "extractGlobalHeaders");
|
|
22315
|
+
function mergeRetryConfig(optionRetry, globalRetry) {
|
|
22316
|
+
if (optionRetry !== void 0) return optionRetry;
|
|
22317
|
+
if (globalRetry !== void 0) return globalRetry;
|
|
22318
|
+
return false;
|
|
22319
|
+
}
|
|
22320
|
+
__name(mergeRetryConfig, "mergeRetryConfig");
|
|
22321
|
+
function buildLocalConfig(options) {
|
|
22322
|
+
return {
|
|
22323
|
+
headers: options.headers ?? {},
|
|
22324
|
+
timeout: options.timeout ?? UPLOAD_CONSTANTS.DEFAULT_TIMEOUT,
|
|
22325
|
+
baseURL: options.baseURL,
|
|
22326
|
+
retry: options.retry ?? false,
|
|
22327
|
+
onError: options.onError,
|
|
22328
|
+
withCredentials: options.withCredentials ?? false
|
|
22329
|
+
};
|
|
22330
|
+
}
|
|
22331
|
+
__name(buildLocalConfig, "buildLocalConfig");
|
|
22332
|
+
function getMergedConfig(options) {
|
|
22333
|
+
if (options.useGlobalConfig === false) {
|
|
22334
|
+
return buildLocalConfig(options);
|
|
22335
|
+
}
|
|
22336
|
+
const globalConfig = getGlobalConfig();
|
|
22337
|
+
const globalHeaders = extractGlobalHeaders(globalConfig);
|
|
22338
|
+
return {
|
|
22339
|
+
headers: { ...globalHeaders, ...options.headers ?? {} },
|
|
22340
|
+
timeout: options.timeout ?? globalConfig.timeout ?? UPLOAD_CONSTANTS.DEFAULT_TIMEOUT,
|
|
22341
|
+
baseURL: options.baseURL ?? globalConfig.baseURL,
|
|
22342
|
+
retry: mergeRetryConfig(options.retry, globalConfig.retry),
|
|
22343
|
+
onError: options.onError,
|
|
22344
|
+
withCredentials: options.withCredentials ?? globalConfig.withCredentials ?? false
|
|
22345
|
+
};
|
|
22346
|
+
}
|
|
22347
|
+
__name(getMergedConfig, "getMergedConfig");
|
|
22348
|
+
function checkRetryableFlag(error) {
|
|
22349
|
+
if (typeof error.isRetryable === "function") return error.isRetryable();
|
|
22350
|
+
if (typeof error.isRetryable === "boolean") return error.isRetryable;
|
|
22351
|
+
if (typeof error.retryable === "boolean") return error.retryable;
|
|
22352
|
+
return void 0;
|
|
22353
|
+
}
|
|
22354
|
+
__name(checkRetryableFlag, "checkRetryableFlag");
|
|
22355
|
+
function isRetryableStatus(status) {
|
|
22356
|
+
if (status === void 0) return false;
|
|
22357
|
+
if (status === config.HTTP_STATUS.TOO_MANY_REQUESTS) return true;
|
|
22358
|
+
return status >= config.HTTP_STATUS.INTERNAL_SERVER_ERROR && status < UPLOAD_CONSTANTS.MAX_SERVER_ERROR_STATUS;
|
|
22359
|
+
}
|
|
22360
|
+
__name(isRetryableStatus, "isRetryableStatus");
|
|
22361
|
+
function hasRetryableErrorCode(error) {
|
|
22362
|
+
return Boolean(
|
|
22363
|
+
error.code && RETRYABLE_ERROR_CODES.includes(error.code)
|
|
22364
|
+
);
|
|
22365
|
+
}
|
|
22366
|
+
__name(hasRetryableErrorCode, "hasRetryableErrorCode");
|
|
22367
|
+
function hasRetryableMessage(error) {
|
|
22368
|
+
const message = error.message?.toLowerCase() ?? "";
|
|
22369
|
+
return RETRYABLE_MESSAGE_PATTERNS.some((pattern) => message.includes(pattern));
|
|
22370
|
+
}
|
|
22371
|
+
__name(hasRetryableMessage, "hasRetryableMessage");
|
|
22372
|
+
function isRetryableError(error, status) {
|
|
22373
|
+
if (!error) return false;
|
|
22374
|
+
const errorWithRetryable = error;
|
|
22375
|
+
const flagResult = checkRetryableFlag(errorWithRetryable);
|
|
22376
|
+
if (flagResult !== void 0) return flagResult;
|
|
22377
|
+
if (hasRetryableErrorCode(errorWithRetryable)) return true;
|
|
22378
|
+
if (hasRetryableMessage(error)) return true;
|
|
22379
|
+
const httpStatus = status ?? errorWithRetryable.statusCode;
|
|
22380
|
+
return isRetryableStatus(httpStatus);
|
|
22381
|
+
}
|
|
22382
|
+
__name(isRetryableError, "isRetryableError");
|
|
22383
|
+
function calculateRetryDelay(attempt, config) {
|
|
22384
|
+
const delay = config.delay ?? UPLOAD_CONSTANTS.DEFAULT_RETRY_DELAY;
|
|
22385
|
+
const backoff = config.backoff ?? UPLOAD_CONSTANTS.DEFAULT_RETRY_BACKOFF;
|
|
22386
|
+
const maxDelay = config.maxDelay ?? UPLOAD_CONSTANTS.DEFAULT_RETRY_MAX_DELAY;
|
|
22387
|
+
const calculatedDelay = delay * Math.pow(backoff, attempt);
|
|
22388
|
+
return Math.min(calculatedDelay, maxDelay);
|
|
22389
|
+
}
|
|
22390
|
+
__name(calculateRetryDelay, "calculateRetryDelay");
|
|
22391
|
+
function notifyRetryError(params) {
|
|
22392
|
+
const { ctx, message, status, statusText, cause } = params;
|
|
22393
|
+
if (!ctx.config.onError) return;
|
|
22394
|
+
ctx.config.onError({
|
|
22395
|
+
message,
|
|
22396
|
+
status,
|
|
22397
|
+
statusText,
|
|
22398
|
+
cause,
|
|
22399
|
+
retryable: true,
|
|
22400
|
+
attempt: ctx.attempt,
|
|
22401
|
+
maxAttempts: ctx.maxAttempts
|
|
22402
|
+
});
|
|
22403
|
+
}
|
|
22404
|
+
__name(notifyRetryError, "notifyRetryError");
|
|
22405
|
+
function notifyFinalError(ctx, error) {
|
|
22406
|
+
if (!ctx.config.onError) return;
|
|
22407
|
+
ctx.config.onError({
|
|
22408
|
+
message: error.message,
|
|
22409
|
+
cause: error,
|
|
22410
|
+
retryable: false,
|
|
22411
|
+
attempt: ctx.attempt,
|
|
22412
|
+
maxAttempts: ctx.maxAttempts
|
|
22413
|
+
});
|
|
22414
|
+
}
|
|
22415
|
+
__name(notifyFinalError, "notifyFinalError");
|
|
22416
|
+
function shouldRetryResult(result, config, attempt, maxAttempts) {
|
|
22417
|
+
if (result.success) return false;
|
|
22418
|
+
if (!config.retry) return false;
|
|
22419
|
+
if (attempt >= maxAttempts - 1) return false;
|
|
22420
|
+
return isRetryableError(new Error(result.statusText ?? "Upload failed"), result.status);
|
|
22421
|
+
}
|
|
22422
|
+
__name(shouldRetryResult, "shouldRetryResult");
|
|
22423
|
+
function shouldRetryError(error, config, attempt, maxAttempts) {
|
|
22424
|
+
if (!config.retry) return false;
|
|
22425
|
+
if (attempt >= maxAttempts - 1) return false;
|
|
22426
|
+
return isRetryableError(error);
|
|
22427
|
+
}
|
|
22428
|
+
__name(shouldRetryError, "shouldRetryError");
|
|
22429
|
+
async function handleRetryDelay(attempt, config) {
|
|
22430
|
+
await sleep(calculateRetryDelay(attempt, config));
|
|
22431
|
+
}
|
|
22432
|
+
__name(handleRetryDelay, "handleRetryDelay");
|
|
22433
|
+
function resolveUrl(url, baseURL) {
|
|
22434
|
+
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
22435
|
+
return url;
|
|
22436
|
+
}
|
|
22437
|
+
if (!baseURL) {
|
|
22438
|
+
return url;
|
|
22439
|
+
}
|
|
22440
|
+
const base = baseURL.replace(/\/$/, "");
|
|
22441
|
+
const path = url.startsWith("/") ? url : `/${url}`;
|
|
22442
|
+
return `${base}${path}`;
|
|
22443
|
+
}
|
|
22444
|
+
__name(resolveUrl, "resolveUrl");
|
|
22445
|
+
function normalizeData(data) {
|
|
22446
|
+
if (Buffer.isBuffer(data)) return data;
|
|
22447
|
+
if (data instanceof Uint8Array) return data;
|
|
22448
|
+
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
22449
|
+
throw new ApiPackageError(
|
|
22450
|
+
"Blob data type is only supported in browser environment",
|
|
22451
|
+
void 0,
|
|
22452
|
+
errors.API_ERROR_CODES.VALIDATION_ERROR
|
|
22453
|
+
);
|
|
22454
|
+
}
|
|
22455
|
+
__name(normalizeData, "normalizeData");
|
|
22456
|
+
function createUploadState(totalSize) {
|
|
22457
|
+
const now2 = Date.now();
|
|
22458
|
+
return {
|
|
22459
|
+
status: "uploading",
|
|
22460
|
+
startTime: now2,
|
|
22461
|
+
bytesUploaded: 0,
|
|
22462
|
+
totalBytes: totalSize,
|
|
22463
|
+
lastProgressTime: now2,
|
|
22464
|
+
lastBytesUploaded: 0
|
|
22465
|
+
};
|
|
22466
|
+
}
|
|
22467
|
+
__name(createUploadState, "createUploadState");
|
|
22468
|
+
function calculateProgress(state) {
|
|
22469
|
+
const now2 = Date.now();
|
|
22470
|
+
const timeDelta = (now2 - state.lastProgressTime) / config.TIME_CONSTANTS.SECOND;
|
|
22471
|
+
const bytesDelta = state.bytesUploaded - state.lastBytesUploaded;
|
|
22472
|
+
const speed = timeDelta > 0 ? bytesDelta / timeDelta : 0;
|
|
22473
|
+
const percentage2 = Math.round(
|
|
22474
|
+
state.bytesUploaded / state.totalBytes * UPLOAD_CONSTANTS.FULL_PERCENTAGE
|
|
22475
|
+
);
|
|
22476
|
+
const remainingBytes = state.totalBytes - state.bytesUploaded;
|
|
22477
|
+
return {
|
|
22478
|
+
loaded: state.bytesUploaded,
|
|
22479
|
+
total: state.totalBytes,
|
|
22480
|
+
percentage: percentage2,
|
|
22481
|
+
speed: speed > 0 ? speed : void 0,
|
|
22482
|
+
estimatedTimeRemaining: speed > 0 ? remainingBytes / speed : void 0
|
|
22483
|
+
};
|
|
22484
|
+
}
|
|
22485
|
+
__name(calculateProgress, "calculateProgress");
|
|
22486
|
+
function emitFinalProgress(onProgress, totalSize, startTime) {
|
|
22487
|
+
if (!onProgress) return;
|
|
22488
|
+
const elapsed = (Date.now() - startTime) / config.TIME_CONSTANTS.SECOND;
|
|
22489
|
+
onProgress({
|
|
22490
|
+
loaded: totalSize,
|
|
22491
|
+
total: totalSize,
|
|
22492
|
+
percentage: UPLOAD_CONSTANTS.FULL_PERCENTAGE,
|
|
22493
|
+
speed: elapsed > 0 ? totalSize / elapsed : void 0,
|
|
22494
|
+
estimatedTimeRemaining: 0
|
|
22495
|
+
});
|
|
22496
|
+
}
|
|
22497
|
+
__name(emitFinalProgress, "emitFinalProgress");
|
|
22498
|
+
function shouldEmitProgress(state, totalSize, throttleMs) {
|
|
22499
|
+
const now2 = Date.now();
|
|
22500
|
+
const timeSinceLastProgress = now2 - state.lastProgressTime;
|
|
22501
|
+
const currentPct = Math.round(
|
|
22502
|
+
state.bytesUploaded / totalSize * UPLOAD_CONSTANTS.FULL_PERCENTAGE
|
|
22503
|
+
);
|
|
22504
|
+
const lastPct = Math.round(
|
|
22505
|
+
state.lastBytesUploaded / totalSize * UPLOAD_CONSTANTS.FULL_PERCENTAGE
|
|
22506
|
+
);
|
|
22507
|
+
return timeSinceLastProgress >= throttleMs || currentPct - lastPct >= UPLOAD_CONSTANTS.PROGRESS_PERCENTAGE_THRESHOLD;
|
|
22508
|
+
}
|
|
22509
|
+
__name(shouldEmitProgress, "shouldEmitProgress");
|
|
22510
|
+
function parseNodeHeaders(headers2) {
|
|
22511
|
+
const result = {};
|
|
22512
|
+
for (const [key, value] of Object.entries(headers2)) {
|
|
22513
|
+
if (value !== void 0) {
|
|
22514
|
+
result[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
22515
|
+
}
|
|
22516
|
+
}
|
|
22517
|
+
return result;
|
|
22518
|
+
}
|
|
22519
|
+
__name(parseNodeHeaders, "parseNodeHeaders");
|
|
22520
|
+
|
|
22521
|
+
// src/api/upload/node.ts
|
|
22522
|
+
var createTimeoutError = /* @__PURE__ */ __name((url) => new ApiPackageError("Upload timed out", void 0, errors.API_ERROR_CODES.REQUEST_TIMEOUT, {
|
|
22523
|
+
context: { url }
|
|
22524
|
+
}), "createTimeoutError");
|
|
22525
|
+
var createAbortError = /* @__PURE__ */ __name((url) => new ApiPackageError("Upload aborted", void 0, errors.API_ERROR_CODES.REQUEST_ABORTED, {
|
|
22526
|
+
context: { url }
|
|
22527
|
+
}), "createAbortError");
|
|
22528
|
+
var normalizeError = /* @__PURE__ */ __name((error) => error instanceof Error ? error : new ApiPackageError(String(error), void 0, errors.API_ERROR_CODES.UNKNOWN_ERROR), "normalizeError");
|
|
22529
|
+
async function uploadOnce(options, config$1, resolvedUrl) {
|
|
22530
|
+
const {
|
|
22531
|
+
data,
|
|
22532
|
+
method = "PUT",
|
|
22533
|
+
contentType = UPLOAD_CONSTANTS.DEFAULT_CONTENT_TYPE,
|
|
22534
|
+
onProgress,
|
|
22535
|
+
abortSignal
|
|
22536
|
+
} = options;
|
|
22537
|
+
const chunkSize = options.chunkSize ?? UPLOAD_CONSTANTS.DEFAULT_CHUNK_SIZE;
|
|
22538
|
+
const throttleMs = options.throttleMs ?? UPLOAD_CONSTANTS.DEFAULT_THROTTLE_MS;
|
|
22539
|
+
const { headers: mergedHeaders, timeout } = config$1;
|
|
22540
|
+
const buffer = normalizeData(data);
|
|
22541
|
+
const totalSize = buffer.length;
|
|
22542
|
+
const parsedUrl = new URL(resolvedUrl);
|
|
22543
|
+
const isHttps = parsedUrl.protocol === "https:";
|
|
22544
|
+
const httpModule = await (isHttps ? import('https') : import('http'));
|
|
22545
|
+
const state = createUploadState(totalSize);
|
|
22546
|
+
return new Promise((resolve, reject) => {
|
|
22547
|
+
let timeoutId;
|
|
22548
|
+
if (timeout > 0) timeoutId = setTimeout(() => reject(createTimeoutError(resolvedUrl)), timeout);
|
|
22549
|
+
const clearUploadTimeout = /* @__PURE__ */ __name(() => {
|
|
22550
|
+
if (timeoutId) {
|
|
22551
|
+
clearTimeout(timeoutId);
|
|
22552
|
+
timeoutId = void 0;
|
|
22553
|
+
}
|
|
22554
|
+
}, "clearUploadTimeout");
|
|
22555
|
+
onProgress?.({ loaded: 0, total: totalSize, percentage: 0 });
|
|
22556
|
+
const requestOptions = {
|
|
22557
|
+
hostname: parsedUrl.hostname,
|
|
22558
|
+
port: parsedUrl.port || (isHttps ? UPLOAD_CONSTANTS.HTTPS_DEFAULT_PORT : UPLOAD_CONSTANTS.HTTP_DEFAULT_PORT),
|
|
22559
|
+
path: parsedUrl.pathname + parsedUrl.search,
|
|
22560
|
+
method,
|
|
22561
|
+
headers: {
|
|
22562
|
+
"Content-Type": contentType,
|
|
22563
|
+
"Content-Length": totalSize.toString(),
|
|
22564
|
+
...mergedHeaders
|
|
22565
|
+
}
|
|
22566
|
+
};
|
|
22567
|
+
const req = httpModule.request(requestOptions, (res) => {
|
|
22568
|
+
let responseData = "";
|
|
22569
|
+
res.on("data", (chunk) => {
|
|
22570
|
+
responseData += chunk;
|
|
22571
|
+
});
|
|
22572
|
+
res.on("end", () => {
|
|
22573
|
+
clearUploadTimeout();
|
|
22574
|
+
const success = res.statusCode !== void 0 && res.statusCode >= config.HTTP_STATUS.OK && res.statusCode < config.HTTP_STATUS.MULTIPLE_CHOICES;
|
|
22575
|
+
if (success) emitFinalProgress(onProgress, totalSize, state.startTime);
|
|
22576
|
+
resolve({
|
|
22577
|
+
status: res.statusCode ?? 0,
|
|
22578
|
+
statusText: res.statusMessage ?? "",
|
|
22579
|
+
data: responseData || void 0,
|
|
22580
|
+
headers: parseNodeHeaders(res.headers),
|
|
22581
|
+
success
|
|
22582
|
+
});
|
|
22583
|
+
});
|
|
22584
|
+
});
|
|
22585
|
+
if (abortSignal)
|
|
22586
|
+
abortSignal.addEventListener("abort", () => {
|
|
22587
|
+
clearUploadTimeout();
|
|
22588
|
+
req.destroy();
|
|
22589
|
+
state.status = "aborted";
|
|
22590
|
+
reject(createAbortError(resolvedUrl));
|
|
22591
|
+
});
|
|
22592
|
+
req.on("error", (error) => {
|
|
22593
|
+
clearUploadTimeout();
|
|
22594
|
+
state.status = "failed";
|
|
22595
|
+
state.error = error;
|
|
22596
|
+
reject(error);
|
|
22597
|
+
});
|
|
22598
|
+
let offset = 0;
|
|
22599
|
+
const writeNextChunk = /* @__PURE__ */ __name(() => {
|
|
22600
|
+
while (offset < totalSize) {
|
|
22601
|
+
const end = Math.min(offset + chunkSize, totalSize);
|
|
22602
|
+
const canContinue = req.write(buffer.subarray(offset, end));
|
|
22603
|
+
state.bytesUploaded = end;
|
|
22604
|
+
offset = end;
|
|
22605
|
+
if (onProgress && shouldEmitProgress(state, totalSize, throttleMs)) {
|
|
22606
|
+
onProgress(calculateProgress(state));
|
|
22607
|
+
state.lastProgressTime = Date.now();
|
|
22608
|
+
state.lastBytesUploaded = state.bytesUploaded;
|
|
22609
|
+
}
|
|
22610
|
+
if (!canContinue) {
|
|
22611
|
+
req.once("drain", writeNextChunk);
|
|
22612
|
+
return;
|
|
22613
|
+
}
|
|
22614
|
+
}
|
|
22615
|
+
state.status = "completed";
|
|
22616
|
+
req.end();
|
|
22617
|
+
}, "writeNextChunk");
|
|
22618
|
+
writeNextChunk();
|
|
22619
|
+
});
|
|
22620
|
+
}
|
|
22621
|
+
__name(uploadOnce, "uploadOnce");
|
|
22622
|
+
async function uploadWithProgressNode(options) {
|
|
22623
|
+
const config = getMergedConfig(options);
|
|
22624
|
+
const resolvedUrl = resolveUrl(options.url, config.baseURL);
|
|
22625
|
+
const maxAttempts = config.retry ? (config.retry.attempts ?? 0) + 1 : 1;
|
|
22626
|
+
let lastError;
|
|
22627
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
22628
|
+
const ctx = { config, maxAttempts, attempt };
|
|
22629
|
+
try {
|
|
22630
|
+
const result = await uploadOnce(options, config, resolvedUrl);
|
|
22631
|
+
if (shouldRetryResult(result, config, attempt, maxAttempts)) {
|
|
22632
|
+
notifyRetryError({
|
|
22633
|
+
ctx,
|
|
22634
|
+
message: `Upload failed: ${result.status}`,
|
|
22635
|
+
status: result.status,
|
|
22636
|
+
statusText: result.statusText
|
|
22637
|
+
});
|
|
22638
|
+
await handleRetryDelay(attempt, config.retry);
|
|
22639
|
+
continue;
|
|
22640
|
+
}
|
|
22641
|
+
return { ...result, attempts: attempt };
|
|
22642
|
+
} catch (error) {
|
|
22643
|
+
lastError = normalizeError(error);
|
|
22644
|
+
if (shouldRetryError(lastError, config, attempt, maxAttempts)) {
|
|
22645
|
+
notifyRetryError({ ctx, message: lastError.message, cause: lastError });
|
|
22646
|
+
await handleRetryDelay(attempt, config.retry);
|
|
22647
|
+
continue;
|
|
22648
|
+
}
|
|
22649
|
+
notifyFinalError(ctx, lastError);
|
|
22650
|
+
throw lastError;
|
|
22651
|
+
}
|
|
22652
|
+
}
|
|
22653
|
+
throw lastError ?? new ApiPackageError(
|
|
22654
|
+
"Upload failed after all retry attempts",
|
|
22655
|
+
void 0,
|
|
22656
|
+
errors.API_ERROR_CODES.NETWORK_ERROR
|
|
22657
|
+
);
|
|
22658
|
+
}
|
|
22659
|
+
__name(uploadWithProgressNode, "uploadWithProgressNode");
|
|
22660
|
+
var normalizeError2 = /* @__PURE__ */ __name((error) => error instanceof Error ? error : new ApiPackageError(String(error), void 0, errors.API_ERROR_CODES.UNKNOWN_ERROR), "normalizeError");
|
|
22661
|
+
async function uploadOnce2(options, config$1, resolvedUrl) {
|
|
22662
|
+
const {
|
|
22663
|
+
data,
|
|
22664
|
+
method = "PUT",
|
|
22665
|
+
contentType = UPLOAD_CONSTANTS.DEFAULT_CONTENT_TYPE,
|
|
22666
|
+
onProgress,
|
|
22667
|
+
abortSignal
|
|
22668
|
+
} = options;
|
|
22669
|
+
const { headers: mergedHeaders, timeout, withCredentials } = config$1;
|
|
22670
|
+
return new Promise((resolve, reject) => {
|
|
22671
|
+
const xhr = new XMLHttpRequest();
|
|
22672
|
+
const startTime = Date.now();
|
|
22673
|
+
if (timeout > 0) xhr.timeout = timeout;
|
|
22674
|
+
xhr.addEventListener(
|
|
22675
|
+
"timeout",
|
|
22676
|
+
() => reject(
|
|
22677
|
+
new ApiPackageError("Upload timed out", void 0, errors.API_ERROR_CODES.REQUEST_TIMEOUT, {
|
|
22678
|
+
context: { url: resolvedUrl }
|
|
22679
|
+
})
|
|
22680
|
+
)
|
|
22681
|
+
);
|
|
22682
|
+
xhr.upload.addEventListener("progress", (event) => {
|
|
22683
|
+
if (!event.lengthComputable || !onProgress) return;
|
|
22684
|
+
const elapsed = (Date.now() - startTime) / config.TIME_CONSTANTS.SECOND;
|
|
22685
|
+
const speed = elapsed > 0 ? event.loaded / elapsed : 0;
|
|
22686
|
+
const remaining = event.total - event.loaded;
|
|
22687
|
+
onProgress({
|
|
22688
|
+
loaded: event.loaded,
|
|
22689
|
+
total: event.total,
|
|
22690
|
+
percentage: Math.round(event.loaded / event.total * UPLOAD_CONSTANTS.FULL_PERCENTAGE),
|
|
22691
|
+
speed,
|
|
22692
|
+
estimatedTimeRemaining: speed > 0 ? remaining / speed : void 0
|
|
22693
|
+
});
|
|
22694
|
+
});
|
|
22695
|
+
xhr.addEventListener("load", () => {
|
|
22696
|
+
const success = xhr.status >= config.HTTP_STATUS.OK && xhr.status < config.HTTP_STATUS.MULTIPLE_CHOICES;
|
|
22697
|
+
const responseHeaders = {};
|
|
22698
|
+
const headerLines = xhr.getAllResponseHeaders().trim().split("\n");
|
|
22699
|
+
for (const line of headerLines) {
|
|
22700
|
+
const [key, ...valueParts] = line.split(":");
|
|
22701
|
+
if (key) responseHeaders[key.trim().toLowerCase()] = valueParts.join(":").trim();
|
|
22702
|
+
}
|
|
22703
|
+
resolve({
|
|
22704
|
+
status: xhr.status,
|
|
22705
|
+
statusText: xhr.statusText,
|
|
22706
|
+
data: xhr.responseText || void 0,
|
|
22707
|
+
headers: responseHeaders,
|
|
22708
|
+
success
|
|
22709
|
+
});
|
|
22710
|
+
});
|
|
22711
|
+
xhr.addEventListener(
|
|
22712
|
+
"error",
|
|
22713
|
+
() => reject(
|
|
22714
|
+
new ApiPackageError(
|
|
22715
|
+
`Upload failed: ${xhr.statusText || "Network error"}`,
|
|
22716
|
+
void 0,
|
|
22717
|
+
errors.API_ERROR_CODES.NETWORK_ERROR,
|
|
22718
|
+
{ context: { url: resolvedUrl, statusText: xhr.statusText } }
|
|
22719
|
+
)
|
|
22720
|
+
)
|
|
22721
|
+
);
|
|
22722
|
+
xhr.addEventListener(
|
|
22723
|
+
"abort",
|
|
22724
|
+
() => reject(
|
|
22725
|
+
new ApiPackageError("Upload aborted", void 0, errors.API_ERROR_CODES.REQUEST_ABORTED, {
|
|
22726
|
+
context: { url: resolvedUrl }
|
|
22727
|
+
})
|
|
22728
|
+
)
|
|
22729
|
+
);
|
|
22730
|
+
if (abortSignal) abortSignal.addEventListener("abort", () => xhr.abort());
|
|
22731
|
+
xhr.open(method, resolvedUrl);
|
|
22732
|
+
if (withCredentials) xhr.withCredentials = true;
|
|
22733
|
+
xhr.setRequestHeader("Content-Type", contentType);
|
|
22734
|
+
for (const [key, value] of Object.entries(mergedHeaders)) xhr.setRequestHeader(key, value);
|
|
22735
|
+
if (data instanceof Blob || data instanceof ArrayBuffer) {
|
|
22736
|
+
xhr.send(data);
|
|
22737
|
+
} else if (data instanceof Uint8Array) {
|
|
22738
|
+
xhr.send(new Uint8Array(data));
|
|
22739
|
+
} else {
|
|
22740
|
+
xhr.send(data);
|
|
22741
|
+
}
|
|
22742
|
+
});
|
|
22743
|
+
}
|
|
22744
|
+
__name(uploadOnce2, "uploadOnce");
|
|
22745
|
+
async function uploadWithProgressBrowser(options) {
|
|
22746
|
+
const config = getMergedConfig(options);
|
|
22747
|
+
const resolvedUrl = resolveUrl(options.url, config.baseURL);
|
|
22748
|
+
const maxAttempts = config.retry ? (config.retry.attempts ?? 0) + 1 : 1;
|
|
22749
|
+
let lastError;
|
|
22750
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
22751
|
+
const ctx = { config, maxAttempts, attempt };
|
|
22752
|
+
try {
|
|
22753
|
+
const result = await uploadOnce2(options, config, resolvedUrl);
|
|
22754
|
+
if (shouldRetryResult(result, config, attempt, maxAttempts)) {
|
|
22755
|
+
notifyRetryError({
|
|
22756
|
+
ctx,
|
|
22757
|
+
message: `Upload failed: ${result.status}`,
|
|
22758
|
+
status: result.status,
|
|
22759
|
+
statusText: result.statusText
|
|
22760
|
+
});
|
|
22761
|
+
await handleRetryDelay(attempt, config.retry);
|
|
22762
|
+
continue;
|
|
22763
|
+
}
|
|
22764
|
+
return { ...result, attempts: attempt };
|
|
22765
|
+
} catch (error) {
|
|
22766
|
+
lastError = normalizeError2(error);
|
|
22767
|
+
if (shouldRetryError(lastError, config, attempt, maxAttempts)) {
|
|
22768
|
+
notifyRetryError({ ctx, message: lastError.message, cause: lastError });
|
|
22769
|
+
await handleRetryDelay(attempt, config.retry);
|
|
22770
|
+
continue;
|
|
22771
|
+
}
|
|
22772
|
+
notifyFinalError(ctx, lastError);
|
|
22773
|
+
throw lastError;
|
|
22774
|
+
}
|
|
22775
|
+
}
|
|
22776
|
+
throw lastError ?? new ApiPackageError(
|
|
22777
|
+
"Upload failed after all retry attempts",
|
|
22778
|
+
void 0,
|
|
22779
|
+
errors.API_ERROR_CODES.NETWORK_ERROR
|
|
22780
|
+
);
|
|
22781
|
+
}
|
|
22782
|
+
__name(uploadWithProgressBrowser, "uploadWithProgressBrowser");
|
|
22783
|
+
|
|
22784
|
+
// src/api/upload/uploadWithProgress.ts
|
|
22785
|
+
async function uploadWithProgress(options) {
|
|
22786
|
+
if (isNode()) {
|
|
22787
|
+
return uploadWithProgressNode(options);
|
|
22788
|
+
}
|
|
22789
|
+
return uploadWithProgressBrowser(options);
|
|
22790
|
+
}
|
|
22791
|
+
__name(uploadWithProgress, "uploadWithProgress");
|
|
22252
22792
|
|
|
22253
22793
|
// src/api/hooks/factories/defaults.ts
|
|
22254
22794
|
var DEFAULT_QUERY_OPTIONS = {};
|
|
@@ -24396,13 +24936,13 @@ function isAbortError(error) {
|
|
|
24396
24936
|
return message.includes("abort") || message.includes("cancel");
|
|
24397
24937
|
}
|
|
24398
24938
|
__name(isAbortError, "isAbortError");
|
|
24399
|
-
function
|
|
24939
|
+
function createAbortError2(message = "Request aborted") {
|
|
24400
24940
|
if (message === null || message === void 0) {
|
|
24401
24941
|
return "Request aborted";
|
|
24402
24942
|
}
|
|
24403
24943
|
return message;
|
|
24404
24944
|
}
|
|
24405
|
-
__name(
|
|
24945
|
+
__name(createAbortError2, "createAbortError");
|
|
24406
24946
|
|
|
24407
24947
|
// src/api/request/tracker.ts
|
|
24408
24948
|
var RequestTracker = class {
|
|
@@ -24452,7 +24992,7 @@ var RequestTracker = class {
|
|
|
24452
24992
|
controller.abort(reason);
|
|
24453
24993
|
this.unregister(key);
|
|
24454
24994
|
}
|
|
24455
|
-
void abortRequest(key,
|
|
24995
|
+
void abortRequest(key, createAbortError2(reason ?? "Request aborted"));
|
|
24456
24996
|
}
|
|
24457
24997
|
/**
|
|
24458
24998
|
* Abort all requests in a group
|
|
@@ -24478,7 +25018,7 @@ var RequestTracker = class {
|
|
|
24478
25018
|
});
|
|
24479
25019
|
this.activeRequests.clear();
|
|
24480
25020
|
this.requestGroups.clear();
|
|
24481
|
-
void abortRequest("*",
|
|
25021
|
+
void abortRequest("*", createAbortError2(reason ?? "All requests aborted"));
|
|
24482
25022
|
}
|
|
24483
25023
|
/**
|
|
24484
25024
|
* Get active request count
|
|
@@ -24535,14 +25075,14 @@ function useRequestCleanup() {
|
|
|
24535
25075
|
}, "untrackRequest");
|
|
24536
25076
|
const abortTracked = /* @__PURE__ */ __name((reason) => {
|
|
24537
25077
|
requestKeys.current.forEach((key) => {
|
|
24538
|
-
void abortRequest(key,
|
|
25078
|
+
void abortRequest(key, createAbortError2(reason ?? "Manual abort"));
|
|
24539
25079
|
});
|
|
24540
25080
|
requestKeys.current.clear();
|
|
24541
25081
|
}, "abortTracked");
|
|
24542
25082
|
react.useEffect(() => {
|
|
24543
25083
|
return () => {
|
|
24544
25084
|
requestKeys.current.forEach((key) => {
|
|
24545
|
-
void abortRequest(key,
|
|
25085
|
+
void abortRequest(key, createAbortError2("Component unmounted"));
|
|
24546
25086
|
});
|
|
24547
25087
|
requestKeys.current.clear();
|
|
24548
25088
|
};
|
|
@@ -24563,14 +25103,14 @@ function useAbortableRequest(key) {
|
|
|
24563
25103
|
controllerRef.current.abort("Component unmounted or dependency changed");
|
|
24564
25104
|
requestTracker.unregister(key);
|
|
24565
25105
|
}
|
|
24566
|
-
void abortRequest(key,
|
|
25106
|
+
void abortRequest(key, createAbortError2("Request cancelled"));
|
|
24567
25107
|
};
|
|
24568
25108
|
}, [key]);
|
|
24569
25109
|
const abort = /* @__PURE__ */ __name((reason) => {
|
|
24570
25110
|
if (controllerRef.current) {
|
|
24571
25111
|
controllerRef.current.abort(reason);
|
|
24572
25112
|
}
|
|
24573
|
-
void abortRequest(key,
|
|
25113
|
+
void abortRequest(key, createAbortError2(reason ?? "Request aborted by user"));
|
|
24574
25114
|
}, "abort");
|
|
24575
25115
|
return {
|
|
24576
25116
|
signal,
|
|
@@ -24632,9 +25172,9 @@ function setupRouteChangeCleanup(router, options = {}) {
|
|
|
24632
25172
|
}
|
|
24633
25173
|
const pattern = options.abortPattern ?? "*";
|
|
24634
25174
|
if (options.preservePatterns && options.preservePatterns.length > 0) {
|
|
24635
|
-
void abortRequest(pattern,
|
|
25175
|
+
void abortRequest(pattern, createAbortError2(`Route changed to ${url}`));
|
|
24636
25176
|
} else {
|
|
24637
|
-
void abortRequest(pattern,
|
|
25177
|
+
void abortRequest(pattern, createAbortError2(`Route changed to ${url}`));
|
|
24638
25178
|
}
|
|
24639
25179
|
}, "executeAbort");
|
|
24640
25180
|
if (options.delay && options.delay > 0) {
|
|
@@ -24681,7 +25221,7 @@ function createRouteGuard(pattern = "*") {
|
|
|
24681
25221
|
}, "enter"),
|
|
24682
25222
|
leave: /* @__PURE__ */ __name((reason) => {
|
|
24683
25223
|
if (isActive) {
|
|
24684
|
-
void abortRequest(pattern,
|
|
25224
|
+
void abortRequest(pattern, createAbortError2(reason ?? "Leaving route"));
|
|
24685
25225
|
isActive = false;
|
|
24686
25226
|
}
|
|
24687
25227
|
}, "leave"),
|
|
@@ -24713,7 +25253,7 @@ __name(createRouteScope, "createRouteScope");
|
|
|
24713
25253
|
|
|
24714
25254
|
// src/api/request/utils.ts
|
|
24715
25255
|
function abortByPattern(pattern, reason) {
|
|
24716
|
-
void abortRequest(pattern,
|
|
25256
|
+
void abortRequest(pattern, createAbortError2(reason ?? `Requests matching ${pattern} aborted`));
|
|
24717
25257
|
}
|
|
24718
25258
|
__name(abortByPattern, "abortByPattern");
|
|
24719
25259
|
function abortSearchRequests(reason) {
|
|
@@ -24731,25 +25271,25 @@ __name(abortAllRequests, "abortAllRequests");
|
|
|
24731
25271
|
function createScopedAbort(scope) {
|
|
24732
25272
|
return (key, reason) => {
|
|
24733
25273
|
const fullKey = key.startsWith("/") ? `${scope}${key}` : `${scope}/${key}`;
|
|
24734
|
-
void abortRequest(fullKey,
|
|
25274
|
+
void abortRequest(fullKey, createAbortError2(reason ?? "Scoped request aborted"));
|
|
24735
25275
|
};
|
|
24736
25276
|
}
|
|
24737
25277
|
__name(createScopedAbort, "createScopedAbort");
|
|
24738
25278
|
function createDebouncedAbort(delay = 300) {
|
|
24739
25279
|
return debounce((key, reason) => {
|
|
24740
|
-
void abortRequest(key,
|
|
25280
|
+
void abortRequest(key, createAbortError2(reason ?? "Debounced abort"));
|
|
24741
25281
|
}, delay);
|
|
24742
25282
|
}
|
|
24743
25283
|
__name(createDebouncedAbort, "createDebouncedAbort");
|
|
24744
25284
|
function createThrottledAbort(limit = 1e3) {
|
|
24745
25285
|
return throttle((key, reason) => {
|
|
24746
|
-
void abortRequest(key,
|
|
25286
|
+
void abortRequest(key, createAbortError2(reason ?? "Throttled abort"));
|
|
24747
25287
|
}, limit);
|
|
24748
25288
|
}
|
|
24749
25289
|
__name(createThrottledAbort, "createThrottledAbort");
|
|
24750
25290
|
async function requestWithTimeout(key, fetcher, timeoutMs) {
|
|
24751
25291
|
const timeoutId = setTimeout(() => {
|
|
24752
|
-
void abortRequest(key,
|
|
25292
|
+
void abortRequest(key, createAbortError2(`Request timeout after ${timeoutMs}ms`));
|
|
24753
25293
|
}, timeoutMs);
|
|
24754
25294
|
try {
|
|
24755
25295
|
return await fetcher();
|
|
@@ -24762,7 +25302,7 @@ async function raceRequests(requests) {
|
|
|
24762
25302
|
const abortLosers = /* @__PURE__ */ __name((winnerKey) => {
|
|
24763
25303
|
requests.forEach((req) => {
|
|
24764
25304
|
if (req.key !== winnerKey) {
|
|
24765
|
-
void abortRequest(req.key,
|
|
25305
|
+
void abortRequest(req.key, createAbortError2("Lost race"));
|
|
24766
25306
|
}
|
|
24767
25307
|
});
|
|
24768
25308
|
}, "abortLosers");
|
|
@@ -24783,7 +25323,7 @@ async function sequentialRequests(requests) {
|
|
|
24783
25323
|
results.push(result);
|
|
24784
25324
|
} catch (error) {
|
|
24785
25325
|
for (let j = i + 1; j < requests.length; j++) {
|
|
24786
|
-
void abortRequest(requests[j].key,
|
|
25326
|
+
void abortRequest(requests[j].key, createAbortError2("Previous request in chain failed"));
|
|
24787
25327
|
}
|
|
24788
25328
|
throw error;
|
|
24789
25329
|
}
|
|
@@ -27039,7 +27579,7 @@ exports.configConflictDetector = configConflictDetector;
|
|
|
27039
27579
|
exports.configureForEnvironment = configureForEnvironment;
|
|
27040
27580
|
exports.containsAny = containsAny;
|
|
27041
27581
|
exports.convertEndpointsToFetchff = convertEndpointsToFetchff;
|
|
27042
|
-
exports.createAbortError =
|
|
27582
|
+
exports.createAbortError = createAbortError2;
|
|
27043
27583
|
exports.createAdaptiveResponse = createAdaptiveResponse;
|
|
27044
27584
|
exports.createApiClient = createApiClient;
|
|
27045
27585
|
exports.createCachePattern = createCachePattern;
|
|
@@ -27490,6 +28030,7 @@ exports.updateInfobipScheduledEmailStatuses = updateInfobipScheduledEmailStatuse
|
|
|
27490
28030
|
exports.uploadFile = uploadFile;
|
|
27491
28031
|
exports.uploadFileForScanning = uploadFileForScanning;
|
|
27492
28032
|
exports.uploadFiles = uploadFiles;
|
|
28033
|
+
exports.uploadWithProgress = uploadWithProgress;
|
|
27493
28034
|
exports.useAbortableRequest = useAbortableRequest;
|
|
27494
28035
|
exports.useApiConfigConflicts = useApiConfigConflicts;
|
|
27495
28036
|
exports.useApiDebugInfo = useApiDebugInfo;
|