@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.
- package/dist/index.browser.js +179 -143
- package/dist/index.d.ts +62 -55
- package/dist/index.node.js +180 -140
- package/dist/index.react-native.js +211 -165
- package/package.json +1 -1
package/dist/index.browser.js
CHANGED
|
@@ -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 {
|
|
@@ -261,45 +277,24 @@ const getFileOptions = ({ name }) => name ? [name] : [];
|
|
|
261
277
|
const transformFile = identity;
|
|
262
278
|
var getFormData = () => new FormData();
|
|
263
279
|
|
|
264
|
-
const
|
|
265
|
-
return
|
|
280
|
+
const isBlob = (data) => {
|
|
281
|
+
return typeof Blob !== 'undefined' && data instanceof Blob;
|
|
266
282
|
};
|
|
267
|
-
const
|
|
268
|
-
return
|
|
269
|
-
!!asset &&
|
|
270
|
-
'uri' in asset &&
|
|
271
|
-
typeof asset.uri === 'string' &&
|
|
272
|
-
isReactNativeUri(asset.uri));
|
|
283
|
+
const isFile = (data) => {
|
|
284
|
+
return typeof File !== 'undefined' && data instanceof File;
|
|
273
285
|
};
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
* FileData type guard.
|
|
277
|
-
*/
|
|
278
|
-
const isFileData = (data) => {
|
|
279
|
-
return (data !== undefined &&
|
|
280
|
-
((typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
281
|
-
(typeof File !== 'undefined' && data instanceof File) ||
|
|
282
|
-
(typeof Buffer !== 'undefined' && data instanceof Buffer) ||
|
|
283
|
-
(typeof data === 'string' && isReactNativeUri(data)) ||
|
|
284
|
-
(typeof data === 'object' && isReactNativeAsset(data))));
|
|
286
|
+
const isBuffer = (data) => {
|
|
287
|
+
return typeof Buffer !== 'undefined' && data instanceof Buffer;
|
|
285
288
|
};
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return !isFileData(data) && regExp.test(data);
|
|
289
|
+
const isReactNativeAsset = (data) => {
|
|
290
|
+
return (!!data &&
|
|
291
|
+
typeof data === 'object' &&
|
|
292
|
+
!Array.isArray(data) &&
|
|
293
|
+
'uri' in data &&
|
|
294
|
+
typeof data.uri === 'string');
|
|
293
295
|
};
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
*
|
|
297
|
-
* @param {NodeFile | BrowserFile | Url | Uuid} data
|
|
298
|
-
*/
|
|
299
|
-
const isUrl = (data) => {
|
|
300
|
-
const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
|
|
301
|
-
const regExp = new RegExp(URL_REGEX);
|
|
302
|
-
return !isFileData(data) && regExp.test(data);
|
|
296
|
+
const isFileData = (data) => {
|
|
297
|
+
return (isBlob(data) || isFile(data) || isBuffer(data) || isReactNativeAsset(data));
|
|
303
298
|
};
|
|
304
299
|
|
|
305
300
|
const isSimpleValue = (value) => {
|
|
@@ -340,11 +335,9 @@ function getFormDataParams(options) {
|
|
|
340
335
|
return params;
|
|
341
336
|
}
|
|
342
337
|
function buildFormData(options) {
|
|
343
|
-
console.log('buildFormData', options);
|
|
344
338
|
const formData = getFormData();
|
|
345
339
|
const paramsList = getFormDataParams(options);
|
|
346
340
|
for (const params of paramsList) {
|
|
347
|
-
console.log('params', params);
|
|
348
341
|
const [key, value, ...rest] = params;
|
|
349
342
|
// node form-data has another signature for append
|
|
350
343
|
formData.append(key, value, ...rest);
|
|
@@ -352,6 +345,19 @@ function buildFormData(options) {
|
|
|
352
345
|
return formData;
|
|
353
346
|
}
|
|
354
347
|
|
|
348
|
+
class UploadClientError extends Error {
|
|
349
|
+
constructor(message, code, request, response, headers) {
|
|
350
|
+
super();
|
|
351
|
+
this.name = 'UploadClientError';
|
|
352
|
+
this.message = message;
|
|
353
|
+
this.code = code;
|
|
354
|
+
this.request = request;
|
|
355
|
+
this.response = response;
|
|
356
|
+
this.headers = headers;
|
|
357
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
355
361
|
const buildSearchParams = (query) => {
|
|
356
362
|
const searchParams = new URLSearchParams();
|
|
357
363
|
for (const [key, value] of Object.entries(query)) {
|
|
@@ -383,26 +389,6 @@ const getUrl = (base, path, query) => {
|
|
|
383
389
|
return url.toString();
|
|
384
390
|
};
|
|
385
391
|
|
|
386
|
-
/*
|
|
387
|
-
Settings for future support:
|
|
388
|
-
parallelDirectUploads: 10,
|
|
389
|
-
*/
|
|
390
|
-
const defaultSettings = {
|
|
391
|
-
baseCDN: 'https://ucarecdn.com',
|
|
392
|
-
baseURL: 'https://upload.uploadcare.com',
|
|
393
|
-
maxContentLength: 50 * 1024 * 1024,
|
|
394
|
-
retryThrottledRequestMaxTimes: 1,
|
|
395
|
-
retryNetworkErrorMaxTimes: 3,
|
|
396
|
-
multipartMinFileSize: 25 * 1024 * 1024,
|
|
397
|
-
multipartChunkSize: 5 * 1024 * 1024,
|
|
398
|
-
multipartMinLastPartSize: 1024 * 1024,
|
|
399
|
-
maxConcurrentRequests: 4,
|
|
400
|
-
pollingTimeoutMilliseconds: 10000,
|
|
401
|
-
pusherKey: '79ae88bd931ea68464d9'
|
|
402
|
-
};
|
|
403
|
-
const defaultContentType = 'application/octet-stream';
|
|
404
|
-
const defaultFilename = 'original';
|
|
405
|
-
|
|
406
392
|
var version = '6.0.0';
|
|
407
393
|
|
|
408
394
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
@@ -415,19 +401,6 @@ function getUserAgent(options) {
|
|
|
415
401
|
});
|
|
416
402
|
}
|
|
417
403
|
|
|
418
|
-
class UploadClientError extends Error {
|
|
419
|
-
constructor(message, code, request, response, headers) {
|
|
420
|
-
super();
|
|
421
|
-
this.name = 'UploadClientError';
|
|
422
|
-
this.message = message;
|
|
423
|
-
this.code = code;
|
|
424
|
-
this.request = request;
|
|
425
|
-
this.response = response;
|
|
426
|
-
this.headers = headers;
|
|
427
|
-
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
404
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
432
405
|
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
433
406
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
@@ -458,6 +431,31 @@ function retryIfFailed(fn, options) {
|
|
|
458
431
|
}));
|
|
459
432
|
}
|
|
460
433
|
|
|
434
|
+
const getContentType = (file) => {
|
|
435
|
+
if (isBlob(file) || isFile(file) || isReactNativeAsset(file)) {
|
|
436
|
+
return file.type || defaultContentType;
|
|
437
|
+
}
|
|
438
|
+
if (isBuffer(file)) {
|
|
439
|
+
return defaultFilename;
|
|
440
|
+
}
|
|
441
|
+
console.warn(`Unknown filename: ${file}. Using default filename: ${defaultFilename}`);
|
|
442
|
+
return defaultFilename;
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const getFilename = (file) => {
|
|
446
|
+
if (isBlob(file) || isBuffer(file)) {
|
|
447
|
+
return defaultFilename;
|
|
448
|
+
}
|
|
449
|
+
if (isFile(file)) {
|
|
450
|
+
return file.name || defaultFilename;
|
|
451
|
+
}
|
|
452
|
+
if (isReactNativeAsset(file)) {
|
|
453
|
+
return file.name || defaultFilename;
|
|
454
|
+
}
|
|
455
|
+
console.warn(`Unknown file type: ${file}. Using default filename: ${defaultFilename}`);
|
|
456
|
+
return defaultFilename;
|
|
457
|
+
};
|
|
458
|
+
|
|
461
459
|
function getStoreValue(store) {
|
|
462
460
|
return typeof store === 'undefined' ? 'auto' : store ? '1' : '0';
|
|
463
461
|
}
|
|
@@ -473,13 +471,13 @@ function base(file, { publicKey, fileName, contentType, baseURL = defaultSetting
|
|
|
473
471
|
jsonerrors: 1
|
|
474
472
|
}),
|
|
475
473
|
headers: {
|
|
476
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
474
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
477
475
|
},
|
|
478
476
|
data: buildFormData({
|
|
479
477
|
file: {
|
|
480
478
|
data: file,
|
|
481
|
-
name: fileName
|
|
482
|
-
contentType
|
|
479
|
+
name: fileName || getFilename(file),
|
|
480
|
+
contentType: contentType || getContentType(file)
|
|
483
481
|
},
|
|
484
482
|
UPLOADCARE_PUB_KEY: publicKey,
|
|
485
483
|
UPLOADCARE_STORE: getStoreValue(store),
|
|
@@ -677,9 +675,9 @@ function multipartStart(size, { publicKey, contentType, fileName, multipartChunk
|
|
|
677
675
|
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
678
676
|
},
|
|
679
677
|
data: buildFormData({
|
|
680
|
-
filename: fileName
|
|
678
|
+
filename: fileName || defaultFilename,
|
|
681
679
|
size: size,
|
|
682
|
-
content_type: contentType
|
|
680
|
+
content_type: contentType || defaultContentType,
|
|
683
681
|
part_size: multipartChunkSize,
|
|
684
682
|
UPLOADCARE_STORE: getStoreValue(store),
|
|
685
683
|
UPLOADCARE_PUB_KEY: publicKey,
|
|
@@ -756,6 +754,28 @@ function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL,
|
|
|
756
754
|
}), { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes });
|
|
757
755
|
}
|
|
758
756
|
|
|
757
|
+
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
758
|
+
return poll({
|
|
759
|
+
check: (signal) => info(file, {
|
|
760
|
+
publicKey,
|
|
761
|
+
baseURL,
|
|
762
|
+
signal,
|
|
763
|
+
source,
|
|
764
|
+
integration,
|
|
765
|
+
userAgent,
|
|
766
|
+
retryThrottledRequestMaxTimes,
|
|
767
|
+
retryNetworkErrorMaxTimes
|
|
768
|
+
}).then((response) => {
|
|
769
|
+
if (response.isReady) {
|
|
770
|
+
return response;
|
|
771
|
+
}
|
|
772
|
+
onProgress && onProgress({ isComputable: true, value: 1 });
|
|
773
|
+
return false;
|
|
774
|
+
}),
|
|
775
|
+
signal
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
|
|
759
779
|
class UploadcareFile {
|
|
760
780
|
constructor(fileInfo, { baseCDN, fileName }) {
|
|
761
781
|
this.name = null;
|
|
@@ -793,28 +813,6 @@ class UploadcareFile {
|
|
|
793
813
|
}
|
|
794
814
|
}
|
|
795
815
|
|
|
796
|
-
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
797
|
-
return poll({
|
|
798
|
-
check: (signal) => info(file, {
|
|
799
|
-
publicKey,
|
|
800
|
-
baseURL,
|
|
801
|
-
signal,
|
|
802
|
-
source,
|
|
803
|
-
integration,
|
|
804
|
-
userAgent,
|
|
805
|
-
retryThrottledRequestMaxTimes,
|
|
806
|
-
retryNetworkErrorMaxTimes
|
|
807
|
-
}).then((response) => {
|
|
808
|
-
if (response.isReady) {
|
|
809
|
-
return response;
|
|
810
|
-
}
|
|
811
|
-
onProgress && onProgress({ isComputable: true, value: 1 });
|
|
812
|
-
return false;
|
|
813
|
-
}),
|
|
814
|
-
signal
|
|
815
|
-
});
|
|
816
|
-
}
|
|
817
|
-
|
|
818
816
|
const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN, metadata }) => {
|
|
819
817
|
return base(file, {
|
|
820
818
|
publicKey,
|
|
@@ -850,6 +848,29 @@ const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, sec
|
|
|
850
848
|
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
851
849
|
};
|
|
852
850
|
|
|
851
|
+
const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, baseCDN }) => {
|
|
852
|
+
return info(uuid, {
|
|
853
|
+
publicKey,
|
|
854
|
+
baseURL,
|
|
855
|
+
signal,
|
|
856
|
+
source,
|
|
857
|
+
integration,
|
|
858
|
+
userAgent,
|
|
859
|
+
retryThrottledRequestMaxTimes,
|
|
860
|
+
retryNetworkErrorMaxTimes
|
|
861
|
+
})
|
|
862
|
+
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
|
|
863
|
+
.then((result) => {
|
|
864
|
+
// hack for node ¯\_(ツ)_/¯
|
|
865
|
+
if (onProgress)
|
|
866
|
+
onProgress({
|
|
867
|
+
isComputable: true,
|
|
868
|
+
value: 1
|
|
869
|
+
});
|
|
870
|
+
return result;
|
|
871
|
+
});
|
|
872
|
+
};
|
|
873
|
+
|
|
853
874
|
const race = (fns, { signal } = {}) => {
|
|
854
875
|
let lastError = null;
|
|
855
876
|
let winnerIndex = null;
|
|
@@ -1189,35 +1210,30 @@ const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, check
|
|
|
1189
1210
|
}))
|
|
1190
1211
|
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
1191
1212
|
|
|
1192
|
-
const
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
retryThrottledRequestMaxTimes,
|
|
1201
|
-
retryNetworkErrorMaxTimes
|
|
1202
|
-
})
|
|
1203
|
-
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
|
|
1204
|
-
.then((result) => {
|
|
1205
|
-
// hack for node ¯\_(ツ)_/¯
|
|
1206
|
-
if (onProgress)
|
|
1207
|
-
onProgress({
|
|
1208
|
-
isComputable: true,
|
|
1209
|
-
value: 1
|
|
1210
|
-
});
|
|
1211
|
-
return result;
|
|
1212
|
-
});
|
|
1213
|
+
const memo = new WeakMap();
|
|
1214
|
+
const getReactNativeBlob = async (asset) => {
|
|
1215
|
+
if (memo.has(asset)) {
|
|
1216
|
+
return memo.get(asset);
|
|
1217
|
+
}
|
|
1218
|
+
const blob = await fetch(asset.uri).then((res) => res.blob());
|
|
1219
|
+
memo.set(asset, blob);
|
|
1220
|
+
return blob;
|
|
1213
1221
|
};
|
|
1214
1222
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1223
|
+
const getFileSize = async (file) => {
|
|
1224
|
+
if (isBuffer(file)) {
|
|
1225
|
+
return file.length;
|
|
1226
|
+
}
|
|
1227
|
+
if (isFile(file) || isBlob(file)) {
|
|
1228
|
+
return file.size;
|
|
1229
|
+
}
|
|
1230
|
+
if (isReactNativeAsset(file)) {
|
|
1231
|
+
const blob = await getReactNativeBlob(file);
|
|
1232
|
+
return blob.size;
|
|
1233
|
+
}
|
|
1234
|
+
throw new Error(`Failed to get file size for file: ${file}`);
|
|
1220
1235
|
};
|
|
1236
|
+
|
|
1221
1237
|
/**
|
|
1222
1238
|
* Check if FileData is multipart data.
|
|
1223
1239
|
*/
|
|
@@ -1225,15 +1241,24 @@ const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartM
|
|
|
1225
1241
|
return fileSize >= multipartMinFileSize;
|
|
1226
1242
|
};
|
|
1227
1243
|
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1244
|
+
/**
|
|
1245
|
+
* Uuid type guard.
|
|
1246
|
+
*/
|
|
1247
|
+
const isUuid = (data) => {
|
|
1248
|
+
const UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
|
|
1249
|
+
const regExp = new RegExp(UUID_REGEX);
|
|
1250
|
+
return !isFileData(data) && regExp.test(data);
|
|
1251
|
+
};
|
|
1252
|
+
/**
|
|
1253
|
+
* Url type guard.
|
|
1254
|
+
*
|
|
1255
|
+
* @param {AnyFile | Url | Uuid} data
|
|
1256
|
+
*/
|
|
1257
|
+
const isUrl = (data) => {
|
|
1258
|
+
const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
|
|
1259
|
+
const regExp = new RegExp(URL_REGEX);
|
|
1260
|
+
return !isFileData(data) && regExp.test(data);
|
|
1232
1261
|
};
|
|
1233
|
-
|
|
1234
|
-
function prepareChunks(file, fileSize, chunkSize) {
|
|
1235
|
-
return (index) => sliceChunk(file, index, fileSize, chunkSize);
|
|
1236
|
-
}
|
|
1237
1262
|
|
|
1238
1263
|
const runWithConcurrency = (concurrency, tasks) => {
|
|
1239
1264
|
return new Promise((resolve, reject) => {
|
|
@@ -1270,6 +1295,16 @@ const runWithConcurrency = (concurrency, tasks) => {
|
|
|
1270
1295
|
});
|
|
1271
1296
|
};
|
|
1272
1297
|
|
|
1298
|
+
const sliceChunk = (file, index, fileSize, chunkSize) => {
|
|
1299
|
+
const start = chunkSize * index;
|
|
1300
|
+
const end = Math.min(start + chunkSize, fileSize);
|
|
1301
|
+
return file.slice(start, end);
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
const prepareChunks = async (file, fileSize, chunkSize) => {
|
|
1305
|
+
return (index) => sliceChunk(file, index, fileSize, chunkSize);
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1273
1308
|
const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes }) => multipartUpload(chunk, url, {
|
|
1274
1309
|
publicKey,
|
|
1275
1310
|
onProgress,
|
|
@@ -1278,8 +1313,8 @@ const uploadPart = (chunk, url, { publicKey, onProgress, signal, integration, re
|
|
|
1278
1313
|
retryThrottledRequestMaxTimes,
|
|
1279
1314
|
retryNetworkErrorMaxTimes
|
|
1280
1315
|
});
|
|
1281
|
-
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 }) => {
|
|
1282
|
-
const size = fileSize || getFileSize(file);
|
|
1316
|
+
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 }) => {
|
|
1317
|
+
const size = fileSize || await getFileSize(file);
|
|
1283
1318
|
let progressValues;
|
|
1284
1319
|
const createProgressHandler = (totalChunks, chunkIdx) => {
|
|
1285
1320
|
if (!onProgress)
|
|
@@ -1301,8 +1336,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
|
|
|
1301
1336
|
};
|
|
1302
1337
|
return multipartStart(size, {
|
|
1303
1338
|
publicKey,
|
|
1304
|
-
contentType,
|
|
1305
|
-
fileName: fileName
|
|
1339
|
+
contentType: contentType || getContentType(file),
|
|
1340
|
+
fileName: fileName || getFilename(file),
|
|
1306
1341
|
baseURL,
|
|
1307
1342
|
secureSignature,
|
|
1308
1343
|
secureExpire,
|
|
@@ -1315,8 +1350,8 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
|
|
|
1315
1350
|
retryNetworkErrorMaxTimes,
|
|
1316
1351
|
metadata
|
|
1317
1352
|
})
|
|
1318
|
-
.then(({ uuid, parts }) => {
|
|
1319
|
-
const getChunk = prepareChunks(file, size, multipartChunkSize);
|
|
1353
|
+
.then(async ({ uuid, parts }) => {
|
|
1354
|
+
const getChunk = await prepareChunks(file, size, multipartChunkSize);
|
|
1320
1355
|
return Promise.all([
|
|
1321
1356
|
uuid,
|
|
1322
1357
|
runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPart(getChunk(index), url, {
|
|
@@ -1363,14 +1398,15 @@ const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureS
|
|
|
1363
1398
|
/**
|
|
1364
1399
|
* Uploads file from provided data.
|
|
1365
1400
|
*/
|
|
1366
|
-
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 }) {
|
|
1401
|
+
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 }) {
|
|
1367
1402
|
if (isFileData(data)) {
|
|
1368
|
-
const fileSize = getFileSize(data);
|
|
1403
|
+
const fileSize = await getFileSize(data);
|
|
1369
1404
|
if (isMultipart(fileSize, multipartMinFileSize)) {
|
|
1370
1405
|
return uploadMultipart(data, {
|
|
1371
1406
|
publicKey,
|
|
1372
1407
|
contentType,
|
|
1373
1408
|
multipartChunkSize,
|
|
1409
|
+
fileSize,
|
|
1374
1410
|
fileName,
|
|
1375
1411
|
baseURL,
|
|
1376
1412
|
secureSignature,
|