@uploadcare/upload-client 2.2.1-alpha.0 → 3.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.
package/dist/index.cjs CHANGED
@@ -112,7 +112,10 @@ var ProgressEmitter = /** @class */ (function (_super) {
112
112
  }
113
113
  ProgressEmitter.prototype._transform = function (chunk, encoding, callback) {
114
114
  this._position += chunk.length;
115
- this._onprogress({ value: this._position / this.size });
115
+ this._onprogress({
116
+ isComputable: true,
117
+ value: this._position / this.size
118
+ });
116
119
  callback(null, chunk);
117
120
  };
118
121
  return ProgressEmitter;
@@ -215,28 +218,80 @@ function identity(obj) {
215
218
  var transformFile = identity;
216
219
  var getFormData = (function () { return new NodeFormData__default["default"](); });
217
220
 
218
- var isFileTuple = function (tuple) {
219
- return tuple[0] === 'file';
221
+ /**
222
+ * FileData type guard.
223
+ */
224
+ var isFileData = function (data) {
225
+ return (data !== undefined &&
226
+ ((typeof Blob !== 'undefined' && data instanceof Blob) ||
227
+ (typeof File !== 'undefined' && data instanceof File) ||
228
+ (typeof Buffer !== 'undefined' && data instanceof Buffer)));
220
229
  };
221
- function buildFormData(body) {
222
- var formData = getFormData();
223
- var _loop_1 = function (tuple) {
224
- if (Array.isArray(tuple[1])) {
225
- // refactor this
226
- tuple[1].forEach(function (val) { return val && formData.append(tuple[0] + '[]', "" + val); });
227
- }
228
- else if (isFileTuple(tuple)) {
229
- var name_1 = tuple[2];
230
- var file = transformFile(tuple[1]); // lgtm[js/superfluous-trailing-arguments]
231
- formData.append(tuple[0], file, name_1);
232
- }
233
- else if (tuple[1] != null) {
234
- formData.append(tuple[0], "" + tuple[1]);
230
+ /**
231
+ * Uuid type guard.
232
+ */
233
+ var isUuid = function (data) {
234
+ var UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
235
+ var regExp = new RegExp(UUID_REGEX);
236
+ return !isFileData(data) && regExp.test(data);
237
+ };
238
+ /**
239
+ * Url type guard.
240
+ *
241
+ * @param {NodeFile | BrowserFile | Url | Uuid} data
242
+ */
243
+ var isUrl = function (data) {
244
+ var URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
245
+ var regExp = new RegExp(URL_REGEX);
246
+ return !isFileData(data) && regExp.test(data);
247
+ };
248
+
249
+ var isSimpleValue = function (value) {
250
+ return (typeof value === 'string' ||
251
+ typeof value === 'number' ||
252
+ typeof value === 'undefined');
253
+ };
254
+ var isObjectValue = function (value) {
255
+ return !!value && typeof value === 'object' && !Array.isArray(value);
256
+ };
257
+ var isFileValue = function (value) {
258
+ return !!value &&
259
+ typeof value === 'object' &&
260
+ 'data' in value &&
261
+ isFileData(value.data);
262
+ };
263
+ function collectParams(params, inputKey, inputValue) {
264
+ if (isFileValue(inputValue)) {
265
+ var name_1 = inputValue.name;
266
+ var file = transformFile(inputValue.data); // lgtm [js/superfluous-trailing-arguments]
267
+ params.push(name_1 ? [inputKey, file, name_1] : [inputKey, file]);
268
+ }
269
+ else if (isObjectValue(inputValue)) {
270
+ for (var _i = 0, _a = Object.entries(inputValue); _i < _a.length; _i++) {
271
+ var _b = _a[_i], key = _b[0], value = _b[1];
272
+ if (typeof value !== 'undefined') {
273
+ params.push([inputKey + "[" + key + "]", String(value)]);
274
+ }
235
275
  }
236
- };
237
- for (var _i = 0, body_1 = body; _i < body_1.length; _i++) {
238
- var tuple = body_1[_i];
239
- _loop_1(tuple);
276
+ }
277
+ else if (isSimpleValue(inputValue) && inputValue) {
278
+ params.push([inputKey, inputValue.toString()]);
279
+ }
280
+ }
281
+ function getFormDataParams(options) {
282
+ var params = [];
283
+ for (var _i = 0, _a = Object.entries(options); _i < _a.length; _i++) {
284
+ var _b = _a[_i], key = _b[0], value = _b[1];
285
+ collectParams(params, key, value);
286
+ }
287
+ return params;
288
+ }
289
+ function buildFormData(options) {
290
+ var formData = getFormData();
291
+ var params = getFormDataParams(options);
292
+ for (var _i = 0, params_1 = params; _i < params_1.length; _i++) {
293
+ var param = params_1[_i];
294
+ formData.append.apply(formData, param);
240
295
  }
241
296
  return formData;
242
297
  }
@@ -244,13 +299,26 @@ function buildFormData(body) {
244
299
  var serializePair = function (key, value) {
245
300
  return typeof value !== 'undefined' ? key + "=" + encodeURIComponent(value) : null;
246
301
  };
302
+ // TODO: generalize value transforming logic and use it here and inside `buildFormData`
247
303
  var createQuery = function (query) {
248
304
  return Object.entries(query)
249
305
  .reduce(function (params, _a) {
250
306
  var key = _a[0], value = _a[1];
251
- return params.concat(Array.isArray(value)
252
- ? value.map(function (value) { return serializePair(key + "[]", value); })
253
- : serializePair(key, value));
307
+ var param;
308
+ if (typeof value === 'object' && !Array.isArray(value)) {
309
+ param = Object.entries(value)
310
+ .filter(function (entry) { return typeof entry[1] !== 'undefined'; })
311
+ .map(function (entry) {
312
+ return serializePair(key + "[" + entry[0] + "]", String(entry[1]));
313
+ });
314
+ }
315
+ else if (Array.isArray(value)) {
316
+ param = value.map(function (val) { return serializePair(key + "[]", val); });
317
+ }
318
+ else {
319
+ param = serializePair(key, value);
320
+ }
321
+ return params.concat(param);
254
322
  }, [])
255
323
  .filter(function (x) { return !!x; })
256
324
  .join('&');
@@ -286,7 +354,7 @@ var defaultSettings = {
286
354
  var defaultContentType = 'application/octet-stream';
287
355
  var defaultFilename = 'original';
288
356
 
289
- var version = '2.2.0';
357
+ var version = '3.1.0';
290
358
 
291
359
  /**
292
360
  * Returns User Agent based on version and settings.
@@ -397,12 +465,16 @@ function retryIfThrottled(fn, retryThrottledMaxTimes) {
397
465
  });
398
466
  }
399
467
 
468
+ function getStoreValue(store) {
469
+ return typeof store === 'undefined' ? 'auto' : store ? '1' : '0';
470
+ }
471
+
400
472
  /**
401
473
  * Performs file uploading request to Uploadcare Upload API.
402
474
  * Can be canceled and has progress.
403
475
  */
404
476
  function base(file, _a) {
405
- var publicKey = _a.publicKey, fileName = _a.fileName, _b = _a.baseURL, baseURL = _b === void 0 ? defaultSettings.baseURL : _b, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, _c = _a.source, source = _c === void 0 ? 'local' : _c, integration = _a.integration, userAgent = _a.userAgent, _d = _a.retryThrottledRequestMaxTimes, retryThrottledRequestMaxTimes = _d === void 0 ? defaultSettings.retryThrottledRequestMaxTimes : _d;
477
+ var publicKey = _a.publicKey, fileName = _a.fileName, _b = _a.baseURL, baseURL = _b === void 0 ? defaultSettings.baseURL : _b, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, _c = _a.source, source = _c === void 0 ? 'local' : _c, integration = _a.integration, userAgent = _a.userAgent, _d = _a.retryThrottledRequestMaxTimes, retryThrottledRequestMaxTimes = _d === void 0 ? defaultSettings.retryThrottledRequestMaxTimes : _d, metadata = _a.metadata;
406
478
  return retryIfThrottled(function () {
407
479
  var _a;
408
480
  return request({
@@ -413,17 +485,18 @@ function base(file, _a) {
413
485
  headers: {
414
486
  'X-UC-User-Agent': getUserAgent({ publicKey: publicKey, integration: integration, userAgent: userAgent })
415
487
  },
416
- data: buildFormData([
417
- ['file', file, (_a = fileName !== null && fileName !== void 0 ? fileName : file.name) !== null && _a !== void 0 ? _a : defaultFilename],
418
- ['UPLOADCARE_PUB_KEY', publicKey],
419
- [
420
- 'UPLOADCARE_STORE',
421
- typeof store === 'undefined' ? 'auto' : store ? 1 : 0
422
- ],
423
- ['signature', secureSignature],
424
- ['expire', secureExpire],
425
- ['source', source]
426
- ]),
488
+ data: buildFormData({
489
+ file: {
490
+ data: file,
491
+ name: (_a = fileName !== null && fileName !== void 0 ? fileName : file.name) !== null && _a !== void 0 ? _a : defaultFilename
492
+ },
493
+ UPLOADCARE_PUB_KEY: publicKey,
494
+ UPLOADCARE_STORE: getStoreValue(store),
495
+ signature: secureSignature,
496
+ expire: secureExpire,
497
+ source: source,
498
+ metadata: metadata
499
+ }),
427
500
  signal: signal,
428
501
  onProgress: onProgress
429
502
  }).then(function (_a) {
@@ -448,7 +521,7 @@ var TypeEnum;
448
521
  * Uploading files from URL.
449
522
  */
450
523
  function fromUrl(sourceUrl, _a) {
451
- var publicKey = _a.publicKey, _b = _a.baseURL, baseURL = _b === void 0 ? defaultSettings.baseURL : _b, store = _a.store, fileName = _a.fileName, checkForUrlDuplicates = _a.checkForUrlDuplicates, saveUrlForRecurrentUploads = _a.saveUrlForRecurrentUploads, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, _c = _a.source, source = _c === void 0 ? 'url' : _c, signal = _a.signal, integration = _a.integration, userAgent = _a.userAgent, _d = _a.retryThrottledRequestMaxTimes, retryThrottledRequestMaxTimes = _d === void 0 ? defaultSettings.retryThrottledRequestMaxTimes : _d;
524
+ var publicKey = _a.publicKey, _b = _a.baseURL, baseURL = _b === void 0 ? defaultSettings.baseURL : _b, store = _a.store, fileName = _a.fileName, checkForUrlDuplicates = _a.checkForUrlDuplicates, saveUrlForRecurrentUploads = _a.saveUrlForRecurrentUploads, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, _c = _a.source, source = _c === void 0 ? 'url' : _c, signal = _a.signal, integration = _a.integration, userAgent = _a.userAgent, _d = _a.retryThrottledRequestMaxTimes, retryThrottledRequestMaxTimes = _d === void 0 ? defaultSettings.retryThrottledRequestMaxTimes : _d, metadata = _a.metadata;
452
525
  return retryIfThrottled(function () {
453
526
  return request({
454
527
  method: 'POST',
@@ -459,13 +532,14 @@ function fromUrl(sourceUrl, _a) {
459
532
  jsonerrors: 1,
460
533
  pub_key: publicKey,
461
534
  source_url: sourceUrl,
462
- store: typeof store === 'undefined' ? 'auto' : store ? 1 : undefined,
535
+ store: getStoreValue(store),
463
536
  filename: fileName,
464
537
  check_URL_duplicates: checkForUrlDuplicates ? 1 : undefined,
465
538
  save_URL_duplicates: saveUrlForRecurrentUploads ? 1 : undefined,
466
539
  signature: secureSignature,
467
540
  expire: secureExpire,
468
- source: source
541
+ source: source,
542
+ metadata: metadata
469
543
  }),
470
544
  signal: signal
471
545
  }).then(function (_a) {
@@ -627,7 +701,7 @@ function info(uuid, _a) {
627
701
  * Start multipart uploading.
628
702
  */
629
703
  function multipartStart(size, _a) {
630
- var publicKey = _a.publicKey, contentType = _a.contentType, fileName = _a.fileName, _b = _a.multipartChunkSize, multipartChunkSize = _b === void 0 ? defaultSettings.multipartChunkSize : _b, _c = _a.baseURL, baseURL = _c === void 0 ? '' : _c, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, _d = _a.source, source = _d === void 0 ? 'local' : _d, integration = _a.integration, userAgent = _a.userAgent, _e = _a.retryThrottledRequestMaxTimes, retryThrottledRequestMaxTimes = _e === void 0 ? defaultSettings.retryThrottledRequestMaxTimes : _e;
704
+ var publicKey = _a.publicKey, contentType = _a.contentType, fileName = _a.fileName, _b = _a.multipartChunkSize, multipartChunkSize = _b === void 0 ? defaultSettings.multipartChunkSize : _b, _c = _a.baseURL, baseURL = _c === void 0 ? '' : _c, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, _d = _a.source, source = _d === void 0 ? 'local' : _d, integration = _a.integration, userAgent = _a.userAgent, _e = _a.retryThrottledRequestMaxTimes, retryThrottledRequestMaxTimes = _e === void 0 ? defaultSettings.retryThrottledRequestMaxTimes : _e, metadata = _a.metadata;
631
705
  return retryIfThrottled(function () {
632
706
  return request({
633
707
  method: 'POST',
@@ -635,17 +709,18 @@ function multipartStart(size, _a) {
635
709
  headers: {
636
710
  'X-UC-User-Agent': getUserAgent({ publicKey: publicKey, integration: integration, userAgent: userAgent })
637
711
  },
638
- data: buildFormData([
639
- ['filename', fileName !== null && fileName !== void 0 ? fileName : defaultFilename],
640
- ['size', size],
641
- ['content_type', contentType !== null && contentType !== void 0 ? contentType : defaultContentType],
642
- ['part_size', multipartChunkSize],
643
- ['UPLOADCARE_STORE', store ? '' : 'auto'],
644
- ['UPLOADCARE_PUB_KEY', publicKey],
645
- ['signature', secureSignature],
646
- ['expire', secureExpire],
647
- ['source', source]
648
- ]),
712
+ data: buildFormData({
713
+ filename: fileName !== null && fileName !== void 0 ? fileName : defaultFilename,
714
+ size: size,
715
+ content_type: contentType !== null && contentType !== void 0 ? contentType : defaultContentType,
716
+ part_size: multipartChunkSize,
717
+ UPLOADCARE_STORE: getStoreValue(store),
718
+ UPLOADCARE_PUB_KEY: publicKey,
719
+ signature: secureSignature,
720
+ expire: secureExpire,
721
+ source: source,
722
+ metadata: metadata
723
+ }),
649
724
  signal: signal
650
725
  }).then(function (_a) {
651
726
  var data = _a.data, headers = _a.headers, request = _a.request;
@@ -671,13 +746,17 @@ function multipartUpload(part, url, _a) {
671
746
  method: 'PUT',
672
747
  url: url,
673
748
  data: part,
749
+ // Upload request can't be non-computable because we always know exact size
674
750
  onProgress: onProgress,
675
751
  signal: signal
676
752
  })
677
753
  .then(function (result) {
678
754
  // hack for node ¯\_(ツ)_/¯
679
755
  if (onProgress)
680
- onProgress({ value: 1 });
756
+ onProgress({
757
+ isComputable: true,
758
+ value: 1
759
+ });
681
760
  return result;
682
761
  })
683
762
  .then(function (_a) {
@@ -698,11 +777,11 @@ function multipartComplete(uuid, _a) {
698
777
  headers: {
699
778
  'X-UC-User-Agent': getUserAgent({ publicKey: publicKey, integration: integration, userAgent: userAgent })
700
779
  },
701
- data: buildFormData([
702
- ['uuid', uuid],
703
- ['UPLOADCARE_PUB_KEY', publicKey],
704
- ['source', source]
705
- ]),
780
+ data: buildFormData({
781
+ uuid: uuid,
782
+ UPLOADCARE_PUB_KEY: publicKey,
783
+ source: source
784
+ }),
706
785
  signal: signal
707
786
  }).then(function (_a) {
708
787
  var data = _a.data, headers = _a.headers, request = _a.request;
@@ -731,6 +810,8 @@ var UploadcareFile = /** @class */ (function () {
731
810
  this.originalFilename = null;
732
811
  this.imageInfo = null;
733
812
  this.videoInfo = null;
813
+ this.contentInfo = null;
814
+ this.metadata = null;
734
815
  var uuid = fileInfo.uuid, s3Bucket = fileInfo.s3Bucket;
735
816
  var urlBase = s3Bucket
736
817
  ? "https://" + s3Bucket + ".s3.amazonaws.com/" + uuid + "/" + fileInfo.filename
@@ -750,6 +831,8 @@ var UploadcareFile = /** @class */ (function () {
750
831
  this.originalFilename = fileInfo.originalFilename;
751
832
  this.imageInfo = camelizeKeys(fileInfo.imageInfo);
752
833
  this.videoInfo = camelizeKeys(fileInfo.videoInfo);
834
+ this.contentInfo = camelizeKeys(fileInfo.contentInfo);
835
+ this.metadata = fileInfo.metadata || null;
753
836
  }
754
837
  return UploadcareFile;
755
838
  }());
@@ -800,7 +883,7 @@ function isReadyPoll(_a) {
800
883
  if (response.isReady) {
801
884
  return response;
802
885
  }
803
- onProgress && onProgress({ value: 1 });
886
+ onProgress && onProgress({ isComputable: true, value: 1 });
804
887
  return false;
805
888
  });
806
889
  },
@@ -809,7 +892,7 @@ function isReadyPoll(_a) {
809
892
  }
810
893
 
811
894
  var uploadFromObject = function (file, _a) {
812
- var publicKey = _a.publicKey, fileName = _a.fileName, baseURL = _a.baseURL, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, baseCDN = _a.baseCDN;
895
+ var publicKey = _a.publicKey, fileName = _a.fileName, baseURL = _a.baseURL, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, baseCDN = _a.baseCDN, metadata = _a.metadata;
813
896
  return base(file, {
814
897
  publicKey: publicKey,
815
898
  fileName: fileName,
@@ -822,7 +905,8 @@ var uploadFromObject = function (file, _a) {
822
905
  source: source,
823
906
  integration: integration,
824
907
  userAgent: userAgent,
825
- retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes
908
+ retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes,
909
+ metadata: metadata
826
910
  })
827
911
  .then(function (_a) {
828
912
  var file = _a.file;
@@ -1052,13 +1136,25 @@ function pollStrategy(_a) {
1052
1136
  return new UploadClientError("Token \"" + token + "\" was not found.");
1053
1137
  }
1054
1138
  case Status.Progress: {
1055
- if (onProgress)
1056
- onProgress({ value: response.done / response.total });
1139
+ if (onProgress) {
1140
+ if (response.total === 'unknown') {
1141
+ onProgress({ isComputable: false });
1142
+ }
1143
+ else {
1144
+ onProgress({
1145
+ isComputable: true,
1146
+ value: response.done / response.total
1147
+ });
1148
+ }
1149
+ }
1057
1150
  return false;
1058
1151
  }
1059
1152
  case Status.Success: {
1060
1153
  if (onProgress)
1061
- onProgress({ value: response.done / response.total });
1154
+ onProgress({
1155
+ isComputable: true,
1156
+ value: response.done / response.total
1157
+ });
1062
1158
  return response;
1063
1159
  }
1064
1160
  default: {
@@ -1087,14 +1183,25 @@ var pushStrategy = function (_a) {
1087
1183
  switch (result.status) {
1088
1184
  case Status.Progress: {
1089
1185
  if (onProgress) {
1090
- onProgress({ value: result.done / result.total });
1186
+ if (result.total === 'unknown') {
1187
+ onProgress({ isComputable: false });
1188
+ }
1189
+ else {
1190
+ onProgress({
1191
+ isComputable: true,
1192
+ value: result.done / result.total
1193
+ });
1194
+ }
1091
1195
  }
1092
1196
  break;
1093
1197
  }
1094
1198
  case Status.Success: {
1095
1199
  destroy();
1096
1200
  if (onProgress)
1097
- onProgress({ value: result.done / result.total });
1201
+ onProgress({
1202
+ isComputable: true,
1203
+ value: result.done / result.total
1204
+ });
1098
1205
  resolve(result);
1099
1206
  break;
1100
1207
  }
@@ -1107,7 +1214,7 @@ var pushStrategy = function (_a) {
1107
1214
  });
1108
1215
  };
1109
1216
  var uploadFromUrl = function (sourceUrl, _a) {
1110
- var publicKey = _a.publicKey, fileName = _a.fileName, baseURL = _a.baseURL, baseCDN = _a.baseCDN, checkForUrlDuplicates = _a.checkForUrlDuplicates, saveUrlForRecurrentUploads = _a.saveUrlForRecurrentUploads, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, _b = _a.pusherKey, pusherKey = _b === void 0 ? defaultSettings.pusherKey : _b;
1217
+ var publicKey = _a.publicKey, fileName = _a.fileName, baseURL = _a.baseURL, baseCDN = _a.baseCDN, checkForUrlDuplicates = _a.checkForUrlDuplicates, saveUrlForRecurrentUploads = _a.saveUrlForRecurrentUploads, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, _b = _a.pusherKey, pusherKey = _b === void 0 ? defaultSettings.pusherKey : _b, metadata = _a.metadata;
1111
1218
  return Promise.resolve(preconnect(pusherKey))
1112
1219
  .then(function () {
1113
1220
  return fromUrl(sourceUrl, {
@@ -1123,7 +1230,8 @@ var uploadFromUrl = function (sourceUrl, _a) {
1123
1230
  source: source,
1124
1231
  integration: integration,
1125
1232
  userAgent: userAgent,
1126
- retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes
1233
+ retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes,
1234
+ metadata: metadata
1127
1235
  });
1128
1236
  })
1129
1237
  .catch(function (error) {
@@ -1197,39 +1305,14 @@ var uploadFromUploaded = function (uuid, _a) {
1197
1305
  .then(function (result) {
1198
1306
  // hack for node ¯\_(ツ)_/¯
1199
1307
  if (onProgress)
1200
- onProgress({ value: 1 });
1308
+ onProgress({
1309
+ isComputable: true,
1310
+ value: 1
1311
+ });
1201
1312
  return result;
1202
1313
  });
1203
1314
  };
1204
1315
 
1205
- /**
1206
- * FileData type guard.
1207
- */
1208
- var isFileData = function (data) {
1209
- return (data !== undefined &&
1210
- ((typeof Blob !== 'undefined' && data instanceof Blob) ||
1211
- (typeof File !== 'undefined' && data instanceof File) ||
1212
- (typeof Buffer !== 'undefined' && data instanceof Buffer)));
1213
- };
1214
- /**
1215
- * Uuid type guard.
1216
- */
1217
- var isUuid = function (data) {
1218
- var UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
1219
- var regExp = new RegExp(UUID_REGEX);
1220
- return !isFileData(data) && regExp.test(data);
1221
- };
1222
- /**
1223
- * Url type guard.
1224
- *
1225
- * @param {NodeFile | BrowserFile | Url | Uuid} data
1226
- */
1227
- var isUrl = function (data) {
1228
- var URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
1229
- var regExp = new RegExp(URL_REGEX);
1230
- return !isFileData(data) && regExp.test(data);
1231
- };
1232
-
1233
1316
  /**
1234
1317
  * Get file size.
1235
1318
  */
@@ -1309,22 +1392,27 @@ var uploadPartWithRetry = function (chunk, url, _a) {
1309
1392
  });
1310
1393
  };
1311
1394
  var uploadMultipart = function (file, _a) {
1312
- var publicKey = _a.publicKey, fileName = _a.fileName, fileSize = _a.fileSize, baseURL = _a.baseURL, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, contentType = _a.contentType, _b = _a.multipartChunkSize, multipartChunkSize = _b === void 0 ? defaultSettings.multipartChunkSize : _b, _c = _a.maxConcurrentRequests, maxConcurrentRequests = _c === void 0 ? defaultSettings.maxConcurrentRequests : _c, _d = _a.multipartMaxAttempts, multipartMaxAttempts = _d === void 0 ? defaultSettings.multipartMaxAttempts : _d, baseCDN = _a.baseCDN;
1395
+ var publicKey = _a.publicKey, fileName = _a.fileName, fileSize = _a.fileSize, baseURL = _a.baseURL, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, contentType = _a.contentType, _b = _a.multipartChunkSize, multipartChunkSize = _b === void 0 ? defaultSettings.multipartChunkSize : _b, _c = _a.maxConcurrentRequests, maxConcurrentRequests = _c === void 0 ? defaultSettings.maxConcurrentRequests : _c, _d = _a.multipartMaxAttempts, multipartMaxAttempts = _d === void 0 ? defaultSettings.multipartMaxAttempts : _d, baseCDN = _a.baseCDN, metadata = _a.metadata;
1313
1396
  var size = fileSize || getFileSize(file);
1314
1397
  var progressValues;
1315
- var createProgressHandler = function (size, index) {
1398
+ var createProgressHandler = function (totalChunks, chunkIdx) {
1316
1399
  if (!onProgress)
1317
1400
  return;
1318
1401
  if (!progressValues) {
1319
- progressValues = Array(size).fill(0);
1402
+ progressValues = Array(totalChunks).fill(0);
1320
1403
  }
1321
1404
  var sum = function (values) {
1322
1405
  return values.reduce(function (sum, next) { return sum + next; }, 0);
1323
1406
  };
1324
- return function (_a) {
1325
- var value = _a.value;
1326
- progressValues[index] = value;
1327
- onProgress({ value: sum(progressValues) / size });
1407
+ return function (info) {
1408
+ if (!info.isComputable) {
1409
+ return;
1410
+ }
1411
+ progressValues[chunkIdx] = info.value;
1412
+ onProgress({
1413
+ isComputable: true,
1414
+ value: sum(progressValues) / totalChunks
1415
+ });
1328
1416
  };
1329
1417
  };
1330
1418
  return multipartStart(size, {
@@ -1339,7 +1427,8 @@ var uploadMultipart = function (file, _a) {
1339
1427
  source: source,
1340
1428
  integration: integration,
1341
1429
  userAgent: userAgent,
1342
- retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes
1430
+ retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes,
1431
+ metadata: metadata
1343
1432
  })
1344
1433
  .then(function (_a) {
1345
1434
  var uuid = _a.uuid, parts = _a.parts;
@@ -1393,10 +1482,10 @@ var uploadMultipart = function (file, _a) {
1393
1482
  * Uploads file from provided data.
1394
1483
  */
1395
1484
  function uploadFile(data, _a) {
1396
- var publicKey = _a.publicKey, fileName = _a.fileName, _b = _a.baseURL, baseURL = _b === void 0 ? defaultSettings.baseURL : _b, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, contentType = _a.contentType, multipartChunkSize = _a.multipartChunkSize, multipartMaxAttempts = _a.multipartMaxAttempts, maxConcurrentRequests = _a.maxConcurrentRequests, _c = _a.baseCDN, baseCDN = _c === void 0 ? defaultSettings.baseCDN : _c, checkForUrlDuplicates = _a.checkForUrlDuplicates, saveUrlForRecurrentUploads = _a.saveUrlForRecurrentUploads, pusherKey = _a.pusherKey;
1485
+ var publicKey = _a.publicKey, fileName = _a.fileName, _b = _a.baseURL, baseURL = _b === void 0 ? defaultSettings.baseURL : _b, secureSignature = _a.secureSignature, secureExpire = _a.secureExpire, store = _a.store, signal = _a.signal, onProgress = _a.onProgress, source = _a.source, integration = _a.integration, userAgent = _a.userAgent, retryThrottledRequestMaxTimes = _a.retryThrottledRequestMaxTimes, contentType = _a.contentType, multipartMinFileSize = _a.multipartMinFileSize, multipartChunkSize = _a.multipartChunkSize, multipartMaxAttempts = _a.multipartMaxAttempts, maxConcurrentRequests = _a.maxConcurrentRequests, _c = _a.baseCDN, baseCDN = _c === void 0 ? defaultSettings.baseCDN : _c, checkForUrlDuplicates = _a.checkForUrlDuplicates, saveUrlForRecurrentUploads = _a.saveUrlForRecurrentUploads, pusherKey = _a.pusherKey, metadata = _a.metadata;
1397
1486
  if (isFileData(data)) {
1398
1487
  var fileSize = getFileSize(data);
1399
- if (isMultipart(fileSize)) {
1488
+ if (isMultipart(fileSize, multipartMinFileSize)) {
1400
1489
  return uploadMultipart(data, {
1401
1490
  publicKey: publicKey,
1402
1491
  contentType: contentType,
@@ -1414,7 +1503,8 @@ function uploadFile(data, _a) {
1414
1503
  userAgent: userAgent,
1415
1504
  maxConcurrentRequests: maxConcurrentRequests,
1416
1505
  retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes,
1417
- baseCDN: baseCDN
1506
+ baseCDN: baseCDN,
1507
+ metadata: metadata
1418
1508
  });
1419
1509
  }
1420
1510
  return uploadFromObject(data, {
@@ -1430,7 +1520,8 @@ function uploadFile(data, _a) {
1430
1520
  integration: integration,
1431
1521
  userAgent: userAgent,
1432
1522
  retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes,
1433
- baseCDN: baseCDN
1523
+ baseCDN: baseCDN,
1524
+ metadata: metadata
1434
1525
  });
1435
1526
  }
1436
1527
  if (isUrl(data)) {
@@ -1450,7 +1541,8 @@ function uploadFile(data, _a) {
1450
1541
  integration: integration,
1451
1542
  userAgent: userAgent,
1452
1543
  retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes,
1453
- pusherKey: pusherKey
1544
+ pusherKey: pusherKey,
1545
+ metadata: metadata
1454
1546
  });
1455
1547
  }
1456
1548
  if (isUuid(data)) {
@@ -1529,6 +1621,7 @@ function uploadFileGroup(data, _a) {
1529
1621
  throw new TypeError("Group uploading from \"" + data + "\" is not supported");
1530
1622
  }
1531
1623
  var progressValues;
1624
+ var isStillComputable = true;
1532
1625
  var filesCount = data.length;
1533
1626
  var createProgressHandler = function (size, index) {
1534
1627
  if (!onProgress)
@@ -1539,10 +1632,14 @@ function uploadFileGroup(data, _a) {
1539
1632
  var normalize = function (values) {
1540
1633
  return values.reduce(function (sum, next) { return sum + next; }) / size;
1541
1634
  };
1542
- return function (_a) {
1543
- var value = _a.value;
1544
- progressValues[index] = value;
1545
- onProgress({ value: normalize(progressValues) });
1635
+ return function (info) {
1636
+ if (!info.isComputable || !isStillComputable) {
1637
+ isStillComputable = false;
1638
+ onProgress({ isComputable: false });
1639
+ return;
1640
+ }
1641
+ progressValues[index] = info.value;
1642
+ onProgress({ isComputable: true, value: normalize(progressValues) });
1546
1643
  };
1547
1644
  };
1548
1645
  return Promise.all(data.map(function (file, index) {
@@ -1583,7 +1680,12 @@ function uploadFileGroup(data, _a) {
1583
1680
  integration: integration,
1584
1681
  userAgent: userAgent,
1585
1682
  retryThrottledRequestMaxTimes: retryThrottledRequestMaxTimes
1586
- }).then(function (groupInfo) { return new UploadcareGroup(groupInfo, filesInGroup); });
1683
+ })
1684
+ .then(function (groupInfo) { return new UploadcareGroup(groupInfo, filesInGroup); })
1685
+ .then(function (group) {
1686
+ onProgress && onProgress({ isComputable: true, value: 1 });
1687
+ return group;
1688
+ });
1587
1689
  });
1588
1690
  }
1589
1691