@uploadcare/upload-client 4.3.1 → 5.0.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,6 +27,107 @@ 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';
@@ -92,11 +193,11 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
92
193
  });
93
194
  }
94
195
  };
95
- xhr.onerror = () => {
196
+ xhr.onerror = (progressEvent) => {
96
197
  if (aborted)
97
198
  return;
98
199
  // only triggers if the request couldn't be made at all
99
- reject(new Error('Network error'));
200
+ reject(new UploadcareNetworkError(progressEvent));
100
201
  };
101
202
  if (onProgress && typeof onProgress === 'function') {
102
203
  xhr.upload.onprogress = (event) => {
@@ -246,109 +347,18 @@ const defaultSettings = {
246
347
  baseURL: 'https://upload.uploadcare.com',
247
348
  maxContentLength: 50 * 1024 * 1024,
248
349
  retryThrottledRequestMaxTimes: 1,
350
+ retryNetworkErrorMaxTimes: 3,
249
351
  multipartMinFileSize: 25 * 1024 * 1024,
250
352
  multipartChunkSize: 5 * 1024 * 1024,
251
353
  multipartMinLastPartSize: 1024 * 1024,
252
354
  maxConcurrentRequests: 4,
253
- multipartMaxAttempts: 3,
254
355
  pollingTimeoutMilliseconds: 10000,
255
356
  pusherKey: '79ae88bd931ea68464d9'
256
357
  };
257
358
  const defaultContentType = 'application/octet-stream';
258
359
  const defaultFilename = 'original';
259
360
 
260
- var version = '4.3.1';
261
-
262
- function isObject(o) {
263
- return Object.prototype.toString.call(o) === '[object Object]';
264
- }
265
-
266
- const SEPARATOR = /\W|_/g;
267
- function camelizeString(text) {
268
- return text
269
- .split(SEPARATOR)
270
- .map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
271
- word.slice(1))
272
- .join('');
273
- }
274
- function camelizeArrayItems(array, { ignoreKeys } = { ignoreKeys: [] }) {
275
- if (!Array.isArray(array)) {
276
- return array;
277
- }
278
- return array.map((item) => camelizeKeys(item, { ignoreKeys }));
279
- }
280
- function camelizeKeys(source, { ignoreKeys } = { ignoreKeys: [] }) {
281
- if (Array.isArray(source)) {
282
- return camelizeArrayItems(source, { ignoreKeys });
283
- }
284
- if (!isObject(source)) {
285
- return source;
286
- }
287
- const result = {};
288
- for (const key of Object.keys(source)) {
289
- let value = source[key];
290
- if (ignoreKeys.includes(key)) {
291
- result[key] = value;
292
- continue;
293
- }
294
- if (isObject(value)) {
295
- value = camelizeKeys(value, { ignoreKeys });
296
- }
297
- else if (Array.isArray(value)) {
298
- value = camelizeArrayItems(value, { ignoreKeys });
299
- }
300
- result[camelizeString(key)] = value;
301
- }
302
- return result;
303
- }
304
-
305
- /**
306
- * setTimeout as Promise.
307
- *
308
- * @param {number} ms Timeout in milliseconds.
309
- */
310
- const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
311
-
312
- function getUserAgent$1({ libraryName, libraryVersion, userAgent, publicKey = '', integration = '' }) {
313
- const languageName = 'JavaScript';
314
- if (typeof userAgent === 'string') {
315
- return userAgent;
316
- }
317
- if (typeof userAgent === 'function') {
318
- return userAgent({
319
- publicKey,
320
- libraryName,
321
- libraryVersion,
322
- languageName,
323
- integration
324
- });
325
- }
326
- const mainInfo = [libraryName, libraryVersion, publicKey]
327
- .filter(Boolean)
328
- .join('/');
329
- const additionInfo = [languageName, integration].filter(Boolean).join('; ');
330
- return `${mainInfo} (${additionInfo})`;
331
- }
332
-
333
- const defaultOptions = {
334
- factor: 2,
335
- time: 100
336
- };
337
- function retrier(fn, options = defaultOptions) {
338
- let attempts = 0;
339
- function runAttempt(fn) {
340
- const defaultDelayTime = Math.round(options.time * options.factor ** attempts);
341
- const retry = (ms) => delay(ms ?? defaultDelayTime).then(() => {
342
- attempts += 1;
343
- return runAttempt(fn);
344
- });
345
- return fn({
346
- attempt: attempts,
347
- retry
348
- });
349
- }
350
- return runAttempt(fn);
351
- }
361
+ var version = '5.0.0';
352
362
 
353
363
  const LIBRARY_NAME = 'UploadcareUploadClient';
354
364
  const LIBRARY_VERSION = version;
@@ -361,20 +371,26 @@ function getUserAgent(options) {
361
371
  }
362
372
 
363
373
  const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
364
- const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
374
+ const DEFAULT_THROTTLED_TIMEOUT = 15000;
375
+ const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
365
376
  function getTimeoutFromThrottledRequest(error) {
366
377
  const { headers } = error || {};
367
378
  return ((headers &&
368
379
  Number.parseInt(headers['x-throttle-wait-seconds']) * 1000) ||
369
- DEFAULT_RETRY_AFTER_TIMEOUT);
380
+ DEFAULT_THROTTLED_TIMEOUT);
370
381
  }
371
- function retryIfThrottled(fn, retryThrottledMaxTimes) {
382
+ function retryIfFailed(fn, options) {
383
+ const { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes } = options;
372
384
  return retrier(({ attempt, retry }) => fn().catch((error) => {
373
385
  if ('response' in error &&
374
386
  error?.code === REQUEST_WAS_THROTTLED_CODE &&
375
- attempt < retryThrottledMaxTimes) {
387
+ attempt < retryThrottledRequestMaxTimes) {
376
388
  return retry(getTimeoutFromThrottledRequest(error));
377
389
  }
390
+ if (error instanceof UploadcareNetworkError &&
391
+ attempt < retryNetworkErrorMaxTimes) {
392
+ return retry((attempt + 1) * DEFAULT_NETWORK_ERROR_TIMEOUT);
393
+ }
378
394
  throw error;
379
395
  }));
380
396
  }
@@ -387,8 +403,8 @@ function getStoreValue(store) {
387
403
  * Performs file uploading request to Uploadcare Upload API.
388
404
  * Can be canceled and has progress.
389
405
  */
390
- function base(file, { publicKey, fileName, contentType, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
391
- return retryIfThrottled(() => request({
406
+ 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 }) {
407
+ return retryIfFailed(() => request({
392
408
  method: 'POST',
393
409
  url: getUrl(baseURL, '/base/', {
394
410
  jsonerrors: 1
@@ -419,7 +435,7 @@ function base(file, { publicKey, fileName, contentType, baseURL = defaultSetting
419
435
  else {
420
436
  return response;
421
437
  }
422
- }), retryThrottledRequestMaxTimes);
438
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
423
439
  }
424
440
 
425
441
  var TypeEnum;
@@ -430,8 +446,8 @@ var TypeEnum;
430
446
  /**
431
447
  * Uploading files from URL.
432
448
  */
433
- function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
434
- return retryIfThrottled(() => request({
449
+ 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 }) {
450
+ return retryIfFailed(() => request({
435
451
  method: 'POST',
436
452
  headers: {
437
453
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -458,7 +474,7 @@ function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, stor
458
474
  else {
459
475
  return response;
460
476
  }
461
- }), retryThrottledRequestMaxTimes);
477
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
462
478
  }
463
479
 
464
480
  var Status;
@@ -475,8 +491,8 @@ const isErrorResponse = (response) => {
475
491
  /**
476
492
  * Checking upload status and working with file tokens.
477
493
  */
478
- function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes } = {}) {
479
- return retryIfThrottled(() => request({
494
+ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes } = {}) {
495
+ return retryIfFailed(() => request({
480
496
  method: 'GET',
481
497
  headers: publicKey
482
498
  ? {
@@ -500,14 +516,14 @@ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, si
500
516
  else {
501
517
  return response;
502
518
  }
503
- }), retryThrottledRequestMaxTimes);
519
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
504
520
  }
505
521
 
506
522
  /**
507
523
  * Create files group.
508
524
  */
509
- function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
510
- return retryIfThrottled(() => request({
525
+ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
526
+ return retryIfFailed(() => request({
511
527
  method: 'POST',
512
528
  headers: {
513
529
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -530,14 +546,14 @@ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallb
530
546
  else {
531
547
  return response;
532
548
  }
533
- }), retryThrottledRequestMaxTimes);
549
+ }), { retryNetworkErrorMaxTimes, retryThrottledRequestMaxTimes });
534
550
  }
535
551
 
536
552
  /**
537
553
  * Get info about group.
538
554
  */
539
- function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
540
- return retryIfThrottled(() => request({
555
+ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
556
+ return retryIfFailed(() => request({
541
557
  method: 'GET',
542
558
  headers: {
543
559
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -557,14 +573,14 @@ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, s
557
573
  else {
558
574
  return response;
559
575
  }
560
- }), retryThrottledRequestMaxTimes);
576
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
561
577
  }
562
578
 
563
579
  /**
564
580
  * Returns a JSON dictionary holding file info.
565
581
  */
566
- function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
567
- return retryIfThrottled(() => request({
582
+ function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
583
+ return retryIfFailed(() => request({
568
584
  method: 'GET',
569
585
  headers: {
570
586
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
@@ -584,14 +600,14 @@ function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, sour
584
600
  else {
585
601
  return response;
586
602
  }
587
- }), retryThrottledRequestMaxTimes);
603
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
588
604
  }
589
605
 
590
606
  /**
591
607
  * Start multipart uploading.
592
608
  */
593
- function multipartStart(size, { publicKey, contentType, fileName, multipartChunkSize = defaultSettings.multipartChunkSize, baseURL = '', secureSignature, secureExpire, store, signal, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
594
- return retryIfThrottled(() => request({
609
+ 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 }) {
610
+ return retryIfFailed(() => request({
595
611
  method: 'POST',
596
612
  url: getUrl(baseURL, '/multipart/start/', { jsonerrors: 1 }),
597
613
  headers: {
@@ -620,14 +636,14 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
620
636
  response.parts = Object.keys(response.parts).map((key) => response.parts[key]);
621
637
  return response;
622
638
  }
623
- }), retryThrottledRequestMaxTimes);
639
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
624
640
  }
625
641
 
626
642
  /**
627
643
  * Complete multipart uploading.
628
644
  */
629
- function multipartUpload(part, url, { signal, onProgress }) {
630
- return request({
645
+ function multipartUpload(part, url, { signal, onProgress, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
646
+ return retryIfFailed(() => request({
631
647
  method: 'PUT',
632
648
  url,
633
649
  data: part,
@@ -644,14 +660,17 @@ function multipartUpload(part, url, { signal, onProgress }) {
644
660
  });
645
661
  return result;
646
662
  })
647
- .then(({ status }) => ({ code: status }));
663
+ .then(({ status }) => ({ code: status })), {
664
+ retryThrottledRequestMaxTimes,
665
+ retryNetworkErrorMaxTimes
666
+ });
648
667
  }
649
668
 
650
669
  /**
651
670
  * Complete multipart uploading.
652
671
  */
653
- function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL, source = 'local', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
654
- return retryIfThrottled(() => request({
672
+ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL, source = 'local', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes = defaultSettings.retryNetworkErrorMaxTimes }) {
673
+ return retryIfFailed(() => request({
655
674
  method: 'POST',
656
675
  url: getUrl(baseURL, '/multipart/complete/', { jsonerrors: 1 }),
657
676
  headers: {
@@ -671,7 +690,7 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
671
690
  else {
672
691
  return response;
673
692
  }
674
- }), retryThrottledRequestMaxTimes);
693
+ }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
675
694
  }
676
695
 
677
696
  class UploadcareFile {
@@ -738,7 +757,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
738
757
  timeoutId = setTimeout(tick, 0);
739
758
  });
740
759
 
741
- function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, signal, onProgress }) {
760
+ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
742
761
  return poll({
743
762
  check: (signal) => info(file, {
744
763
  publicKey,
@@ -747,7 +766,8 @@ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent,
747
766
  source,
748
767
  integration,
749
768
  userAgent,
750
- retryThrottledRequestMaxTimes
769
+ retryThrottledRequestMaxTimes,
770
+ retryNetworkErrorMaxTimes
751
771
  }).then((response) => {
752
772
  if (response.isReady) {
753
773
  return response;
@@ -759,7 +779,7 @@ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent,
759
779
  });
760
780
  }
761
781
 
762
- const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN, metadata }) => {
782
+ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN, metadata }) => {
763
783
  return base(file, {
764
784
  publicKey,
765
785
  fileName,
@@ -774,6 +794,7 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
774
794
  integration,
775
795
  userAgent,
776
796
  retryThrottledRequestMaxTimes,
797
+ retryNetworkErrorMaxTimes,
777
798
  metadata
778
799
  })
779
800
  .then(({ file }) => {
@@ -785,6 +806,7 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
785
806
  integration,
786
807
  userAgent,
787
808
  retryThrottledRequestMaxTimes,
809
+ retryNetworkErrorMaxTimes,
788
810
  onProgress,
789
811
  signal
790
812
  });
@@ -972,7 +994,7 @@ const preconnect = (key) => {
972
994
  getPusher(key).connect();
973
995
  };
974
996
 
975
- function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, onProgress, signal }) {
997
+ function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, onProgress, signal }) {
976
998
  return poll({
977
999
  check: (signal) => fromUrlStatus(token, {
978
1000
  publicKey,
@@ -980,6 +1002,7 @@ function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retry
980
1002
  integration,
981
1003
  userAgent,
982
1004
  retryThrottledRequestMaxTimes,
1005
+ retryNetworkErrorMaxTimes,
983
1006
  signal
984
1007
  }).then((response) => {
985
1008
  switch (response.status) {
@@ -1130,7 +1153,7 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
1130
1153
  }))
1131
1154
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1132
1155
 
1133
- const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN }) => {
1156
+ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN }) => {
1134
1157
  return info(uuid, {
1135
1158
  publicKey,
1136
1159
  baseURL,
@@ -1138,7 +1161,8 @@ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProg
1138
1161
  source,
1139
1162
  integration,
1140
1163
  userAgent,
1141
- retryThrottledRequestMaxTimes
1164
+ retryThrottledRequestMaxTimes,
1165
+ retryNetworkErrorMaxTimes
1142
1166
  })
1143
1167
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1144
1168
  .then((result) => {
@@ -1223,18 +1247,15 @@ const runWithConcurrency = (concurrency, tasks) => {
1223
1247
  });
1224
1248
  };
1225
1249
 
1226
- const uploadPartWithRetry = (chunk, url, { publicKey, onProgress, signal, integration, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
1250
+ const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes }) => multipartUpload(chunk, url, {
1227
1251
  publicKey,
1228
1252
  onProgress,
1229
1253
  signal,
1230
- integration
1231
- }).catch((error) => {
1232
- if (attempt < multipartMaxAttempts) {
1233
- return retry();
1234
- }
1235
- throw error;
1236
- }));
1237
- 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 }) => {
1254
+ integration,
1255
+ retryThrottledRequestMaxTimes,
1256
+ retryNetworkErrorMaxTimes
1257
+ });
1258
+ 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 }) => {
1238
1259
  const size = fileSize || getFileSize(file);
1239
1260
  let progressValues;
1240
1261
  const createProgressHandler = (totalChunks, chunkIdx) => {
@@ -1268,18 +1289,20 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1268
1289
  integration,
1269
1290
  userAgent,
1270
1291
  retryThrottledRequestMaxTimes,
1292
+ retryNetworkErrorMaxTimes,
1271
1293
  metadata
1272
1294
  })
1273
1295
  .then(({ uuid, parts }) => {
1274
1296
  const getChunk = prepareChunks(file, size, multipartChunkSize);
1275
1297
  return Promise.all([
1276
1298
  uuid,
1277
- runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(index), url, {
1299
+ runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPart(getChunk(index), url, {
1278
1300
  publicKey,
1279
1301
  onProgress: createProgressHandler(parts.length, index),
1280
1302
  signal,
1281
1303
  integration,
1282
- multipartMaxAttempts
1304
+ retryThrottledRequestMaxTimes,
1305
+ retryNetworkErrorMaxTimes
1283
1306
  })))
1284
1307
  ]);
1285
1308
  })
@@ -1289,7 +1312,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1289
1312
  source,
1290
1313
  integration,
1291
1314
  userAgent,
1292
- retryThrottledRequestMaxTimes
1315
+ retryThrottledRequestMaxTimes,
1316
+ retryNetworkErrorMaxTimes
1293
1317
  }))
1294
1318
  .then((fileInfo) => {
1295
1319
  if (fileInfo.isReady) {
@@ -1304,6 +1328,7 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1304
1328
  integration,
1305
1329
  userAgent,
1306
1330
  retryThrottledRequestMaxTimes,
1331
+ retryNetworkErrorMaxTimes,
1307
1332
  onProgress,
1308
1333
  signal
1309
1334
  });
@@ -1315,7 +1340,7 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1315
1340
  /**
1316
1341
  * Uploads file from provided data.
1317
1342
  */
1318
- 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 }) {
1343
+ 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 }) {
1319
1344
  if (isFileData(data)) {
1320
1345
  const fileSize = getFileSize(data);
1321
1346
  if (isMultipart(fileSize, multipartMinFileSize)) {
@@ -1323,7 +1348,6 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1323
1348
  publicKey,
1324
1349
  contentType,
1325
1350
  multipartChunkSize,
1326
- multipartMaxAttempts,
1327
1351
  fileName,
1328
1352
  baseURL,
1329
1353
  secureSignature,
@@ -1336,6 +1360,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1336
1360
  userAgent,
1337
1361
  maxConcurrentRequests,
1338
1362
  retryThrottledRequestMaxTimes,
1363
+ retryNetworkErrorMaxTimes,
1339
1364
  baseCDN,
1340
1365
  metadata
1341
1366
  });
@@ -1354,6 +1379,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1354
1379
  integration,
1355
1380
  userAgent,
1356
1381
  retryThrottledRequestMaxTimes,
1382
+ retryNetworkErrorMaxTimes,
1357
1383
  baseCDN,
1358
1384
  metadata
1359
1385
  });
@@ -1375,6 +1401,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1375
1401
  integration,
1376
1402
  userAgent,
1377
1403
  retryThrottledRequestMaxTimes,
1404
+ retryNetworkErrorMaxTimes,
1378
1405
  pusherKey,
1379
1406
  metadata
1380
1407
  });
@@ -1390,6 +1417,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1390
1417
  integration,
1391
1418
  userAgent,
1392
1419
  retryThrottledRequestMaxTimes,
1420
+ retryNetworkErrorMaxTimes,
1393
1421
  baseCDN
1394
1422
  });
1395
1423
  }
@@ -1445,7 +1473,7 @@ const isUrlArray = (data) => {
1445
1473
  return true;
1446
1474
  };
1447
1475
 
1448
- 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 }) {
1476
+ 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 }) {
1449
1477
  if (!isFileDataArray(data) && !isUrlArray(data) && !isUuidArray(data)) {
1450
1478
  throw new TypeError(`Group uploading from "${data}" is not supported`);
1451
1479
  }
@@ -1482,6 +1510,7 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1482
1510
  integration,
1483
1511
  userAgent,
1484
1512
  retryThrottledRequestMaxTimes,
1513
+ retryNetworkErrorMaxTimes,
1485
1514
  contentType,
1486
1515
  multipartChunkSize,
1487
1516
  baseCDN
@@ -1497,7 +1526,8 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1497
1526
  source,
1498
1527
  integration,
1499
1528
  userAgent,
1500
- retryThrottledRequestMaxTimes
1529
+ retryThrottledRequestMaxTimes,
1530
+ retryNetworkErrorMaxTimes
1501
1531
  })
1502
1532
  .then((groupInfo) => new UploadcareGroup(groupInfo, files))
1503
1533
  .then((group) => {
@@ -1570,4 +1600,4 @@ class UploadClient {
1570
1600
  }
1571
1601
  }
1572
1602
 
1573
- export { UploadClient, UploadClientError, UploadcareFile, UploadcareGroup, base, fromUrl, fromUrlStatus, getUserAgent$1 as getUserAgent, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadDirect, uploadFile, uploadFileGroup, uploadFromUploaded, uploadFromUrl, uploadMultipart };
1603
+ 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 };