@uploadcare/upload-client 6.0.1-alpha.7 → 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,61 +269,43 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
253
269
  }
254
270
  });
255
271
 
256
- const isReactNativeUri = (uri) => {
257
- return uri.startsWith('file:') || uri.startsWith('content:');
272
+ const isBlob = (data) => {
273
+ return typeof Blob !== 'undefined' && data instanceof Blob;
274
+ };
275
+ const isFile = (data) => {
276
+ return typeof File !== 'undefined' && data instanceof File;
258
277
  };
259
- const isReactNativeAsset = (asset) => {
260
- return (typeof asset === 'object' &&
261
- !!asset &&
262
- 'uri' in asset &&
263
- typeof asset.uri === 'string' &&
264
- isReactNativeUri(asset.uri));
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));
265
290
  };
266
291
 
267
- const getFileOptions = ({ name }) => name ? [name] : [];
292
+ const getFileOptions = () => [];
268
293
  const transformFile = (file, name, contentType) => {
269
- if (typeof file === 'string' && isReactNativeUri(file)) {
270
- return { uri: file, name, type: contentType };
271
- }
272
294
  if (isReactNativeAsset(file)) {
273
- return file;
295
+ return {
296
+ uri: file.uri,
297
+ name: file.name || name,
298
+ type: file.type || contentType
299
+ };
300
+ }
301
+ if (isBlob(file)) {
302
+ const uri = URL.createObjectURL(file);
303
+ return { uri, name: name, type: file.type || contentType };
274
304
  }
275
- const uri = URL.createObjectURL(file);
276
- const type = contentType || file.type;
277
- return { uri, name, type };
305
+ throw new Error(`Unsupported file type: ${file}`);
278
306
  };
279
307
  var getFormData = () => new FormData();
280
308
 
