@uploadcare/upload-client 4.3.1-alpha.0 → 5.1.0

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.
@@ -27,14 +27,116 @@ const onCancel = (signal, callback) => {
27
27
  }
28
28
  };
29
29
 
30
+ function isObject(o) {
31
+ return Object.prototype.toString.call(o) === '[object Object]';
32
+ }
33
+
34
+ const SEPARATOR = /\W|_/g;
35
+ function camelizeString(text) {
36
+ return text
37
+ .split(SEPARATOR)
38
+ .map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
39
+ word.slice(1))
40
+ .join('');
41
+ }
42
+ function camelizeArrayItems(array, { ignoreKeys } = { ignoreKeys: [] }) {
43
+ if (!Array.isArray(array)) {
44
+ return array;
45
+ }
46
+ return array.map((item) => camelizeKeys(item, { ignoreKeys }));
47
+ }
48
+ function camelizeKeys(source, { ignoreKeys } = { ignoreKeys: [] }) {
49
+ if (Array.isArray(source)) {
50
+ return camelizeArrayItems(source, { ignoreKeys });
51
+ }
52
+ if (!isObject(source)) {
53
+ return source;
54
+ }
55
+ const result = {};
56
+ for (const key of Object.keys(source)) {
57
+ let value = source[key];
58
+ if (ignoreKeys.includes(key)) {
59
+ result[key] = value;
60
+ continue;
61
+ }
62
+ if (isObject(value)) {
63
+ value = camelizeKeys(value, { ignoreKeys });
64
+ }
65
+ else if (Array.isArray(value)) {
66
+ value = camelizeArrayItems(value, { ignoreKeys });
67
+ }
68
+ result[camelizeString(key)] = value;
69
+ }
70
+ return result;
71
+ }
72
+
73
+ /**
74
+ * setTimeout as Promise.
75
+ *
76
+ * @param {number} ms Timeout in milliseconds.
77
+ */
78
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
79
+
80
+ function getUserAgent$1({ libraryName, libraryVersion, userAgent, publicKey = '', integration = '' }) {
81
+ const languageName = 'JavaScript';
82
+ if (typeof userAgent === 'string') {
83
+ return userAgent;
84
+ }
85
+ if (typeof userAgent === 'function') {
86
+ return userAgent({
87
+ publicKey,
88
+ libraryName,
89
+ libraryVersion,
90
+ languageName,
91
+ integration
92
+ });
93
+ }
94
+ const mainInfo = [libraryName, libraryVersion, publicKey]
95
+ .filter(Boolean)
96
+ .join('/');
97
+ const additionInfo = [languageName, integration].filter(Boolean).join('; ');
98
+ return `${mainInfo} (${additionInfo})`;
99
+ }
100
+
101
+ const defaultOptions = {
102
+ factor: 2,
103
+ time: 100
104
+ };
105
+ function retrier(fn, options = defaultOptions) {
106
+ let attempts = 0;
107
+ function runAttempt(fn) {
108
+ const defaultDelayTime = Math.round(options.time * options.factor ** attempts);
109
+ const retry = (ms) => delay(ms ?? defaultDelayTime).then(() => {
110
+ attempts += 1;
111
+ return runAttempt(fn);
112
+ });
113
+ return fn({
114
+ attempt: attempts,
115
+ retry
116
+ });
117
+ }
118
+ return runAttempt(fn);
119
+ }
120
+
121
+ class UploadcareNetworkError extends Error {
122
+ constructor(progressEvent) {
123
+ super();
124
+ this.name = 'UploadcareNetworkError';
125
+ this.message = 'Network error';
126
+ Object.setPrototypeOf(this, UploadcareNetworkError.prototype);
127
+ this.originalProgressEvent = progressEvent;
128
+ }
129
+ }
130
+
30
131
  const request = ({ method, url, data, headers = {}, signal, onProgress }) => new Promise((resolve, reject) => {
31
132
  const xhr = new XMLHttpRequest();
32
133
  const requestMethod = method?.toUpperCase() || 'GET';
33
134
  let aborted = false;
34
135
  /**
35
136
  * Force synchronous flag to be off
36
- * Some users get `InvalidAccessError` error when we set `responseType`
137
+ * Some chrome versions gets `InvalidAccessError` error when we set `responseType`
37
138
  * See https://xhr.spec.whatwg.org/#synchronous-flag
139
+ * and https://bugs.chromium.org/p/chromium/issues/detail?id=1346628
38
140
  */
39
141
  xhr.open(requestMethod, url, true);
40
142
  if (headers) {
@@ -91,11 +193,11 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
91
193
  });
92
194
  }
