@uploadcare/upload-client 6.0.1-alpha.8 → 6.0.1-alpha.9

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.
@@ -157,6 +157,26 @@ const poll = ({ check, interval = DEFAULT_INTERVAL, timeout, signal }) => new Pr
157
157
  tickTimeoutId = setTimeout(tick, 0);
158
158
  });
159
159
 
160
+ /*
161
+ Settings for future support:
162
+ parallelDirectUploads: 10,
163
+ */
164
+ const defaultSettings = {
165
+ baseCDN: 'https://ucarecdn.com',
166
+ baseURL: 'https://upload.uploadcare.com',
167
+ maxContentLength: 50 * 1024 * 1024,
168
+ retryThrottledRequestMaxTimes: 1,
169
+ retryNetworkErrorMaxTimes: 3,
170
+ multipartMinFileSize: 25 * 1024 * 1024,
171
+ multipartChunkSize: 5 * 1024 * 1024,
172
+ multipartMinLastPartSize: 1024 * 1024,
173
+ maxConcurrentRequests: 4,
174
+ pollingTimeoutMilliseconds: 10000,
175
+ pusherKey: '79ae88bd931ea68464d9'
176
+ };
177
+ const defaultContentType = 'application/octet-stream';
178
+ const defaultFilename = 'original';
179
+
160
180
  const request = ({ method, url, data, headers = {}, signal, onProgress }) => new Promise((resolve, reject) => {
161
181
  const xhr = new XMLHttpRequest();
162
182
  const requestMethod = method?.toUpperCase() || 'GET';
@@ -168,14 +188,12 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
168
188
  * and https://bugs.chromium.org/p/chromium/issues/detail?id=1346628
169
189
  */
170
190
  xhr.open(requestMethod, url, true);
171
- console.log(`xhr.open(${requestMethod}, ${url}, true)`);
172
191
  if (headers) {
173
192
  Object.entries(headers).forEach((entry) => {
174
193
  const [key, value] = entry;
175
194
  typeof value !== 'undefined' &&
176
195
  !Array.isArray(value) &&
177
196
  xhr.setRequestHeader(key, value);
178
- console.log(`xhr.setRequestHeader(${key}, ${value})`);
179
197
  });
180
198
  }
181
199
  xhr.responseType = 'text';
@@ -227,7 +245,6 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
227
245
  xhr.onerror = (progressEvent) => {
228
246
  if (aborted)
229
247
  return;
230
- console.log('aboirt', xhr, progressEvent);
231
248
  // only triggers if the request couldn't be made at all
232
249
  reject(new UploadcareNetworkError(progressEvent));
233
250
  };
@@ -245,7 +262,6 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
245
262
  };
246
263
  }
247
264
  if (data) {
248
- console.log(`xhr.send(${data})`);
249
265
  xhr.send(data);
250
266
  }
251
267
  else {
@@ -253,26 +269,28 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
253
269
  }
254
270
  });
255
271
 