281
- /**
282
- * FileData type guard.
283
- */
284
- const isFileData = (data) => {
285
- return (data !== undefined &&
286
- ((typeof Blob !== 'undefined' && data instanceof Blob) ||
287
- (typeof File !== 'undefined' && data instanceof File) ||
288
- (typeof Buffer !== 'undefined' && data instanceof Buffer) ||
289
- (typeof data === 'string' && isReactNativeUri(data)) ||
290
- (typeof data === 'object' && isReactNativeAsset(data))));
291
- };
292
- /**
293
- * Uuid type guard.
294
- */
295
- const isUuid = (data) => {
296
- const UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
297
- const regExp = new RegExp(UUID_REGEX);
298
- return !isFileData(data) && regExp.test(data);
299
- };
300
- /**
301
- * Url type guard.
302
- *
303
- * @param {NodeFile | BrowserFile | Url | Uuid} data
304
- */
305
- const isUrl = (data) => {
306
- const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
307
- const regExp = new RegExp(URL_REGEX);
308
- return !isFileData(data) && regExp.test(data);
309
- };
310
-
311
309
  const isSimpleValue = (value) => {
312
310
  return (typeof value === 'string' ||
313
311
  typeof value === 'number' ||
@@ -324,7 +322,7 @@ function collectParams(params, inputKey, inputValue) {
324
322
  if (isFileValue(inputValue)) {
325
323
  const { name, contentType } = inputValue;
326
324
  const file = transformFile(inputValue.data, name, contentType); // lgtm [js/superfluous-trailing-arguments]
327
- const options = getFileOptions({ name, contentType });
325
+ const options = getFileOptions();
328
326
  params.push([inputKey, file, ...options]);
329
327
  }
330
328
  else if (isObjectValue(inputValue)) {
@@ -346,11 +344,9 @@ function getFormDataParams(options) {
346
344
  return params;
347
345
  }
348
346
  function buildFormData(options) {
349
- console.log('buildFormData', options);
350
347
  const formData = getFormData();
351
348
  const paramsList = getFormDataParams(options);
352
349
  for (const params of paramsList) {
353
- console.log('params', params);
354
350
  const [key, value, ...rest] = params;
355
351
  // node form-data has another signature for append
356
352
  formData.append(key, value, ...rest);
@@ -358,6 +354,19 @@ function buildFormData(options) {
358
354
  return formData;
359
355
  }
360
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
+
361
370
  const buildSearchParams = (query) => {
362
371
  const searchParams = new URLSearchParams();
363
372
  for (const [key, value] of Object.entries(query)) {
@@ -389,26 +398,6 @@ const getUrl = (base, path, query) => {
389
398
  return url.toString();
390
399
  };
391
400
 
392
- /*
393
- Settings for future support:
394
- parallelDirectUploads: 10,
395
- */
396
- const defaultSettings = {
397
- baseCDN: 'https://ucarecdn.com',
398
- baseURL: 'https://upload.uploadcare.com',
399
- maxContentLength: 50 * 1024 * 1024,
400
- retryThrottledRequestMaxTimes: 1,
401
- retryNetworkErrorMaxTimes: 3,
402
- multipartMinFileSize: 25 * 1024 * 1024,
403
- multipartChunkSize: 5 * 1024 * 1024,
404
- multipartMinLastPartSize: 1024 * 1024,
405
- maxConcurrentRequests: 4,
406
- pollingTimeoutMilliseconds: 10000,
407
- pusherKey: '79ae88bd931ea68464d9'
408
- };
409
- const defaultContentType = 'application/octet-stream';
410
- const defaultFilename = 'original';
411
-
412
401
  var version = '6.0.0';
413
402
 
414
403
  const LIBRARY_NAME = 'UploadcareUploadClient';
@@ -421,19 +410,6 @@ function getUserAgent(options) {
421
410
  });
422
411
  }
423
412
 
424
- class UploadClientError extends Error {
425
- constructor(message, code, request, response, headers) {
426
- super();
427
- this.name = 'UploadClientError';
428
- this.message = message;
429
- this.code = code;
430
- this.request = request;
431
- this.response = response;
432
- this.headers = headers;
433
- Object.setPrototypeOf(this, UploadClientError.prototype);
434
- }
435
- }
436
-
437
413
  const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
438
414
  const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
439
415
  const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
@@ -464,6 +440,31 @@ function retryIfFailed(fn, options) {
464
440
  }));
465
441
  }
466
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
+
467
468
  function getStoreValue(store) {
468
469
  return typeof store === 'undefined' ? 'auto' : store ? '1' : '0';
469
470
  }
@@ -479,13 +480,13 @@ function base(file, { publicKey, fileName, contentType, baseURL = defaultSetting
479
480
  jsonerrors: 1
480
481
  }),
481
482
  headers: {
482
- 'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent }),
483
+ 'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
483
484
  },
484
485
  data: buildFormData({
485
486
  file: {
486
487
  data: file,
487
- name: fileName ?? file?.name ?? defaultFilename,
488
- contentType
488
+ name: fileName || getFilename(file),
489
+ contentType: contentType || getContentType(file)
489
490
  },
490
491
  UPLOADCARE_PUB_KEY: publicKey,
491
492
  UPLOADCARE_STORE: getStoreValue(store),
@@ -683,9 +684,9 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
683
684
  'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
684
685
  },
685
686
  data: buildFormData({
686
- filename: fileName ?? defaultFilename,
687
+ filename: fileName || defaultFilename,
687
688
  size: size,
688
- content_type: contentType ?? defaultContentType,
689
+ content_type: contentType || defaultContentType,
689
690
  part_size: multipartChunkSize,
690
691
  UPLOADCARE_STORE: getStoreValue(store),
691
692
  UPLOADCARE_PUB_KEY: publicKey,
@@ -762,6 +763,28 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
762
763
  }), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
763
764
  }
764
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
+
765
788
  class UploadcareFile {
766
789
  constructor(fileInfo, { baseCDN, fileName }) {
767
790
  this.name = null;
@@ -799,28 +822,6 @@ class UploadcareFile {
799
822
  }
800
823
  }
801
824
 
802
- function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
803
- return poll({
804
- check: (signal) => info(file, {
805
- publicKey,
806
- baseURL,
807
- signal,
808
- source,
809
- integration,
810
- userAgent,
811
- retryThrottledRequestMaxTimes,
812
- retryNetworkErrorMaxTimes
813
- }).then((response) => {
814
- if (response.isReady) {
815
- return response;
816
- }
817
- onProgress && onProgress({ isComputable: true, value: 1 });
818
- return false;
819
- }),
820
- signal
821
- });
822
- }
823
-
824
825
  const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN, metadata }) => {
825
826
  return base(file, {
826
827
  publicKey,
@@ -856,6 +857,29 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
856
857
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
857
858
  };
858
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
+
859
883
  const race = (fns, { signal } = {}) => {
860
884
  let lastError = null;
861
885
  let winnerIndex = null;
@@ -1195,35 +1219,30 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
1195
1219
  }))
1196
1220
  .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
1197
1221
 
1198
- const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN }) => {
1199
- return info(uuid, {
1200
- publicKey,
1201
- baseURL,
1202
- signal,
1203
- source,
1204
- integration,
1205
- userAgent,
1206
- retryThrottledRequestMaxTimes,
1207
- retryNetworkErrorMaxTimes
1208
- })
1209
- .then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
1210
- .then((result) => {
1211
- // hack for node ¯\_(ツ)_/¯
1212
- if (onProgress)
1213
- onProgress({
1214
- isComputable: true,
1215
- value: 1
1216
- });
1217
- return result;
1218
- });
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;
1219
1230
  };