93
195
  };
94
- xhr.onerror = () => {
196
+ xhr.onerror = (progressEvent) => {
95
197
  if (aborted)
96
198
  return;
97
199
  // only triggers if the request couldn't be made at all
98
- reject(new Error('Network error'));
200
+ reject(new UploadcareNetworkError(progressEvent));
99
201
  };
100
202
  if (onProgress && typeof onProgress === 'function') {
101
203
  xhr.upload.onprogress = (event) => {
@@ -226,7 +328,7 @@ const buildSearchParams = (query) => {
226
328
  };
227
329
  const getUrl = (base, path, query) => {
228
330
  const url = new URL(base);
229
- url.pathname = path;
331
+ url.pathname = (url.pathname + path).replace('//', '/');
230
332
  if (query) {
231
333
  url.search = buildSearchParams(query);
232
334
  }
@@ -242,109 +344,18 @@ const defaultSettings = {
242
344
  baseURL: 'https://upload.uploadcare.com',
243
345
  maxContentLength: 50 * 1024 * 1024,
244
346
  retryThrottledRequestMaxTimes: 1,
347
+ retryNetworkErrorMaxTimes: 3,
245
348
  multipartMinFileSize: 25 * 1024 * 1024,
246
349
  multipartChunkSize: 5 * 1024 * 1024,
247
350
  multipartMinLastPartSize: 1024 * 1024,
248
351
  maxConcurrentRequests: 4,
249
- multipartMaxAttempts: 3,
250
352
  pollingTimeoutMilliseconds: 10000,
251
353
  pusherKey: '79ae88bd931ea68464d9'
252
354
  };
253
355
  const defaultContentType = 'application/octet-stream';
254
356
  const defaultFilename = 'original';
255
357
 
256
- var version = '4.3.1-alpha.0';
257
-
258
- function isObject(o) {
259
- return Object.prototype.toString.call(o) === '[object Object]';
260
- }
261
-
262
- const SEPARATOR = /\W|_/g;
263
- function camelizeString(text) {
264
- return text
265
- .split(SEPARATOR)
266
- .map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
267
- word.slice(1))
268
- .join('');
269
- }
270
- function camelizeArrayItems(array, { ignoreKeys } = { ignoreKeys: [] }) {
271
- if (!Array.isArray(array)) {
272
- return array;
273
- }
274
- return array.map((item) => camelizeKeys(item, { ignoreKeys }));
275
- }
276
- function camelizeKeys(source, { ignoreKeys } = { ignoreKeys: [] }) {
277
- if (Array.isArray(source)) {
278
- return camelizeArrayItems(source, { ignoreKeys });
279
- }
280
- if (!isObject(source)) {
281
- return source;
282
- }
283
- const result = {};
284
- for (const key of Object.keys(source)) {
285
- let value = source[key];
286
- if (ignoreKeys.includes(key)) {
287
- result[key] = value;
288
- continue;
289
- }
290
- if (isObject(value)) {
291
- value = camelizeKeys(value, { ignoreKeys });
292
- }
293
- else if (Array.isArray(value)) {
294
- value = camelizeArrayItems(value, { ignoreKeys });
295
- }
296
- result[camelizeString(key)] = value;
297
- }
298
- return result;
299
- }
300
-
301
- /**
302
- * setTimeout as Promise.
303
- *
304
- * @param {number} ms Timeout in milliseconds.
305
- */
306
- const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
307
-
308
- function getUserAgent$1({ libraryName, libraryVersion, userAgent, publicKey = '', integration = '' }) {
309
- const languageName = 'JavaScript';
310
- if (typeof userAgent === 'string') {
311
- return userAgent;
312
- }
313
- if (typeof userAgent === 'function') {
314
- return userAgent({
315
- publicKey,
316
- libraryName,
317
- libraryVersion,
318
- languageName,
319
- integration
320
- });
321
- }
322
- const mainInfo = [libraryName, libraryVersion, publicKey]
323
- .filter(Boolean)
324
- .join('/');
325
- const additionInfo = [languageName, integration].filter(Boolean).join('; ');
326
- return `${mainInfo} (${additionInfo})`;
327
- }
328
-
329
- const defaultOptions = {
330
- factor: 2,
331
- time: 100
332
- };
333
- function retrier(fn, options = defaultOptions) {
334
- let attempts = 0;
335
- function runAttempt(fn) {
336
- const defaultDelayTime = Math.round(options.time * options.factor ** attempts);
337
- const retry = (ms) => delay(ms ?? defaultDelayTime).then(() => {
338
- attempts += 1;
339
- return runAttempt(fn);
340
- });
341
- return fn({
342
- attempt: attempts,
343
- retry
344
- });
345
- }
346
- return runAttempt(fn);
347
- }
358
+ var version = '5.1.0';
348
359
 
349
360
  const LIBRARY_NAME = 'UploadcareUploadClient';
350
361
  const LIBRARY_VERSION = version;
@@ -357,20 +368,26 @@ function getUserAgent(options) {
357
368
  }
358
369
 
359
370
  const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
360
- const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
371
+ const DEFAULT_THROTTLED_TIMEOUT = 15000;
372
+ const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
361
373
  function getTimeoutFromThrottledRequest(error) {
362
374
  const { headers } = error || {};
363
375
  return ((headers &&
364
376
  Number.parseInt(headers['x-throttle-wait-seconds']) * 1000) ||
365
- DEFAULT_RETRY_AFTER_TIMEOUT);
377
+ DEFAULT_THROTTLED_TIMEOUT);
366
378
  }
367
- function retryIfThrottled(fn, retryThrottledMaxTimes) {
379
+ function retryIfFailed(fn, options) {
380
+ const { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes } = options;
368
381
  return retrier(({ attempt, retry }) => fn().catch((error) => {
369
382
  if ('response' in error &&
370
383
  error?.code === REQUEST_WAS_THROTTLED_CODE &&
371
- attempt < retryThrottledMaxTimes) {
384
+ attempt < retryThrottledRequestMaxTimes) {
372
385
  return retry(getTimeoutFromThrottledRequest(error));
373
386
  }
387
+ if (error instanceof UploadcareNetworkError &&
388
+ attempt < retryNetworkErrorMaxTimes) {
389
+ return retry((attempt + 1) * DEFAULT_NETWORK_ERROR_TIMEOUT);
390
+ }
374
391
  throw error;
375
392
  }));
376
393
  }
@@ -383,8 +400,8 @@ function getStoreValue(store) {
383
400
  * Performs file uploading request to Uploadcare Upload API.
384
401
  * Can be canceled and has progress.
385
402
  */
386
- function base(file, { publicKey, fileName, contentType, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
387
- return retryIfThrottled(() => request({
403
+ function base(file, { publicKey, fileName, contentType, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes, metadata }) {
404
+ return retryIfFailed(() => request({
388
405
  method: 'POST',
389
406
  url: getUrl(baseURL, '/base/', {
390
407
  jsonerrors: 1
@@ -415,7 +432,7 @@ function base(file, { publicKey, fileName, contentType, baseURL = defaultSetting
415
432
  else {
416
433
  return response;
417
434
  }
418
- }), retryThrottledRequestMaxTimes);
435
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
419
436
  }
420
437
 
421
438
  var TypeEnum;
@@ -426,8 +443,8 @@ var TypeEnum;
426
443
  /**
427
444
  * Uploading files from URL.
428
445
  */
429
- function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
430
- return retryIfThrottled(() => request({
446
+ function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes, metadata }) {
447
+ return retryIfFailed(() => request({
431
448
  method: 'POST',
432
449
  headers: {
433
450
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -454,7 +471,7 @@ function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, stor
454
471
  else {
455
472
  return response;
456
473
  }
457
- }), retryThrottledRequestMaxTimes);
474
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
458
475
  }
459
476
 
460
477
  var Status;
@@ -471,8 +488,8 @@ const isErrorResponse = (response) => {
471
488
  /**
472
489
  * Checking upload status and working with file tokens.
473
490
  */
474
- function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes } = {}) {
475
- return retryIfThrottled(() => request({
491
+ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes } = {}) {
492
+ return retryIfFailed(() => request({
476
493
  method: 'GET',
477
494
  headers: publicKey
478
495
  ? {
@@ -496,14 +513,14 @@ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, si
496
513
  else {
497
514
  return response;
498
515
  }
499
- }), retryThrottledRequestMaxTimes);
516
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
500
517
  }
501
518
 
502
519
  /**
503
520
  * Create files group.
504
521
  */
505
- function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
506
- return retryIfThrottled(() => request({
522
+ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
523
+ return retryIfFailed(() => request({
507
524
  method: 'POST',
508
525
  headers: {
509
526
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -526,14 +543,14 @@ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallb
526
543
  else {
527
544
  return response;
528
545
  }
529
- }), retryThrottledRequestMaxTimes);
546
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
530
547
  }
531
548
 
532
549
  /**
533
550
  * Get info about group.
534
551
  */
535
- function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
536
- return retryIfThrottled(() => request({
552
+ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
553
+ return retryIfFailed(() => request({
537
554
  method: 'GET',
538
555
  headers: {
539
556
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -553,14 +570,14 @@ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, s
553
570
  else {
554
571
  return response;
555
572
  }
556
- }), retryThrottledRequestMaxTimes);
573
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
557
574
  }
558
575
 
559
576
  /**
560
577
  * Returns a JSON dictionary holding file info.
561
578
  */
562
- function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
563
- return retryIfThrottled(() => request({
579
+ function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
580
+ return retryIfFailed(() => request({
564
581
  method: 'GET',
565
582
  headers: {
566
583
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -580,14 +597,14 @@ function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, sour
580
597
  else {
581
598
  return response;
582
599
  }
583
- }), retryThrottledRequestMaxTimes);
600
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
584
601
  }
585
602
 
586
603
  /**
587
604
  * Start multipart uploading.
588
605
  */
589
- function multipartStart(size, { publicKey, contentType, fileName, multipartChunkSize = defaultSettings.multipartChunkSize, baseURL = '', secureSignature, secureExpire, store, signal, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
590
- return retryIfThrottled(() => request({
606
+ function multipartStart(size, { publicKey, contentType, fileName, multipartChunkSize = defaultSettings.multipartChunkSize, baseURL = '', secureSignature, secureExpire, store, signal, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes, metadata }) {
607
+ return retryIfFailed(() => request({
591
608
  method: 'POST',
592
609
  url: getUrl(baseURL, '/multipart/start/', { jsonerrors: 1 }),
593
610
  headers: {
@@ -616,14 +633,14 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
616
633
  response.parts = Object.keys(response.parts).map((key) => response.parts[key]);
617
634
  return response;
618
635
  }
619
- }), retryThrottledRequestMaxTimes);
636
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
620
637
  }
621
638
 
622
639
  /**
623
640
  * Complete multipart uploading.
624
641
  */
625
- function multipartUpload(part, url, { signal, onProgress }) {
626
- return request({
642
+ function multipartUpload(part, url, { signal, onProgress, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
643
+ return retryIfFailed(() => request({
627
644
  method: 'PUT',
628
645
  url,
629
646
  data: part,
@@ -640,14 +657,17 @@ function multipartUpload(part, url, { signal, onProgress }) {
640
657
  });
641
658
  return result;
642
659
  })
643
- .then(({ status }) => ({ code: status }));
660
+ .then(({ status }) => ({ code: status })), {
661
+ retryThrottledRequestMaxTimes,
662
+ retryNetworkErrorMaxTimes
663
+ });
644
664
  }
645
665
 
646
666
  /**
647
667
  * Complete multipart uploading.
648
668
  */
649
- function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL, source = 'local', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
650
- return retryIfThrottled(() => request({
669
+ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL, source = 'local', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
670
+ return retryIfFailed(() => request({
651
671
  method: 'POST',
652
672
  url: getUrl(baseURL, '/multipart/complete/', { jsonerrors: 1 }),
653
673
  headers: {
@@ -667,7 +687,7 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
667
687
  else {
668
688
  return response;
669
689
  }
670
- }), retryThrottledRequestMaxTimes);
690
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
671
691
  }
672
692
 
673
693
  class UploadcareFile {
@@ -734,7 +754,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
734
754
  timeoutId = setTimeout(tick, 0);
735
755
  });
736
756
 
737
- function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, signal, onProgress }) {
757
+ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
738
758
  return poll({
739
759
  check: (signal) => info(file, {
740
760
  publicKey,
@@ -743,7 +763,8 @@ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent,
743
763
  source,
744
764
  integration,
745
765
  userAgent,
746
- retryThrottledRequestMaxTimes
766
+ retryThrottledRequestMaxTimes,
767
+ retryNetworkErrorMaxTimes
747
768
  }).then((response) => {
748
769
  if (response.isReady) {
749
770
  return response;
@@ -755,7 +776,7 @@ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent,
755
776
  });
756
777
  }
757
778
 
758
- const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN, metadata }) => {
779
+ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN, metadata }) => {
759
780
  return base(file, {
760
781
  publicKey,
761
782
  fileName,
@@ -770,6 +791,7 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
770
791
  integration,
771
792
  userAgent,
772
793
  retryThrottledRequestMaxTimes,
794
+ retryNetworkErrorMaxTimes,
773
795
  metadata
774
796
  })
775
797
  .then(({ file }) => {
@@ -781,6 +803,7 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
781
803
  integration,
782
804
  userAgent,
783
805
  retryThrottledRequestMaxTimes,
806
+ retryNetworkErrorMaxTimes,
784
807
  onProgress,
785
808
  signal
786
809
  });
@@ -968,7 +991,7 @@ const preconnect = (key) => {
968
991
  getPusher(key).connect();
969
992
  };
970
993
 
971
- function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, onProgress, signal }) {
994
+ function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, onProgress, signal }) {
972
995
  return poll({
973
996
  check: (signal) => fromUrlStatus(token, {
974
997
  publicKey,
@@ -976,6 +999,7 @@ function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retry
976
999
  integration,
977
1000
  userAgent,
978
1001
  retryThrottledRequestMaxTimes,
1002
+ retryNetworkErrorMaxTimes,
979
1003
  signal
980
1004
  }).then((response) => {
981
1005
  switch (response.status) {
@@ -1126,7 +1150,7 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
1126
1150
  }))
1127
1151
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1128
1152
 
1129
- const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN }) => {
1153
+ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN }) => {
1130
1154
  return info(uuid, {
1131
1155
  publicKey,
1132
1156
  baseURL,
@@ -1134,7 +1158,8 @@ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProg
1134
1158
  source,
1135
1159
  integration,
1136
1160
  userAgent,
1137
- retryThrottledRequestMaxTimes
1161
+ retryThrottledRequestMaxTimes,
1162
+ retryNetworkErrorMaxTimes
1138
1163
  })
1139
1164
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1140
1165
  .then((result) => {
@@ -1206,18 +1231,15 @@ const runWithConcurrency = (concurrency, tasks) => {
1206
1231
  });
1207
1232
  };
1208
1233
 
1209
- const uploadPartWithRetry = (chunk, url, { publicKey, onProgress, signal, integration, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
1234
+ const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes }) => multipartUpload(chunk, url, {
1210
1235
  publicKey,
1211
1236
  onProgress,
1212
1237
  signal,
1213
- integration
1214
- }).catch((error) => {
1215
- if (attempt < multipartMaxAttempts) {
1216
- return retry();
1217
- }
1218
- throw error;
1219
- }));
1220
- const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, maxConcurrentRequests = defaultSettings.maxConcurrentRequests, multipartMaxAttempts = defaultSettings.multipartMaxAttempts, baseCDN, metadata }) => {
1238
+ integration,
1239
+ retryThrottledRequestMaxTimes,
1240
+ retryNetworkErrorMaxTimes
1241
+ });
1242
+ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, maxConcurrentRequests = defaultSettings.maxConcurrentRequests, baseCDN, metadata }) => {
1221
1243
  const size = fileSize || getFileSize(file);
1222
1244
  let progressValues;
1223
1245
  const createProgressHandler = (totalChunks, chunkIdx) => {
@@ -1251,18 +1273,20 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1251
1273
  integration,
1252
1274
  userAgent,
1253
1275
  retryThrottledRequestMaxTimes,
1276
+ retryNetworkErrorMaxTimes,
1254
1277
  metadata
1255
1278
  })
1256
1279
  .then(({ uuid, parts }) => {
1257
1280
  const getChunk = prepareChunks(file, size, multipartChunkSize);
1258
1281
  return Promise.all([
1259
1282
  uuid,
1260
- runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(index), url, {
1283
+ runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPart(getChunk(index), url, {
1261
1284
  publicKey,
1262
1285
  onProgress: createProgressHandler(parts.length, index),
1263
1286
  signal,
1264
1287
  integration,
1265
- multipartMaxAttempts
1288
+ retryThrottledRequestMaxTimes,
1289
+ retryNetworkErrorMaxTimes
1266
1290
  })))
1267
1291
  ]);
1268
1292
  })
@@ -1272,7 +1296,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1272
1296
  source,
1273
1297
  integration,
1274
1298
  userAgent,
1275
- retryThrottledRequestMaxTimes
1299
+ retryThrottledRequestMaxTimes,
1300
+ retryNetworkErrorMaxTimes
1276
1301
  }))
1277
1302
  .then((fileInfo) => {
1278
1303
  if (fileInfo.isReady) {
@@ -1287,6 +1312,7 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1287
1312
  integration,
1288
1313
  userAgent,
1289
1314
  retryThrottledRequestMaxTimes,
1315
+ retryNetworkErrorMaxTimes,
1290
1316
  onProgress,
1291
1317
  signal
1292
1318
  });
@@ -1298,7 +1324,7 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1298
1324
  /**
1299
1325
  * Uploads file from provided data.
1300
1326
  */
1301
- function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartMinFileSize, multipartChunkSize, multipartMaxAttempts, maxConcurrentRequests, baseCDN = defaultSettings.baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, pusherKey, metadata }) {
1327
+ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, contentType, multipartMinFileSize, multipartChunkSize, maxConcurrentRequests, baseCDN = defaultSettings.baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, pusherKey, metadata }) {
1302
1328
  if (isFileData(data)) {
1303
1329
  const fileSize = getFileSize(data);
1304
1330
  if (isMultipart(fileSize, multipartMinFileSize)) {
@@ -1306,7 +1332,6 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1306
1332
  publicKey,
1307
1333
  contentType,
1308
1334
  multipartChunkSize,
1309
- multipartMaxAttempts,
1310
1335
  fileName,
1311
1336
  baseURL,
1312
1337
  secureSignature,
@@ -1319,6 +1344,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1319
1344
  userAgent,
1320
1345
  maxConcurrentRequests,
1321
1346
  retryThrottledRequestMaxTimes,
1347
+ retryNetworkErrorMaxTimes,
1322
1348
  baseCDN,
1323
1349
  metadata
1324
1350
  });
@@ -1337,6 +1363,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1337
1363
  integration,
1338
1364
  userAgent,
1339
1365
  retryThrottledRequestMaxTimes,
1366
+ retryNetworkErrorMaxTimes,
1340
1367
  baseCDN,
1341
1368
  metadata
1342
1369
  });
@@ -1358,6 +1385,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1358
1385
  integration,
1359
1386
  userAgent,
1360
1387
  retryThrottledRequestMaxTimes,
1388
+ retryNetworkErrorMaxTimes,
1361
1389
  pusherKey,
1362
1390
  metadata
1363
1391
  });
@@ -1373,6 +1401,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1373
1401
  integration,
1374
1402
  userAgent,
1375
1403
  retryThrottledRequestMaxTimes,
1404
+ retryNetworkErrorMaxTimes,
1376
1405
  baseCDN
1377
1406
  });
1378
1407
  }
@@ -1428,7 +1457,7 @@ const isUrlArray = (data) => {
1428
1457
  return true;
1429
1458
  };
1430
1459
 
1431
- function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, baseCDN = defaultSettings.baseCDN, jsonpCallback }) {
1460
+ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, baseCDN = defaultSettings.baseCDN, jsonpCallback }) {
1432
1461
  if (!isFileDataArray(data) && !isUrlArray(data) && !isUuidArray(data)) {
1433
1462
  throw new TypeError(`Group uploading from "${data}" is not supported`);
1434
1463
  }
@@ -1465,6 +1494,7 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1465
1494
  integration,
1466
1495
  userAgent,
1467
1496
  retryThrottledRequestMaxTimes,
1497
+ retryNetworkErrorMaxTimes,
1468
1498
  contentType,
1469
1499
  multipartChunkSize,
1470
1500
  baseCDN
@@ -1480,7 +1510,8 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1480
1510
  source,
1481
1511
  integration,
1482
1512
  userAgent,
1483
- retryThrottledRequestMaxTimes
1513
+ retryThrottledRequestMaxTimes,
1514
+ retryNetworkErrorMaxTimes
1484
1515
  })
1485
1516
  .then((groupInfo) => new UploadcareGroup(groupInfo, files))
1486
1517
  .then((group) => {
@@ -1553,4 +1584,4 @@ class UploadClient {
1553
1584
  }
1554
1585
  }
1555
1586
 
1556
- export { UploadClient, UploadClientError, UploadcareFile, UploadcareGroup, base, fromUrl, fromUrlStatus, getUserAgent$1 as getUserAgent, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadDirect, uploadFile, uploadFileGroup, uploadFromUploaded, uploadFromUrl, uploadMultipart };
1587
+ export { UploadClient, UploadClientError, UploadcareFile, UploadcareGroup, UploadcareNetworkError, base, fromUrl, fromUrlStatus, getUserAgent$1 as getUserAgent, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadDirect, uploadFile, uploadFileGroup, uploadFromUploaded, uploadFromUrl, uploadMultipart };