@uploadcare/upload-client 2.0.0-alpha.9 → 2.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.
@@ -1,8 +1,9 @@
1
1
  class UploadClientError extends Error {
2
- constructor(message, request, response, headers) {
2
+ constructor(message, code, request, response, headers) {
3
3
  super();
4
4
  this.name = 'UploadClientError';
5
5
  this.message = message;
6
+ this.code = code;
6
7
  this.request = request;
7
8
  this.response = response;
8
9
  this.headers = headers;
@@ -32,7 +33,7 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
32
33
  let aborted = false;
33
34
  xhr.open(requestMethod, url);
34
35
  if (headers) {
35
- Object.entries(headers).forEach(entry => {
36
+ Object.entries(headers).forEach((entry) => {
36
37
  const [key, value] = entry;
37
38
  typeof value !== 'undefined' &&
38
39
  !Array.isArray(value) &&
@@ -104,18 +105,25 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
104
105
  }
105
106
  });
106
107
 
108
+ function identity(obj) {
109
+ return obj;
110
+ }
111
+
112
+ const transformFile = identity;
107
113
  var getFormData = () => new FormData();
108
114
 
115
+ const isFileTuple = (tuple) => tuple[0] === 'file';
109
116
  function buildFormData(body) {
110
117
  const formData = getFormData();
111
- const isTriple = (tuple) => tuple[0] === 'file';
112
118
  for (const tuple of body) {
113
119
  if (Array.isArray(tuple[1])) {
114
120
  // refactor this
115
- tuple[1].forEach(val => val && formData.append(tuple[0] + '[]', `${val}`));
121
+ tuple[1].forEach((val) => val && formData.append(tuple[0] + '[]', `${val}`));
116
122
  }
117
- else if (isTriple(tuple)) {
118
- formData.append(tuple[0], tuple[1], tuple[2]);
123
+ else if (isFileTuple(tuple)) {
124
+ const name = tuple[2];
125
+ const file = transformFile(tuple[1]); // lgtm[js/superfluous-trailing-arguments]
126
+ formData.append(tuple[0], file, name);
119
127
  }
120
128
  else if (tuple[1] != null) {
121
129
  formData.append(tuple[0], `${tuple[1]}`);
@@ -127,9 +135,9 @@ function buildFormData(body) {
127
135
  const serializePair = (key, value) => typeof value !== 'undefined' ? `${key}=${encodeURIComponent(value)}` : null;
128
136
  const createQuery = (query) => Object.entries(query)
129
137
  .reduce((params, [key, value]) => params.concat(Array.isArray(value)
130
- ? value.map(value => serializePair(`${key}[]`, value))
138
+ ? value.map((value) => serializePair(`${key}[]`, value))
131
139
  : serializePair(key, value)), [])
132
- .filter(x => !!x)
140
+ .filter((x) => !!x)
133
141
  .join('&');
134
142
  const getUrl = (base, path, query) => [
135
143
  base,
@@ -160,7 +168,7 @@ const defaultSettings = {
160
168
  const defaultContentType = 'application/octet-stream';
161
169
  const defaultFilename = 'original';
162
170
 
163
- var version = '1.1.2';
171
+ var version = '2.0.0';
164
172
 
165
173
  /**
166
174
  * Returns User Agent based on version and settings.
@@ -219,7 +227,7 @@ function camelizeKeys(source) {
219
227
  *
220
228
  * @param {number} ms Timeout in milliseconds.
221
229
  */
222
- const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
230
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
223
231
 
224
232
  const defaultOptions = {
225
233
  factor: 2,
@@ -241,7 +249,7 @@ function retrier(fn, options = defaultOptions) {
241
249
  return runAttempt(fn);
242
250
  }
243
251
 
244
- const REQUEST_WAS_THROTTLED_CODE = 429;
252
+ const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
245
253
  const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
246
254
  function getTimeoutFromThrottledRequest(error) {
247
255
  const { headers } = error || {};
@@ -251,9 +259,8 @@ function getTimeoutFromThrottledRequest(error) {
251
259
  }
252
260
  function retryIfThrottled(fn, retryThrottledMaxTimes) {
253
261
  return retrier(({ attempt, retry }) => fn().catch((error) => {
254
- var _a;
255
262
  if ('response' in error &&
256
- ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.statusCode) === REQUEST_WAS_THROTTLED_CODE &&
263
+ (error === null || error === void 0 ? void 0 : error.code) === REQUEST_WAS_THROTTLED_CODE &&
257
264
  attempt < retryThrottledMaxTimes) {
258
265
  return retry(getTimeoutFromThrottledRequest(error));
259
266
  }
@@ -292,7 +299,7 @@ function base(file, { publicKey, fileName, baseURL = defaultSettings.baseURL, se
292
299
  }).then(({ data, headers, request }) => {
293
300
  const response = camelizeKeys(JSON.parse(data));
294
301
  if ('error' in response) {
295
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
302
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
296
303
  }
297
304
  else {
298
305
  return response;
@@ -309,7 +316,6 @@ var TypeEnum;
309
316
  /**
310
317
  * Uploading files from URL.
311
318
  */
312
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key", "source_url", "check_URL_duplicates", "save_URL_duplicates"]}] */
313
319
  function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
314
320
  return retryIfThrottled(() => request({
315
321
  method: 'POST',
@@ -332,7 +338,7 @@ function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, stor
332
338
  }).then(({ data, headers, request }) => {
333
339
  const response = camelizeKeys(JSON.parse(data));
334
340
  if ('error' in response) {
335
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
341
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
336
342
  }
337
343
  else {
338
344
  return response;
@@ -374,7 +380,7 @@ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, si
374
380
  }).then(({ data, headers, request }) => {
375
381
  const response = camelizeKeys(JSON.parse(data));
376
382
  if ('error' in response && !isErrorResponse(response)) {
377
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
383
+ throw new UploadClientError(response.error.content, undefined, request, response, headers);
378
384
  }
379
385
  else {
380
386
  return response;
@@ -385,7 +391,6 @@ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, si
385
391
  /**
386
392
  * Create files group.
387
393
  */
388
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key"]}] */
389
394
  function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
390
395
  return retryIfThrottled(() => request({
391
396
  method: 'POST',
@@ -405,7 +410,7 @@ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallb
405
410
  }).then(({ data, headers, request }) => {
406
411
  const response = camelizeKeys(JSON.parse(data));
407
412
  if ('error' in response) {
408
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
413
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
409
414
  }
410
415
  else {
411
416
  return response;
@@ -416,7 +421,6 @@ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallb
416
421
  /**
417
422
  * Get info about group.
418
423
  */
419
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key", "group_id"]}] */
420
424
  function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
421
425
  return retryIfThrottled(() => request({
422
426
  method: 'GET',
@@ -433,7 +437,7 @@ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, s
433
437
  }).then(({ data, headers, request }) => {
434
438
  const response = camelizeKeys(JSON.parse(data));
435
439
  if ('error' in response) {
436
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
440
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
437
441
  }
438
442
  else {
439
443
  return response;
@@ -444,7 +448,6 @@ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, s
444
448
  /**
445
449
  * Returns a JSON dictionary holding file info.
446
450
  */
447
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key", "file_id"]}] */
448
451
  function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
449
452
  return retryIfThrottled(() => request({
450
453
  method: 'GET',
@@ -461,7 +464,7 @@ function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, sour
461
464
  }).then(({ data, headers, request }) => {
462
465
  const response = camelizeKeys(JSON.parse(data));
463
466
  if ('error' in response) {
464
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
467
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
465
468
  }
466
469
  else {
467
470
  return response;
@@ -494,11 +497,11 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
494
497
  }).then(({ data, headers, request }) => {
495
498
  const response = camelizeKeys(JSON.parse(data));
496
499
  if ('error' in response) {
497
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
500
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
498
501
  }
499
502
  else {
500
503
  // convert to array
501
- response.parts = Object.keys(response.parts).map(key => response.parts[key]);
504
+ response.parts = Object.keys(response.parts).map((key) => response.parts[key]);
502
505
  return response;
503
506
  }
504
507
  }), retryThrottledRequestMaxTimes);
@@ -515,7 +518,7 @@ function multipartUpload(part, url, { signal, onProgress }) {
515
518
  onProgress,
516
519
  signal
517
520
  })
518
- .then(result => {
521
+ .then((result) => {
519
522
  // hack for node ¯\_(ツ)_/¯
520
523
  if (onProgress)
521
524
  onProgress({ value: 1 });
@@ -543,7 +546,7 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
543
546
  }).then(({ data, headers, request }) => {
544
547
  const response = camelizeKeys(JSON.parse(data));
545
548
  if ('error' in response) {
546
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
549
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
547
550
  }
548
551
  else {
549
552
  return response;
@@ -557,6 +560,7 @@ class UploadcareFile {
557
560
  this.size = null;
558
561
  this.isStored = null;
559
562
  this.isImage = null;
563
+ this.mimeType = null;
560
564
  this.cdnUrl = null;
561
565
  this.cdnUrlModifiers = null;
562
566
  this.originalUrl = null;
@@ -575,6 +579,7 @@ class UploadcareFile {
575
579
  this.size = fileInfo.size;
576
580
  this.isStored = fileInfo.isStored;
577
581
  this.isImage = fileInfo.isImage;
582
+ this.mimeType = fileInfo.mimeType;
578
583
  this.cdnUrl = cdnUrl;
579
584
  this.cdnUrlModifiers = cdnUrlModifiers;
580
585
  this.originalUrl = originalUrl;
@@ -594,7 +599,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
594
599
  const tick = () => {
595
600
  try {
596
601
  Promise.resolve(check(signal))
597
- .then(result => {
602
+ .then((result) => {
598
603
  if (result) {
599
604
  resolve(result);
600
605
  }
@@ -602,7 +607,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
602
607
  timeoutId = setTimeout(tick, interval);
603
608
  }
604
609
  })
605
- .catch(error => reject(error));
610
+ .catch((error) => reject(error));
606
611
  }
607
612
  catch (error) {
608
613
  reject(error);
@@ -613,7 +618,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
613
618
 
614
619
  function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, signal, onProgress }) {
615
620
  return poll({
616
- check: signal => info(file, {
621
+ check: (signal) => info(file, {
617
622
  publicKey,
618
623
  baseURL,
619
624
  signal,
@@ -621,7 +626,7 @@ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent,
621
626
  integration,
622
627
  userAgent,
623
628
  retryThrottledRequestMaxTimes
624
- }).then(response => {
629
+ }).then((response) => {
625
630
  if (response.isReady) {
626
631
  return response;
627
632
  }
@@ -660,7 +665,7 @@ const uploadFromObject = (file, { publicKey, fileName, baseURL, secureSignature,
660
665
  signal
661
666
  });
662
667
  })
663
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN }));
668
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
664
669
  };
665
670
 
666
671
  /*globals self, window */
@@ -680,21 +685,21 @@ const race = (fns, { signal } = {}) => {
680
685
  controllers.forEach((controller, index) => index !== i && controller.abort());
681
686
  };
682
687
  onCancel(signal, () => {
683
- controllers.forEach(controller => controller.abort());
688
+ controllers.forEach((controller) => controller.abort());
684
689
  });
685
690
  return Promise.all(fns.map((fn, i) => {
686
691
  const stopRace = createStopRaceCallback(i);
687
692
  return Promise.resolve()
688
693
  .then(() => fn({ stopRace, signal: controllers[i].signal }))
689
- .then(result => {
694
+ .then((result) => {
690
695
  stopRace();
691
696
  return result;
692
697
  })
693
- .catch(error => {
698
+ .catch((error) => {
694
699
  lastError = error;
695
700
  return null;
696
701
  });
697
- })).then(results => {
702
+ })).then((results) => {
698
703
  if (winnerIndex === null) {
699
704
  throw lastError;
700
705
  }
@@ -712,7 +717,7 @@ class Events {
712
717
  }
713
718
  emit(event, data) {
714
719
  var _a;
715
- (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.forEach(fn => fn(data));
720
+ (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(data));
716
721
  }
717
722
  on(event, callback) {
718
723
  this.events[event] = this.events[event] || [];
@@ -720,7 +725,7 @@ class Events {
720
725
  }
721
726
  off(event, callback) {
722
727
  if (callback) {
723
- this.events[event] = this.events[event].filter(fn => fn !== callback);
728
+ this.events[event] = this.events[event].filter((fn) => fn !== callback);
724
729
  }
725
730
  else {
726
731
  this.events[event] = [];
@@ -753,16 +758,16 @@ class Pusher {
753
758
  if (!this.isConnected && !this.ws) {
754
759
  const pusherUrl = `wss://ws.pusherapp.com/app/${this.key}?protocol=5&client=js&version=1.12.2`;
755
760
  this.ws = new WebSocket(pusherUrl);
756
- this.ws.addEventListener('error', error => {
761
+ this.ws.addEventListener('error', (error) => {
757
762
  this.emmitter.emit('error', new Error(error.message));
758
763
  });
759
764
  this.emmitter.on('connected', () => {
760
765
  this.isConnected = true;
761
- this.queue.forEach(message => this.send(message.event, message.data));
766
+ this.queue.forEach((message) => this.send(message.event, message.data));
762
767
  this.queue = [];
763
768
  });
764
- this.ws.addEventListener('message', e => {
765
- const data = JSON.parse(e.data);
769
+ this.ws.addEventListener('message', (e) => {
770
+ const data = JSON.parse(e.data.toString());
766
771
  switch (data.event) {
767
772
  case 'pusher:connection_established': {
768
773
  this.emmitter.emit('connected', undefined);
@@ -830,7 +835,7 @@ class Pusher {
830
835
  this.send(message.event, message.data);
831
836
  }
832
837
  else {
833
- this.queue = this.queue.filter(msg => msg.data.channel !== channel);
838
+ this.queue = this.queue.filter((msg) => msg.data.channel !== channel);
834
839
  }
835
840
  if (this.subscribers === 0) {
836
841
  this.disconnect();
@@ -856,17 +861,17 @@ const preconnect = (key) => {
856
861
 
857
862
  function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, onProgress, signal }) {
858
863
  return poll({
859
- check: signal => fromUrlStatus(token, {
864
+ check: (signal) => fromUrlStatus(token, {
860
865
  publicKey,
861
866
  baseURL,
862
867
  integration,
863
868
  userAgent,
864
869
  retryThrottledRequestMaxTimes,
865
870
  signal
866
- }).then(response => {
871
+ }).then((response) => {
867
872
  switch (response.status) {
868
873
  case Status.Error: {
869
- return new UploadClientError(response.error);
874
+ return new UploadClientError(response.error, response.errorCode);
870
875
  }
871
876
  case Status.Waiting: {
872
877
  return false;
@@ -892,7 +897,7 @@ function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retry
892
897
  signal
893
898
  });
894
899
  }
895
- const pushStrategy = ({ token, pusherKey, signal, stopRace, onProgress }) => new Promise((resolve, reject) => {
900
+ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((resolve, reject) => {
896
901
  const pusher = getPusher(pusherKey);
897
902
  const unsubErrorHandler = pusher.onError(reject);
898
903
  const destroy = () => {
@@ -901,10 +906,9 @@ const pushStrategy = ({ token, pusherKey, signal, stopRace, onProgress }) => new
901
906
  };
902
907
  onCancel(signal, () => {
903
908
  destroy();
904
- reject(cancelError('pisher cancelled'));
909
+ reject(cancelError('pusher cancelled'));
905
910
  });
906
- pusher.subscribe(token, result => {
907
- stopRace();
911
+ pusher.subscribe(token, (result) => {
908
912
  switch (result.status) {
909
913
  case Status.Progress: {
910
914
  if (onProgress) {
@@ -921,7 +925,7 @@ const pushStrategy = ({ token, pusherKey, signal, stopRace, onProgress }) => new
921
925
  }
922
926
  case Status.Error: {
923
927
  destroy();
924
- reject(new UploadClientError(result.msg));
928
+ reject(new UploadClientError(result.msg, result.error_code));
925
929
  }
926
930
  }
927
931
  });
@@ -942,7 +946,12 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
942
946
  userAgent,
943
947
  retryThrottledRequestMaxTimes
944
948
  }))
945
- .then(urlResponse => {
949
+ .catch((error) => {
950
+ const pusher = getPusher(pusherKey);
951
+ pusher === null || pusher === void 0 ? void 0 : pusher.disconnect();
952
+ return Promise.reject(error);
953
+ })
954
+ .then((urlResponse) => {
946
955
  if (urlResponse.type === TypeEnum.FileInfo) {
947
956
  return urlResponse;
948
957
  }
@@ -958,22 +967,21 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
958
967
  onProgress,
959
968
  signal
960
969
  }),
961
- ({ stopRace, signal }) => pushStrategy({
970
+ ({ signal }) => pushStrategy({
962
971
  token: urlResponse.token,
963
972
  pusherKey,
964
- stopRace,
965
973
  signal,
966
974
  onProgress
967
975
  })
968
976
  ], { signal });
969
977
  }
970
978
  })
971
- .then(result => {
979
+ .then((result) => {
972
980
  if (result instanceof UploadClientError)
973
981
  throw result;
974
982
  return result;
975
983
  })
976
- .then(result => isReadyPoll({
984
+ .then((result) => isReadyPoll({
977
985
  file: result.uuid,
978
986
  publicKey,
979
987
  baseURL,
@@ -983,7 +991,7 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
983
991
  onProgress,
984
992
  signal
985
993
  }))
986
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN }));
994
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
987
995
 
988
996
  const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN }) => {
989
997
  return info(uuid, {
@@ -995,8 +1003,8 @@ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProg
995
1003
  userAgent,
996
1004
  retryThrottledRequestMaxTimes
997
1005
  })
998
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN, fileName }))
999
- .then(result => {
1006
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1007
+ .then((result) => {
1000
1008
  // hack for node ¯\_(ツ)_/¯
1001
1009
  if (onProgress)
1002
1010
  onProgress({ value: 1 });
@@ -1045,6 +1053,16 @@ const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartM
1045
1053
  return fileSize >= multipartMinFileSize;
1046
1054
  };
1047
1055
 
1056
+ const sliceChunk = (file, index, fileSize, chunkSize) => {
1057
+ const start = chunkSize * index;
1058
+ const end = Math.min(start + chunkSize, fileSize);
1059
+ return file.slice(start, end);
1060
+ };
1061
+
1062
+ function prepareChunks(file, fileSize, chunkSize) {
1063
+ return (index) => sliceChunk(file, index, fileSize, chunkSize);
1064
+ }
1065
+
1048
1066
  const runWithConcurrency = (concurrency, tasks) => {
1049
1067
  return new Promise((resolve, reject) => {
1050
1068
  const results = [];
@@ -1068,7 +1086,7 @@ const runWithConcurrency = (concurrency, tasks) => {
1068
1086
  resolve(results);
1069
1087
  }
1070
1088
  })
1071
- .catch(error => {
1089
+ .catch((error) => {
1072
1090
  rejected = true;
1073
1091
  reject(error);
1074
1092
  });
@@ -1080,15 +1098,12 @@ const runWithConcurrency = (concurrency, tasks) => {
1080
1098
  });
1081
1099
  };
1082
1100
 
1083
- const getChunk = (file, index, fileSize, chunkSize) => {
1084
- const start = chunkSize * index;
1085
- const end = Math.min(start + chunkSize, fileSize);
1086
- return file.slice(start, end);
1087
- };
1088
- const uploadPartWithRetry = (chunk, url, { onProgress, signal, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
1101
+ const uploadPartWithRetry = (chunk, url, { publicKey, onProgress, signal, integration, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
1102
+ publicKey,
1089
1103
  onProgress,
1090
- signal
1091
- }).catch(error => {
1104
+ signal,
1105
+ integration
1106
+ }).catch((error) => {
1092
1107
  if (attempt < multipartMaxAttempts) {
1093
1108
  return retry();
1094
1109
  }
@@ -1123,14 +1138,19 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1123
1138
  userAgent,
1124
1139
  retryThrottledRequestMaxTimes
1125
1140
  })
1126
- .then(({ uuid, parts }) => Promise.all([
1127
- uuid,
1128
- runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(file, index, size, multipartChunkSize), url, {
1129
- onProgress: createProgressHandler(parts.length, index),
1130
- signal,
1131
- multipartMaxAttempts
1132
- })))
1133
- ]))
1141
+ .then(({ uuid, parts }) => {
1142
+ const getChunk = prepareChunks(file, size, multipartChunkSize);
1143
+ return Promise.all([
1144
+ uuid,
1145
+ runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(index), url, {
1146
+ publicKey,
1147
+ onProgress: createProgressHandler(parts.length, index),
1148
+ signal,
1149
+ integration,
1150
+ multipartMaxAttempts
1151
+ })))
1152
+ ]);
1153
+ })
1134
1154
  .then(([uuid]) => multipartComplete(uuid, {
1135
1155
  publicKey,
1136
1156
  baseURL,
@@ -1139,7 +1159,7 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1139
1159
  userAgent,
1140
1160
  retryThrottledRequestMaxTimes
1141
1161
  }))
1142
- .then(fileInfo => {
1162
+ .then((fileInfo) => {
1143
1163
  if (fileInfo.isReady) {
1144
1164
  return fileInfo;
1145
1165
  }
@@ -1157,13 +1177,13 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1157
1177
  });
1158
1178
  }
1159
1179
  })
1160
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN }));
1180
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1161
1181
  };
1162
1182
 
1163
1183
  /**
1164
1184
  * Uploads file from provided data.
1165
1185
  */
1166
- function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, baseCDN = defaultSettings.baseCDN }) {
1186
+ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize, multipartMaxAttempts, maxConcurrentRequests, baseCDN = defaultSettings.baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, pusherKey }) {
1167
1187
  if (isFileData(data)) {
1168
1188
  const fileSize = getFileSize(data);
1169
1189
  if (isMultipart(fileSize)) {
@@ -1171,6 +1191,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1171
1191
  publicKey,
1172
1192
  contentType,
1173
1193
  multipartChunkSize,
1194
+ multipartMaxAttempts,
1174
1195
  fileName,
1175
1196
  baseURL,
1176
1197
  secureSignature,
@@ -1181,6 +1202,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1181
1202
  source,
1182
1203
  integration,
1183
1204
  userAgent,
1205
+ maxConcurrentRequests,
1184
1206
  retryThrottledRequestMaxTimes,
1185
1207
  baseCDN
1186
1208
  });
@@ -1206,6 +1228,9 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1206
1228
  publicKey,
1207
1229
  fileName,
1208
1230
  baseURL,
1231
+ baseCDN,
1232
+ checkForUrlDuplicates,
1233
+ saveUrlForRecurrentUploads,
1209
1234
  secureSignature,
1210
1235
  secureExpire,
1211
1236
  store,
@@ -1215,7 +1240,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1215
1240
  integration,
1216
1241
  userAgent,
1217
1242
  retryThrottledRequestMaxTimes,
1218
- baseCDN
1243
+ pusherKey
1219
1244
  });
1220
1245
  }
1221
1246
  if (isUuid(data)) {
@@ -1242,8 +1267,7 @@ class UploadcareGroup {
1242
1267
  this.filesCount = groupInfo.filesCount;
1243
1268
  this.totalSize = Object.values(groupInfo.files).reduce((acc, file) => acc + file.size, 0);
1244
1269
  this.isStored = !!groupInfo.datetimeStored;
1245
- this.isImage = !!Object.values(groupInfo.files).filter(file => file.isImage)
1246
- .length;
1270
+ this.isImage = !!Object.values(groupInfo.files).filter((file) => file.isImage).length;
1247
1271
  this.cdnUrl = groupInfo.cdnUrl;
1248
1272
  this.files = files;
1249
1273
  this.createdAt = groupInfo.datetimeCreated;
@@ -1319,8 +1343,8 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1319
1343
  contentType,
1320
1344
  multipartChunkSize,
1321
1345
  baseCDN
1322
- }))).then(files => {
1323
- const uuids = files.map(file => file.uuid);
1346
+ }))).then((files) => {
1347
+ const uuids = files.map((file) => file.uuid);
1324
1348
  const addDefaultEffects = (file) => {
1325
1349
  const cdnUrlModifiers = defaultEffects ? `-/${defaultEffects}` : null;
1326
1350
  const cdnUrl = `${file.urlBase}${cdnUrlModifiers || ''}`;
@@ -1339,7 +1363,7 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1339
1363
  integration,
1340
1364
  userAgent,
1341
1365
  retryThrottledRequestMaxTimes
1342
- }).then(groupInfo => new UploadcareGroup(groupInfo, filesInGroup));
1366
+ }).then((groupInfo) => new UploadcareGroup(groupInfo, filesInGroup));
1343
1367
  });
1344
1368
  }
1345
1369
 
@@ -1403,4 +1427,4 @@ class UploadClient {
1403
1427
  }
1404
1428
  }
1405
1429
 
1406
- export { AbortController, UploadClient, base, fromUrl, fromUrlStatus, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadFile, uploadFileGroup };
1430
+ export { AbortController, UploadClient, base, fromUrl, fromUrlStatus, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadFromObject as uploadBase, uploadFile, uploadFileGroup, uploadFromUploaded, uploadFromUrl, uploadMultipart };