1220
1231
 
1221
- /**
1222
- * Get file size.
1223
- */
1224
- const getFileSize = (file) => {
1225
- 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}`);
1226
1244
  };
1245
+
1227
1246
  /**
1228
1247
  * Check if FileData is multipart data.
1229
1248
  */
@@ -1231,28 +1250,24 @@ const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartM
1231
1250
  return fileSize >= multipartMinFileSize;
1232
1251
  };
1233
1252
 
1234
- const sliceChunk = (file, index, fileSize, chunkSize) => {
1235
- const start = chunkSize * index;
1236
- const end = Math.min(start + chunkSize, fileSize);
1237
- 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);
1238
1260
  };
1239
-
1240
1261
  /**
1241
- * React-native hack for blob slicing
1242
- *
1243
- * We need to store references to sliced blobs to prevent source blob from
1244
- * being deallocated until uploading complete. Access to deallocated blob
1245
- * causes app crash.
1262
+ * Url type guard.
1246
1263
  *
1247
- * See https://github.com/uploadcare/uploadcare-js-api-clients/issues/306
1248
- * and https://github.com/facebook/react-native/issues/27543
1264
+ * @param {AnyFile | Url | Uuid} data
1249
1265
  */
1250
- function prepareChunks(file, fileSize, chunkSize) {
1251
- return (index) => {
1252
- const chunk = sliceChunk(file, index, fileSize, chunkSize);
1253
- return chunk;
1254
- };
1255
- }
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
+ };
1256
1271
 
1257
1272
  const runWithConcurrency = (concurrency, tasks) => {
1258
1273
  return new Promise((resolve, reject) => {
@@ -1289,6 +1304,36 @@ const runWithConcurrency = (concurrency, tasks) => {
1289
1304
  });
1290
1305
  };
1291
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
+
1292
1337
  const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes }) => multipartUpload(chunk, url, {
1293
1338
  publicKey,
1294
1339
  onProgress,
@@ -1297,8 +1342,8 @@ const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, re
1297
1342
  retryThrottledRequestMaxTimes,
1298
1343
  retryNetworkErrorMaxTimes
1299
1344
  });
1300
- 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 }) => {
1301
- 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);
1302
1347
  let progressValues;
1303
1348
  const createProgressHandler = (totalChunks, chunkIdx) => {
1304
1349
  if (!onProgress)
@@ -1320,8 +1365,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1320
1365
  };
1321
1366
  return multipartStart(size, {
1322
1367
  publicKey,
1323
- contentType,
1324
- fileName: fileName ?? file.name,
1368
+ contentType: contentType || getContentType(file),
1369
+ fileName: fileName || getFilename(file),
1325
1370
  baseURL,
1326
1371
  secureSignature,
1327
1372
  secureExpire,
@@ -1334,8 +1379,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1334
1379
  retryNetworkErrorMaxTimes,
1335
1380
  metadata
1336
1381
  })
1337
- .then(({ uuid, parts }) => {
1338
- const getChunk = prepareChunks(file, size, multipartChunkSize);
1382
+ .then(async ({ uuid, parts }) => {
1383
+ const getChunk = await prepareChunks(file, size, multipartChunkSize);
1339
1384
  return Promise.all([
1340
1385
  uuid,
1341
1386
  runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPart(getChunk(index), url, {
@@ -1382,14 +1427,15 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
1382
1427
  /**
1383
1428
  * Uploads file from provided data.
1384
1429
  */
1385
- 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 }) {
1386
1431
  if (isFileData(data)) {
1387
- const fileSize = getFileSize(data);
1432
+ const fileSize = await getFileSize(data);
1388
1433
  if (isMultipart(fileSize, multipartMinFileSize)) {
1389
1434
  return uploadMultipart(data, {
1390
1435
  publicKey,
1391
1436
  contentType,
1392
1437
  multipartChunkSize,
1438
+ fileSize,
1393
1439
  fileName,
1394
1440
  baseURL,
1395
1441
  secureSignature,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uploadcare/upload-client",
3
- "version": "6.0.1-alpha.7",
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",