256
- const isReactNativeUri = (uri) => {
257
- if (typeof uri !== 'string') {
258
- return false;
259
- }
260
- return uri.startsWith('file:') || uri.startsWith('content:');
272
+ const isBlob = (data) => {
273
+ return typeof Blob !== 'undefined' && data instanceof Blob;
261
274
  };
262
- const isReactNativeAsset = (asset) => {
263
- return (!!asset &&
264
- typeof asset === 'object' &&
265
- !Array.isArray(asset) &&
266
- 'uri' in asset &&
267
- typeof asset.uri === 'string' &&
268
- isReactNativeUri(asset.uri));
275
+ const isFile = (data) => {
276
+ return typeof File !== 'undefined' && data instanceof File;
277
+ };
278
+ const isBuffer = (data) => {
279
+ return typeof Buffer !== 'undefined' && data instanceof Buffer;
280
+ };
281
+ const isReactNativeAsset = (data) => {
282
+ return (!!data &&
283
+ typeof data === 'object' &&
284
+ !Array.isArray(data) &&
285
+ 'uri' in data &&
286
+ typeof data.uri === 'string');
287
+ };
288
+ const isFileData = (data) => {
289
+ return (isBlob(data) || isFile(data) || isBuffer(data) || isReactNativeAsset(data));
269
290
  };
270
291
 
271
- const getFileOptions = ({ name }) => name ? [name] : [];
292
+ const getFileOptions = () => [];
272
293
  const transformFile = (file, name, contentType) => {
273
- if (isReactNativeUri(file)) {
274
- return { uri: file, name, type: contentType };
275
- }
276
294
  if (isReactNativeAsset(file)) {
277
295
  return {
278
296
  uri: file.uri,
@@ -280,41 +298,14 @@ const transformFile = (file, name, contentType) => {
280
298
  type: file.type || contentType
281
299
  };
282
300
  }
283
- const uri = URL.createObjectURL(file);
284
- return { uri, name, type: contentType };
301
+ if (isBlob(file)) {
302
+ const uri = URL.createObjectURL(file);
303
+ return { uri, name: name, type: file.type || contentType };
304
+ }
305
+ throw new Error(`Unsupported file type: ${file}`);
285
306
  };
286
307
  var getFormData = () => new FormData();
287
308
 
288
- /**
289
- * FileData type guard.
290
- */
291
- const isFileData = (data) => {
292
- return (data !== undefined &&
293
- ((typeof Blob !== 'undefined' && data instanceof Blob) ||
294
- (typeof File !== 'undefined' && data instanceof File) ||
295
- (typeof Buffer !== 'undefined' && data instanceof Buffer) ||
296
- (typeof data === 'string' && isReactNativeUri(data)) ||
297
- (typeof data === 'object' && isReactNativeAsset(data))));
298
- };
299
- /**
300
- * Uuid type guard.
301
- */
302
- const isUuid = (data) => {
303
- const UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
304
- const regExp = new RegExp(UUID_REGEX);
305
- return !isFileData(data) && regExp.test(data);
306
- };
307
- /**
308
- * Url type guard.
309
- *
310
- * @param {NodeFile | BrowserFile | Url | Uuid} data
311
- */
312
- const isUrl = (data) => {
313
- const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
314
- const regExp = new RegExp(URL_REGEX);
315
- return !isFileData(data) && regExp.test(data);
316
- };
317
-
318
309
  const isSimpleValue = (value) => {
319
310
  return (typeof value === 'string' ||
320
311
  typeof value === 'number' ||
@@ -331,7 +322,7 @@ function collectParams(params, inputKey, inputValue) {
331
322
  if (isFileValue(inputValue)) {
332
323
  const { name, contentType } = inputValue;
333
324
  const file = transformFile(inputValue.data, name, contentType); // lgtm [js/superfluous-trailing-arguments]
334
- const options = getFileOptions({ name, contentType });
325
+ const options = getFileOptions();
335
326
  params.push([inputKey, file, ...options]);
336
327
  }
337
328
  else if (isObjectValue(inputValue)) {
@@ -353,11 +344,9 @@ function getFormDataParams(options) {
353
344
  return params;
354
345
  }
355
346
  function buildFormData(options) {
356
- console.log('buildFormData', options);
357
347
  const formData = getFormData();
358
348
  const paramsList = getFormDataParams(options);
359
349
  for (const params of paramsList) {
360
- console.log('params', params);
361
350
  const [key, value, ...rest] = params;
362
351
  // node form-data has another signature for append
363
352
  formData.append(key, value, ...rest);
@@ -365,6 +354,19 @@ function buildFormData(options) {
365
354
  return formData;
366
355
  }
367
356
 
357
+ class UploadClientError extends Error {
358
+ constructor(message, code, request, response, headers) {
359
+ super();
360
+ this.name = 'UploadClientError';
361
+ this.message = message;
362
+ this.code = code;
363
+ this.request = request;
364
+ this.response = response;
365
+ this.headers = headers;
366
+ Object.setPrototypeOf(this, UploadClientError.prototype);
367
+ }
368
+ }
369
+
368
370
  const buildSearchParams = (query) => {
369
371
  const searchParams = new URLSearchParams();
370
372
  for (const [key, value] of Object.entries(query)) {
@@ -396,26 +398,6 @@ const getUrl = (base, path, query) => {
396
398
  return url.toString();
397
399
  };
398
400
 
399
- /*
400
- Settings for future support:
401
- parallelDirectUploads: 10,
402
- */
403
- const defaultSettings = {
404
- baseCDN: 'https://ucarecdn.com',
405
- baseURL: 'https://upload.uploadcare.com',
406
- maxContentLength: 50 * 1024 * 1024,
407
- retryThrottledRequestMaxTimes: 1,
408
- retryNetworkErrorMaxTimes: 3,
409
- multipartMinFileSize: 25 * 1024 * 1024,
410
- multipartChunkSize: 5 * 1024 * 1024,
411
- multipartMinLastPartSize: 1024 * 1024,
412
- maxConcurrentRequests: 4,
413
- pollingTimeoutMilliseconds: 10000,
414
- pusherKey: '79ae88bd931ea68464d9'
415
- };
416
- const defaultContentType = 'application/octet-stream';
417
- const defaultFilename = 'original';
418
-
419
401
  var version = '6.0.0';
420
402
 
421
403
  const LIBRARY_NAME = 'UploadcareUploadClient';
@@ -428,19 +410,6 @@ function getUserAgent(options) {
428
410
  });
429
411
  }
430
412
 
431
- class UploadClientError extends Error {
432
- constructor(message, code, request, response, headers) {
433
- super();
434
- this.name = 'UploadClientError';
435
- this.message = message;
436
- this.code = code;
437
- this.request = request;
438
- this.response = response;
439
- this.headers = headers;
440
- Object.setPrototypeOf(this, UploadClientError.prototype);
441
- }
442
- }
443
-
444
413
  const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
445
414
  const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
446
415
  const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
@@ -471,6 +440,31 @@ function retryIfFailed(fn, options) {
471
440
  }));
472
441
  }
473
442
 
443
+ const getContentType = (file) => {
444
+ if (isBlob(file) || isFile(file) || isReactNativeAsset(file)) {
445
+ return file.type || defaultContentType;
446
+ }
447
+ if (isBuffer(file)) {
448
+ return defaultFilename;
449
+ }
450
+ console.warn(`Unknown filename: ${file}. Using default filename: ${defaultFilename}`);
451
+ return defaultFilename;
452
+ };
453
+
454
+ const getFilename = (file) => {
455
+ if (isBlob(file) || isBuffer(file)) {
456
+ return defaultFilename;
457
+ }
458
+ if (isFile(file)) {
459
+ return file.name || defaultFilename;
460
+ }
461
+ if (isReactNativeAsset(file)) {
462
+ return file.name || defaultFilename;
463
+ }
464
+ console.warn(`Unknown file type: ${file}. Using default filename: ${defaultFilename}`);
465
+ return defaultFilename;
466
+ };
467
+
474
468
  function getStoreValue(store) {
475
469
  return typeof store === 'undefined' ? 'auto' : store ? '1' : '0';
476
470
  }
@@ -486,13 +480,13 @@ function base(file, { publicKey, fileName, contentType, baseURL = defaultSetting
486
480
  jsonerrors: 1
487
481
  }),
488
482
  headers: {
489
- 'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent }),
483
+ 'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
490
484
  },
491
485
  data: buildFormData({
492
486
  file: {
493
487
  data: file,
494
- name: fileName ?? file?.name ?? defaultFilename,
495
- contentType: contentType ?? file?.type ?? defaultContentType
488
+ name: fileName || getFilename(file),
489
+ contentType: contentType || getContentType(file)
496
490
  },
497
491
  UPLOADCARE_PUB_KEY: publicKey,
498
492
  UPLOADCARE_STORE: getStoreValue(store),
@@ -690,9 +684,9 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
690
684
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
691
685
  },
692
686
  data: buildFormData({
693
- filename: fileName ?? defaultFilename,
687
+ filename: fileName || defaultFilename,
694
688
  size: size,
695
- content_type: contentType ?? defaultContentType,
689
+ content_type: contentType || defaultContentType,
696
690
  part_size: multipartChunkSize,
697
691
  UPLOADCARE_STORE: getStoreValue(store),
698
692
  UPLOADCARE_PUB_KEY: publicKey,
@@ -769,6 +763,28 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
769
763
  }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
770
764
  }
771
765
 
766
+ function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
767
+ return poll({
768
+ check: (signal) => info(file, {
769
+ publicKey,
770
+ baseURL,
771
+ signal,
772
+ source,
773
+ integration,
774
+ userAgent,
775
+ retryThrottledRequestMaxTimes,
776
+ retryNetworkErrorMaxTimes
777
+ }).then((response) => {
778
+ if (response.isReady) {
779
+ return response;
780
+ }
781
+ onProgress && onProgress({ isComputable: true, value: 1 });
782
+ return false;
783
+ }),
784
+ signal
785
+ });
786
+ }
787
+
772
788
  class UploadcareFile {
773
789
  constructor(fileInfo, { baseCDN, fileName }) {
774
790
  this.name = null;
@@ -806,28 +822,6 @@ class UploadcareFile {
806
822
  }
807
823
  }
808
824
 
809
- function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
810
- return poll({
811
- check: (signal) => info(file, {
812
- publicKey,
813
- baseURL,
814
- signal,
815
- source,
816
- integration,
817
- userAgent,
818
- retryThrottledRequestMaxTimes,
819
- retryNetworkErrorMaxTimes
820
- }).then((response) => {
821
- if (response.isReady) {
822
- return response;
823
- }
824
- onProgress && onProgress({ isComputable: true, value: 1 });
825
- return false;
826
- }),
827
- signal
828
- });
829
- }
830
-
831
825
  const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN, metadata }) => {
832
826
  return base(file, {
833
827
  publicKey,
@@ -863,6 +857,29 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
863
857
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
864
858
  };
865
859
 
860
+ const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN }) => {
861
+ return info(uuid, {
862
+ publicKey,
863
+ baseURL,
864
+ signal,
865
+ source,
866
+ integration,
867
+ userAgent,
868
+ retryThrottledRequestMaxTimes,
869
+ retryNetworkErrorMaxTimes
870
+ })
871
+ .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
872
+ .then((result) => {
873
+ // hack for node ¯\_(ツ)_/¯
874
+ if (onProgress)
875
+ onProgress({
876
+ isComputable: true,
877
+ value: 1
878
+ });
879
+ return result;
880
+ });
881
+ };
882
+
866
883
  const race = (fns, { signal } = {}) => {
867
884
  let lastError = null;
868
885
  let winnerIndex = null;
@@ -1202,35 +1219,30 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
1202
1219
  }))
1203
1220
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1204
1221
 
1205
- const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN }) => {
1206
- return info(uuid, {
1207
- publicKey,
1208
- baseURL,
1209
- signal,
1210
- source,
1211
- integration,
1212
- userAgent,
1213
- retryThrottledRequestMaxTimes,
1214
- retryNetworkErrorMaxTimes
1215
- })
1216
- .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1217
- .then((result) => {
1218
- // hack for node ¯\_(ツ)_/¯
1219
- if (onProgress)
1220
- onProgress({
1221
- isComputable: true,
1222
- value: 1
1223
- });
1224
- return result;
1225
- });
1222
+ const memo = new WeakMap();
1223
+ const getReactNativeBlob = async (asset) => {
1224
+ if (memo.has(asset)) {
1225
+ return memo.get(asset);
1226
+ }
1227
+ const blob = await fetch(asset.uri).then((res) => res.blob());
1228
+ memo.set(asset, blob);
1229
+ return blob;
1226
1230
  };
1227
1231
 
1228
- /**
1229
- * Get file size.
1230
- */
1231
- const getFileSize = (file) => {
1232
- return file.length || file.size;
1232
+ const getFileSize = async (file) => {
1233
+ if (isBuffer(file)) {
1234
+ return file.length;
1235
+ }
1236
+ if (isFile(file) || isBlob(file)) {
1237
+ return file.size;
1238
+ }
1239
+ if (isReactNativeAsset(file)) {
1240
+ const blob = await getReactNativeBlob(file);
1241
+ return blob.size;
1242
+ }
1243
+ throw new Error(`Failed to get file size for file: ${file}`);
1233
1244
  };
1245
+
1234
1246
  /**
1235
1247
  * Check if FileData is multipart data.
1236
1248
  */
@@ -1238,28 +1250,24 @@ const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartM
1238
1250
  return fileSize >= multipartMinFileSize;
1239
1251
  };
1240
1252
 
1241
- const sliceChunk = (file, index, fileSize, chunkSize) => {
1242
- const start = chunkSize * index;
1243
- const end = Math.min(start + chunkSize, fileSize);
1244
- return file.slice(start, end);
1253
+ /**
1254
+ * Uuid type guard.
1255
+ */
1256
+ const isUuid = (data) => {
1257
+ const UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
1258
+ const regExp = new RegExp(UUID_REGEX);
1259
+ return !isFileData(data) && regExp.test(data);
1245
1260
  };
1246
-
1247
1261
  /**
1248
- * React-native hack for blob slicing
1249
- *
1250
- * We need to store references to sliced blobs to prevent source blob from
1251
- * being deallocated until uploading complete. Access to deallocated blob
1252
- * causes app crash.
1262
+ * Url type guard.
1253
1263
  *
1254
- * See https://github.com/uploadcare/uploadcare-js-api-clients/issues/306
1255
- * and https://github.com/facebook/react-native/issues/27543
1264
+ * @param {AnyFile | Url | Uuid} data
1256
1265
  */
1257
- function prepareChunks(file, fileSize, chunkSize) {
1258
- return (index) => {
1259
- const chunk = sliceChunk(file, index, fileSize, chunkSize);
1260
- return chunk;
1261
- };
1262
- }
1266
+ const isUrl = (data) => {
1267
+ const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
1268
+ const regExp = new RegExp(URL_REGEX);
1269
+ return !isFileData(data) && regExp.test(data);
1270
+ };
1263
1271
 
1264
1272
  const runWithConcurrency = (concurrency, tasks) => {
1265
1273
  return new Promise((resolve, reject) => {
@@ -1296,6 +1304,36 @@ const runWithConcurrency = (concurrency, tasks) => {
1296
1304
  });
1297
1305
  };
1298
1306
 
1307
+ const sliceChunk = (file, index, fileSize, chunkSize) => {
1308
+ const start = chunkSize * index;
1309
+ const end = Math.min(start + chunkSize, fileSize);
1310
+ return file.slice(start, end);
1311
+ };
1312
+
1313
+ /**
1314
+ * React-native hack for blob slicing
1315
+ *
1316
+ * We need to store references to sliced blobs to prevent source blob from
1317
+ * being deallocated until uploading complete. Access to deallocated blob
1318
+ * causes app crash.
1319
+ *
1320
+ * See https://github.com/uploadcare/uploadcare-js-api-clients/issues/306
1321
+ * and https://github.com/facebook/react-native/issues/27543
1322
+ */
1323
+ const prepareChunks = async (file, fileSize, chunkSize) => {
1324
+ let blob;
1325
+ if (isReactNativeAsset(file)) {
1326
+ blob = await getReactNativeBlob(file);
1327
+ }
1328
+ else {
1329
+ blob = file;
1330
+ }
1331
+ return (index) => {
1332
+ const chunk = sliceChunk(blob, index, fileSize, chunkSize);
1333
+ return chunk;
1334
+ };
1335
+ };
1336
+
1299
1337
  const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes }) => multipartUpload(chunk, url, {
1300
1338
  publicKey,
1301
1339
  onProgress,
@@ -1304,8 +1342,8 @@ const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, re
1304
1342
  retryThrottledRequestMaxTimes,
1305
1343
  retryNetworkErrorMaxTimes
1306
1344
  });
1307
- 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 }) => {
1308
- const size = fileSize || getFileSize(file);
1345
+ const uploadMultipart = async (file, { publicKey, fileName, fileSize, baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, maxConcurrentRequests = defaultSettings.maxConcurrentRequests, baseCDN, metadata }) => {
1346
+ const size = fileSize || await getFileSize(file);
1309
1347
  let progressValues;
1310
1348
  const createProgressHandler = (totalChunks, chunkIdx) => {
1311
1349
  if (!onProgress)
@@ -1327,8 +1365,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1327
1365
  };
1328
1366
  return multipartStart(size, {
1329
1367
  publicKey,
1330
- contentType,
1331
- fileName: fileName ?? file.name,
1368
+ contentType: contentType || getContentType(file),
1369
+ fileName: fileName || getFilename(file),
1332
1370
  baseURL,
1333
1371
  secureSignature,
1334
1372
  secureExpire,
@@ -1341,8 +1379,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1341
1379
  retryNetworkErrorMaxTimes,
1342
1380
  metadata
1343
1381
  })
1344
- .then(({ uuid, parts }) => {
1345
- const getChunk = prepareChunks(file, size, multipartChunkSize);
1382
+ .then(async ({ uuid, parts }) => {
1383
+ const getChunk = await prepareChunks(file, size, multipartChunkSize);
1346
1384
  return Promise.all([
1347
1385
  uuid,
1348
1386
  runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPart(getChunk(index), url, {
@@ -1389,14 +1427,15 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1389
1427
  /**
1390
1428
  * Uploads file from provided data.
1391
1429
  */
1392
- 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 }) {
1430
+ async 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 }) {
1393
1431
  if (isFileData(data)) {
1394
- const fileSize = getFileSize(data);
1432
+ const fileSize = await getFileSize(data);
1395
1433
  if (isMultipart(fileSize, multipartMinFileSize)) {
1396
1434
  return uploadMultipart(data, {
1397
1435
  publicKey,
1398
1436
  contentType,
1399
1437
  multipartChunkSize,
1438
+ fileSize,
1400
1439
  fileName,
1401
1440
  baseURL,
1402
1441
  secureSignature,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uploadcare/upload-client",
3
- "version": "6.0.1-alpha.8",
3
+ "version": "6.0.1-alpha.9",
4
4
  "description": "Library for work with Uploadcare Upload API",
5
5
  "type": "module",
6
6
  "module": "./dist/index.node.js",