@uploadcare/upload-client 2.0.0-alpha.8 → 2.2.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.
package/dist/index.js CHANGED
@@ -1,17 +1,18 @@
1
- import { request as request$1 } from 'http';
2
- import { request as request$2 } from 'https';
1
+ import http from 'http';
2
+ import https from 'https';
3
3
  import { parse } from 'url';
4
4
  import { Transform, Readable } from 'stream';
5
- import * as NodeFormData from 'form-data';
5
+ import NodeFormData from 'form-data';
6
6
  import { AbortController } from 'abort-controller';
7
7
  export { AbortController } from 'abort-controller';
8
- import * as WebSocket from 'ws';
8
+ import WebSocket from 'ws';
9
9
 
10
10
  class UploadClientError extends Error {
11
- constructor(message, request, response, headers) {
11
+ constructor(message, code, request, response, headers) {
12
12
  super();
13
13
  this.name = 'UploadClientError';
14
14
  this.message = message;
15
+ this.code = code;
15
16
  this.request = request;
16
17
  this.response = response;
17
18
  this.headers = headers;
@@ -82,7 +83,7 @@ const request = (params) => {
82
83
  return undefined;
83
84
  }
84
85
  })
85
- .then(length => new Promise((resolve, reject) => {
86
+ .then((length) => new Promise((resolve, reject) => {
86
87
  const isFormData = !!length;
87
88
  let aborted = false;
88
89
  const options = parse(url);
@@ -95,19 +96,19 @@ const request = (params) => {
95
96
  length || data.length;
96
97
  }
97
98
  const req = options.protocol !== 'https:'
98
- ? request$1(options)
99
- : request$2(options);
99
+ ? http.request(options)
100
+ : https.request(options);
100
101
  onCancel(signal, () => {
101
102
  aborted = true;
102
103
  req.abort();
103
104
  reject(cancelError());
104
105
  });
105
- req.on('response', res => {
106
+ req.on('response', (res) => {
106
107
  if (aborted)
107
108
  return;
108
109
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
110
  const resChunks = [];
110
- res.on('data', data => {
111
+ res.on('data', (data) => {
111
112
  resChunks.push(data);
112
113
  });
113
114
  res.on('end', () => resolve({
@@ -117,7 +118,7 @@ const request = (params) => {
117
118
  request: params
118
119
  }));
119
120
  });
120
- req.on('error', err => {
121
+ req.on('error', (err) => {
121
122
  if (aborted)
122
123
  return;
123
124
  reject(err);
@@ -136,18 +137,25 @@ const request = (params) => {
136
137
  }));
137
138
  };
138
139
 
140
+ function identity(obj) {
141
+ return obj;
142
+ }
143
+
144
+ const transformFile = identity;
139
145
  var getFormData = () => new NodeFormData();
140
146
 
147
+ const isFileTuple = (tuple) => tuple[0] === 'file';
141
148
  function buildFormData(body) {
142
149
  const formData = getFormData();
143
- const isTriple = (tuple) => tuple[0] === 'file';
144
150
  for (const tuple of body) {
145
151
  if (Array.isArray(tuple[1])) {
146
152
  // refactor this
147
- tuple[1].forEach(val => val && formData.append(tuple[0] + '[]', `${val}`));
153
+ tuple[1].forEach((val) => val && formData.append(tuple[0] + '[]', `${val}`));
148
154
  }
149
- else if (isTriple(tuple)) {
150
- formData.append(tuple[0], tuple[1], tuple[2]);
155
+ else if (isFileTuple(tuple)) {
156
+ const name = tuple[2];
157
+ const file = transformFile(tuple[1]); // lgtm[js/superfluous-trailing-arguments]
158
+ formData.append(tuple[0], file, name);
151
159
  }
152
160
  else if (tuple[1] != null) {
153
161
  formData.append(tuple[0], `${tuple[1]}`);
@@ -159,9 +167,9 @@ function buildFormData(body) {
159
167
  const serializePair = (key, value) => typeof value !== 'undefined' ? `${key}=${encodeURIComponent(value)}` : null;
160
168
  const createQuery = (query) => Object.entries(query)
161
169
  .reduce((params, [key, value]) => params.concat(Array.isArray(value)
162
- ? value.map(value => serializePair(`${key}[]`, value))
170
+ ? value.map((value) => serializePair(`${key}[]`, value))
163
171
  : serializePair(key, value)), [])
164
- .filter(x => !!x)
172
+ .filter((x) => !!x)
165
173
  .join('&');
166
174
  const getUrl = (base, path, query) => [
167
175
  base,
@@ -192,7 +200,7 @@ const defaultSettings = {
192
200
  const defaultContentType = 'application/octet-stream';
193
201
  const defaultFilename = 'original';
194
202
 
195
- var version = '1.1.2';
203
+ var version = '2.2.0';
196
204
 
197
205
  /**
198
206
  * Returns User Agent based on version and settings.
@@ -251,7 +259,7 @@ function camelizeKeys(source) {
251
259
  *
252
260
  * @param {number} ms Timeout in milliseconds.
253
261
  */
254
- const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
262
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
255
263
 
256
264
  const defaultOptions = {
257
265
  factor: 2,
@@ -273,7 +281,7 @@ function retrier(fn, options = defaultOptions) {
273
281
  return runAttempt(fn);
274
282
  }
275
283
 
276
- const REQUEST_WAS_THROTTLED_CODE = 429;
284
+ const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
277
285
  const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
278
286
  function getTimeoutFromThrottledRequest(error) {
279
287
  const { headers } = error || {};
@@ -283,9 +291,8 @@ function getTimeoutFromThrottledRequest(error) {
283
291
  }
284
292
  function retryIfThrottled(fn, retryThrottledMaxTimes) {
285
293
  return retrier(({ attempt, retry }) => fn().catch((error) => {
286
- var _a;
287
294
  if ('response' in error &&
288
- ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.statusCode) === REQUEST_WAS_THROTTLED_CODE &&
295
+ (error === null || error === void 0 ? void 0 : error.code) === REQUEST_WAS_THROTTLED_CODE &&
289
296
  attempt < retryThrottledMaxTimes) {
290
297
  return retry(getTimeoutFromThrottledRequest(error));
291
298
  }
@@ -324,7 +331,7 @@ function base(file, { publicKey, fileName, baseURL = defaultSettings.baseURL, se
324
331
  }).then(({ data, headers, request }) => {
325
332
  const response = camelizeKeys(JSON.parse(data));
326
333
  if ('error' in response) {
327
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
334
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
328
335
  }
329
336
  else {
330
337
  return response;
@@ -341,7 +348,6 @@ var TypeEnum;
341
348
  /**
342
349
  * Uploading files from URL.
343
350
  */
344
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key", "source_url", "check_URL_duplicates", "save_URL_duplicates"]}] */
345
351
  function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
346
352
  return retryIfThrottled(() => request({
347
353
  method: 'POST',
@@ -364,7 +370,7 @@ function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, stor
364
370
  }).then(({ data, headers, request }) => {
365
371
  const response = camelizeKeys(JSON.parse(data));
366
372
  if ('error' in response) {
367
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
373
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
368
374
  }
369
375
  else {
370
376
  return response;
@@ -406,7 +412,7 @@ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, si
406
412
  }).then(({ data, headers, request }) => {
407
413
  const response = camelizeKeys(JSON.parse(data));
408
414
  if ('error' in response && !isErrorResponse(response)) {
409
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
415
+ throw new UploadClientError(response.error.content, undefined, request, response, headers);
410
416
  }
411
417
  else {
412
418
  return response;
@@ -417,7 +423,6 @@ function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, si
417
423
  /**
418
424
  * Create files group.
419
425
  */
420
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key"]}] */
421
426
  function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
422
427
  return retryIfThrottled(() => request({
423
428
  method: 'POST',
@@ -437,7 +442,7 @@ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallb
437
442
  }).then(({ data, headers, request }) => {
438
443
  const response = camelizeKeys(JSON.parse(data));
439
444
  if ('error' in response) {
440
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
445
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
441
446
  }
442
447
  else {
443
448
  return response;
@@ -448,7 +453,6 @@ function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallb
448
453
  /**
449
454
  * Get info about group.
450
455
  */
451
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key", "group_id"]}] */
452
456
  function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
453
457
  return retryIfThrottled(() => request({
454
458
  method: 'GET',
@@ -465,7 +469,7 @@ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, s
465
469
  }).then(({ data, headers, request }) => {
466
470
  const response = camelizeKeys(JSON.parse(data));
467
471
  if ('error' in response) {
468
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
472
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
469
473
  }
470
474
  else {
471
475
  return response;
@@ -476,7 +480,6 @@ function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, s
476
480
  /**
477
481
  * Returns a JSON dictionary holding file info.
478
482
  */
479
- /* eslint @typescript-eslint/camelcase: [2, {allow: ["pub_key", "file_id"]}] */
480
483
  function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
481
484
  return retryIfThrottled(() => request({
482
485
  method: 'GET',
@@ -493,7 +496,7 @@ function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, sour
493
496
  }).then(({ data, headers, request }) => {
494
497
  const response = camelizeKeys(JSON.parse(data));
495
498
  if ('error' in response) {
496
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
499
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
497
500
  }
498
501
  else {
499
502
  return response;
@@ -526,11 +529,11 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
526
529
  }).then(({ data, headers, request }) => {
527
530
  const response = camelizeKeys(JSON.parse(data));
528
531
  if ('error' in response) {
529
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
532
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
530
533
  }
531
534
  else {
532
535
  // convert to array
533
- response.parts = Object.keys(response.parts).map(key => response.parts[key]);
536
+ response.parts = Object.keys(response.parts).map((key) => response.parts[key]);
534
537
  return response;
535
538
  }
536
539
  }), retryThrottledRequestMaxTimes);
@@ -547,7 +550,7 @@ function multipartUpload(part, url, { signal, onProgress }) {
547
550
  onProgress,
548
551
  signal
549
552
  })
550
- .then(result => {
553
+ .then((result) => {
551
554
  // hack for node ¯\_(ツ)_/¯
552
555
  if (onProgress)
553
556
  onProgress({ value: 1 });
@@ -575,7 +578,7 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
575
578
  }).then(({ data, headers, request }) => {
576
579
  const response = camelizeKeys(JSON.parse(data));
577
580
  if ('error' in response) {
578
- throw new UploadClientError(`[${response.error.statusCode}] ${response.error.content}`, request, response.error, headers);
581
+ throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
579
582
  }
580
583
  else {
581
584
  return response;
@@ -589,6 +592,7 @@ class UploadcareFile {
589
592
  this.size = null;
590
593
  this.isStored = null;
591
594
  this.isImage = null;
595
+ this.mimeType = null;
592
596
  this.cdnUrl = null;
593
597
  this.cdnUrlModifiers = null;
594
598
  this.originalUrl = null;
@@ -607,6 +611,7 @@ class UploadcareFile {
607
611
  this.size = fileInfo.size;
608
612
  this.isStored = fileInfo.isStored;
609
613
  this.isImage = fileInfo.isImage;
614
+ this.mimeType = fileInfo.mimeType;
610
615
  this.cdnUrl = cdnUrl;
611
616
  this.cdnUrlModifiers = cdnUrlModifiers;
612
617
  this.originalUrl = originalUrl;
@@ -626,7 +631,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
626
631
  const tick = () => {
627
632
  try {
628
633
  Promise.resolve(check(signal))
629
- .then(result => {
634
+ .then((result) => {
630
635
  if (result) {
631
636
  resolve(result);
632
637
  }
@@ -634,7 +639,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
634
639
  timeoutId = setTimeout(tick, interval);
635
640
  }
636
641
  })
637
- .catch(error => reject(error));
642
+ .catch((error) => reject(error));
638
643
  }
639
644
  catch (error) {
640
645
  reject(error);
@@ -645,7 +650,7 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((re
645
650
 
646
651
  function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, signal, onProgress }) {
647
652
  return poll({
648
- check: signal => info(file, {
653
+ check: (signal) => info(file, {
649
654
  publicKey,
650
655
  baseURL,
651
656
  signal,
@@ -653,7 +658,7 @@ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent,
653
658
  integration,
654
659
  userAgent,
655
660
  retryThrottledRequestMaxTimes
656
- }).then(response => {
661
+ }).then((response) => {
657
662
  if (response.isReady) {
658
663
  return response;
659
664
  }
@@ -692,7 +697,7 @@ const uploadFromObject = (file, { publicKey, fileName, baseURL, secureSignature,
692
697
  signal
693
698
  });
694
699
  })
695
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN }));
700
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
696
701
  };
697
702
 
698
703
  const race = (fns, { signal } = {}) => {
@@ -704,21 +709,21 @@ const race = (fns, { signal } = {}) => {
704
709
  controllers.forEach((controller, index) => index !== i && controller.abort());
705
710
  };
706
711
  onCancel(signal, () => {
707
- controllers.forEach(controller => controller.abort());
712
+ controllers.forEach((controller) => controller.abort());
708
713
  });
709
714
  return Promise.all(fns.map((fn, i) => {
710
715
  const stopRace = createStopRaceCallback(i);
711
716
  return Promise.resolve()
712
717
  .then(() => fn({ stopRace, signal: controllers[i].signal }))
713
- .then(result => {
718
+ .then((result) => {
714
719
  stopRace();
715
720
  return result;
716
721
  })
717
- .catch(error => {
722
+ .catch((error) => {
718
723
  lastError = error;
719
724
  return null;
720
725
  });
721
- })).then(results => {
726
+ })).then((results) => {
722
727
  if (winnerIndex === null) {
723
728
  throw lastError;
724
729
  }
@@ -734,7 +739,7 @@ class Events {
734
739
  }
735
740
  emit(event, data) {
736
741
  var _a;
737
- (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.forEach(fn => fn(data));
742
+ (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(data));
738
743
  }
739
744
  on(event, callback) {
740
745
  this.events[event] = this.events[event] || [];
@@ -742,7 +747,7 @@ class Events {
742
747
  }
743
748
  off(event, callback) {
744
749
  if (callback) {
745
- this.events[event] = this.events[event].filter(fn => fn !== callback);
750
+ this.events[event] = this.events[event].filter((fn) => fn !== callback);
746
751
  }
747
752
  else {
748
753
  this.events[event] = [];
@@ -775,16 +780,16 @@ class Pusher {
775
780
  if (!this.isConnected && !this.ws) {
776
781
  const pusherUrl = `wss://ws.pusherapp.com/app/${this.key}?protocol=5&client=js&version=1.12.2`;
777
782
  this.ws = new WebSocket(pusherUrl);
778
- this.ws.addEventListener('error', error => {
783
+ this.ws.addEventListener('error', (error) => {
779
784
  this.emmitter.emit('error', new Error(error.message));
780
785
  });
781
786
  this.emmitter.on('connected', () => {
782
787
  this.isConnected = true;
783
- this.queue.forEach(message => this.send(message.event, message.data));
788
+ this.queue.forEach((message) => this.send(message.event, message.data));
784
789
  this.queue = [];
785
790
  });
786
- this.ws.addEventListener('message', e => {
787
- const data = JSON.parse(e.data);
791
+ this.ws.addEventListener('message', (e) => {
792
+ const data = JSON.parse(e.data.toString());
788
793
  switch (data.event) {
789
794
  case 'pusher:connection_established': {
790
795
  this.emmitter.emit('connected', undefined);
@@ -852,7 +857,7 @@ class Pusher {
852
857
  this.send(message.event, message.data);
853
858
  }
854
859
  else {
855
- this.queue = this.queue.filter(msg => msg.data.channel !== channel);
860
+ this.queue = this.queue.filter((msg) => msg.data.channel !== channel);
856
861
  }
857
862
  if (this.subscribers === 0) {
858
863
  this.disconnect();
@@ -878,17 +883,17 @@ const preconnect = (key) => {
878
883
 
879
884
  function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, onProgress, signal }) {
880
885
  return poll({
881
- check: signal => fromUrlStatus(token, {
886
+ check: (signal) => fromUrlStatus(token, {
882
887
  publicKey,
883
888
  baseURL,
884
889
  integration,
885
890
  userAgent,
886
891
  retryThrottledRequestMaxTimes,
887
892
  signal
888
- }).then(response => {
893
+ }).then((response) => {
889
894
  switch (response.status) {
890
895
  case Status.Error: {
891
- return new UploadClientError(response.error);
896
+ return new UploadClientError(response.error, response.errorCode);
892
897
  }
893
898
  case Status.Waiting: {
894
899
  return false;
@@ -914,7 +919,7 @@ function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retry
914
919
  signal
915
920
  });
916
921
  }
917
- const pushStrategy = ({ token, pusherKey, signal, stopRace, onProgress }) => new Promise((resolve, reject) => {
922
+ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((resolve, reject) => {
918
923
  const pusher = getPusher(pusherKey);
919
924
  const unsubErrorHandler = pusher.onError(reject);
920
925
  const destroy = () => {
@@ -923,10 +928,9 @@ const pushStrategy = ({ token, pusherKey, signal, stopRace, onProgress }) => new
923
928
  };
924
929
  onCancel(signal, () => {
925
930
  destroy();
926
- reject(cancelError('pisher cancelled'));
931
+ reject(cancelError('pusher cancelled'));
927
932
  });
928
- pusher.subscribe(token, result => {
929
- stopRace();
933
+ pusher.subscribe(token, (result) => {
930
934
  switch (result.status) {
931
935
  case Status.Progress: {
932
936
  if (onProgress) {
@@ -943,7 +947,7 @@ const pushStrategy = ({ token, pusherKey, signal, stopRace, onProgress }) => new
943
947
  }
944
948
  case Status.Error: {
945
949
  destroy();
946
- reject(new UploadClientError(result.msg));
950
+ reject(new UploadClientError(result.msg, result.error_code));
947
951
  }
948
952
  }
949
953
  });
@@ -964,7 +968,12 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
964
968
  userAgent,
965
969
  retryThrottledRequestMaxTimes
966
970
  }))
967
- .then(urlResponse => {
971
+ .catch((error) => {
972
+ const pusher = getPusher(pusherKey);
973
+ pusher === null || pusher === void 0 ? void 0 : pusher.disconnect();
974
+ return Promise.reject(error);
975
+ })
976
+ .then((urlResponse) => {
968
977
  if (urlResponse.type === TypeEnum.FileInfo) {
969
978
  return urlResponse;
970
979
  }
@@ -980,22 +989,21 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
980
989
  onProgress,
981
990
  signal
982
991
  }),
983
- ({ stopRace, signal }) => pushStrategy({
992
+ ({ signal }) => pushStrategy({
984
993
  token: urlResponse.token,
985
994
  pusherKey,
986
- stopRace,
987
995
  signal,
988
996
  onProgress
989
997
  })
990
998
  ], { signal });
991
999
  }
992
1000
  })
993
- .then(result => {
1001
+ .then((result) => {
994
1002
  if (result instanceof UploadClientError)
995
1003
  throw result;
996
1004
  return result;
997
1005
  })
998
- .then(result => isReadyPoll({
1006
+ .then((result) => isReadyPoll({
999
1007
  file: result.uuid,
1000
1008
  publicKey,
1001
1009
  baseURL,
@@ -1005,7 +1013,7 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
1005
1013
  onProgress,
1006
1014
  signal
1007
1015
  }))
1008
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN }));
1016
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1009
1017
 
1010
1018
  const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN }) => {
1011
1019
  return info(uuid, {
@@ -1017,8 +1025,8 @@ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProg
1017
1025
  userAgent,
1018
1026
  retryThrottledRequestMaxTimes
1019
1027
  })
1020
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1021
- .then(result => {
1028
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1029
+ .then((result) => {
1022
1030
  // hack for node ¯\_(ツ)_/¯
1023
1031
  if (onProgress)
1024
1032
  onProgress({ value: 1 });
@@ -1067,6 +1075,16 @@ const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartM
1067
1075
  return fileSize >= multipartMinFileSize;
1068
1076
  };
1069
1077
 
1078
+ const sliceChunk = (file, index, fileSize, chunkSize) => {
1079
+ const start = chunkSize * index;
1080
+ const end = Math.min(start + chunkSize, fileSize);
1081
+ return file.slice(start, end);
1082
+ };
1083
+
1084
+ function prepareChunks(file, fileSize, chunkSize) {
1085
+ return (index) => sliceChunk(file, index, fileSize, chunkSize);
1086
+ }
1087
+
1070
1088
  const runWithConcurrency = (concurrency, tasks) => {
1071
1089
  return new Promise((resolve, reject) => {
1072
1090
  const results = [];
@@ -1090,7 +1108,7 @@ const runWithConcurrency = (concurrency, tasks) => {
1090
1108
  resolve(results);
1091
1109
  }
1092
1110
  })
1093
- .catch(error => {
1111
+ .catch((error) => {
1094
1112
  rejected = true;
1095
1113
  reject(error);
1096
1114
  });
@@ -1102,15 +1120,12 @@ const runWithConcurrency = (concurrency, tasks) => {
1102
1120
  });
1103
1121
  };
1104
1122
 
1105
- const getChunk = (file, index, fileSize, chunkSize) => {
1106
- const start = chunkSize * index;
1107
- const end = Math.min(start + chunkSize, fileSize);
1108
- return file.slice(start, end);
1109
- };
1110
- const uploadPartWithRetry = (chunk, url, { onProgress, signal, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
1123
+ const uploadPartWithRetry = (chunk, url, { publicKey, onProgress, signal, integration, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
1124
+ publicKey,
1111
1125
  onProgress,
1112
- signal
1113
- }).catch(error => {
1126
+ signal,
1127
+ integration
1128
+ }).catch((error) => {
1114
1129
  if (attempt < multipartMaxAttempts) {
1115
1130
  return retry();
1116
1131
  }
@@ -1145,14 +1160,19 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1145
1160
  userAgent,
1146
1161
  retryThrottledRequestMaxTimes
1147
1162
  })
1148
- .then(({ uuid, parts }) => Promise.all([
1149
- uuid,
1150
- runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(file, index, size, multipartChunkSize), url, {
1151
- onProgress: createProgressHandler(parts.length, index),
1152
- signal,
1153
- multipartMaxAttempts
1154
- })))
1155
- ]))
1163
+ .then(({ uuid, parts }) => {
1164
+ const getChunk = prepareChunks(file, size, multipartChunkSize);
1165
+ return Promise.all([
1166
+ uuid,
1167
+ runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(index), url, {
1168
+ publicKey,
1169
+ onProgress: createProgressHandler(parts.length, index),
1170
+ signal,
1171
+ integration,
1172
+ multipartMaxAttempts
1173
+ })))
1174
+ ]);
1175
+ })
1156
1176
  .then(([uuid]) => multipartComplete(uuid, {
1157
1177
  publicKey,
1158
1178
  baseURL,
@@ -1161,7 +1181,7 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1161
1181
  userAgent,
1162
1182
  retryThrottledRequestMaxTimes
1163
1183
  }))
1164
- .then(fileInfo => {
1184
+ .then((fileInfo) => {
1165
1185
  if (fileInfo.isReady) {
1166
1186
  return fileInfo;
1167
1187
  }
@@ -1179,13 +1199,13 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1179
1199
  });
1180
1200
  }
1181
1201
  })
1182
- .then(fileInfo => new UploadcareFile(fileInfo, { baseCDN }));
1202
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1183
1203
  };
1184
1204
 
1185
1205
  /**
1186
1206
  * Uploads file from provided data.
1187
1207
  */
1188
- function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, baseCDN = defaultSettings.baseCDN }) {
1208
+ 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 }) {
1189
1209
  if (isFileData(data)) {
1190
1210
  const fileSize = getFileSize(data);
1191
1211
  if (isMultipart(fileSize)) {
@@ -1193,6 +1213,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1193
1213
  publicKey,
1194
1214
  contentType,
1195
1215
  multipartChunkSize,
1216
+ multipartMaxAttempts,
1196
1217
  fileName,
1197
1218
  baseURL,
1198
1219
  secureSignature,
@@ -1203,6 +1224,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1203
1224
  source,
1204
1225
  integration,
1205
1226
  userAgent,
1227
+ maxConcurrentRequests,
1206
1228
  retryThrottledRequestMaxTimes,
1207
1229
  baseCDN
1208
1230
  });
@@ -1228,6 +1250,9 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1228
1250
  publicKey,
1229
1251
  fileName,
1230
1252
  baseURL,
1253
+ baseCDN,
1254
+ checkForUrlDuplicates,
1255
+ saveUrlForRecurrentUploads,
1231
1256
  secureSignature,
1232
1257
  secureExpire,
1233
1258
  store,
@@ -1237,7 +1262,7 @@ function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseU
1237
1262
  integration,
1238
1263
  userAgent,
1239
1264
  retryThrottledRequestMaxTimes,
1240
- baseCDN
1265
+ pusherKey
1241
1266
  });
1242
1267
  }
1243
1268
  if (isUuid(data)) {
@@ -1264,8 +1289,7 @@ class UploadcareGroup {
1264
1289
  this.filesCount = groupInfo.filesCount;
1265
1290
  this.totalSize = Object.values(groupInfo.files).reduce((acc, file) => acc + file.size, 0);
1266
1291
  this.isStored = !!groupInfo.datetimeStored;
1267
- this.isImage = !!Object.values(groupInfo.files).filter(file => file.isImage)
1268
- .length;
1292
+ this.isImage = !!Object.values(groupInfo.files).filter((file) => file.isImage).length;
1269
1293
  this.cdnUrl = groupInfo.cdnUrl;
1270
1294
  this.files = files;
1271
1295
  this.createdAt = groupInfo.datetimeCreated;
@@ -1341,8 +1365,8 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1341
1365
  contentType,
1342
1366
  multipartChunkSize,
1343
1367
  baseCDN
1344
- }))).then(files => {
1345
- const uuids = files.map(file => file.uuid);
1368
+ }))).then((files) => {
1369
+ const uuids = files.map((file) => file.uuid);
1346
1370
  const addDefaultEffects = (file) => {
1347
1371
  const cdnUrlModifiers = defaultEffects ? `-/${defaultEffects}` : null;
1348
1372
  const cdnUrl = `${file.urlBase}${cdnUrlModifiers || ''}`;
@@ -1361,7 +1385,7 @@ function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.
1361
1385
  integration,
1362
1386
  userAgent,
1363
1387
  retryThrottledRequestMaxTimes
1364
- }).then(groupInfo => new UploadcareGroup(groupInfo, filesInGroup));
1388
+ }).then((groupInfo) => new UploadcareGroup(groupInfo, filesInGroup));
1365
1389
  });
1366
1390
  }
1367
1391
 
@@ -1425,4 +1449,4 @@ class UploadClient {
1425
1449
  }
1426
1450
  }
1427
1451
 
1428
- export { UploadClient, base, fromUrl, fromUrlStatus, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadFile, uploadFileGroup };
1452
+ export { UploadClient, UploadClientError, UploadcareFile, UploadcareGroup, base, fromUrl, fromUrlStatus, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadFromObject as uploadBase, uploadFile, uploadFileGroup, uploadFromUploaded, uploadFromUrl, uploadMultipart };