@uploadcare/upload-client 5.2.0 → 6.0.1-alpha.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.browser.js +78 -62
- package/dist/index.node.js +164 -148
- package/dist/index.react-native.js +80 -64
- package/package.json +2 -2
package/dist/index.browser.js
CHANGED
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
class UploadClientError extends Error {
|
|
2
|
-
constructor(message, code, request, response, headers) {
|
|
3
|
-
super();
|
|
4
|
-
this.name = 'UploadClientError';
|
|
5
|
-
this.message = message;
|
|
6
|
-
this.code = code;
|
|
7
|
-
this.request = request;
|
|
8
|
-
this.response = response;
|
|
9
|
-
this.headers = headers;
|
|
10
|
-
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
const cancelError = (message = 'Request canceled') => {
|
|
14
|
-
const error = new UploadClientError(message);
|
|
15
|
-
error.isCancel = true;
|
|
16
|
-
return error;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const onCancel = (signal, callback) => {
|
|
20
|
-
if (signal) {
|
|
21
|
-
if (signal.aborted) {
|
|
22
|
-
Promise.resolve().then(callback);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
signal.addEventListener('abort', () => callback(), { once: true });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
1
|
function isObject(o) {
|
|
31
2
|
return Object.prototype.toString.call(o) === '[object Object]';
|
|
32
3
|
}
|
|
@@ -128,6 +99,64 @@ class UploadcareNetworkError extends Error {
|
|
|
128
99
|
}
|
|
129
100
|
}
|
|
130
101
|
|
|
102
|
+
const onCancel = (signal, callback) => {
|
|
103
|
+
if (signal) {
|
|
104
|
+
if (signal.aborted) {
|
|
105
|
+
Promise.resolve().then(callback);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
signal.addEventListener('abort', () => callback(), { once: true });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
class CancelError extends Error {
|
|
114
|
+
constructor(message = 'Request canceled') {
|
|
115
|
+
super(message);
|
|
116
|
+
this.isCancel = true;
|
|
117
|
+
Object.setPrototypeOf(this, CancelError.prototype);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const DEFAULT_INTERVAL = 500;
|
|
122
|
+
const poll = ({ check, interval = DEFAULT_INTERVAL, timeout, signal }) => new Promise((resolve, reject) => {
|
|
123
|
+
let tickTimeoutId;
|
|
124
|
+
let timeoutId;
|
|
125
|
+
onCancel(signal, () => {
|
|
126
|
+
tickTimeoutId && clearTimeout(tickTimeoutId);
|
|
127
|
+
reject(new CancelError('Poll cancelled'));
|
|
128
|
+
});
|
|
129
|
+
if (timeout) {
|
|
130
|
+
timeoutId = setTimeout(() => {
|
|
131
|
+
tickTimeoutId && clearTimeout(tickTimeoutId);
|
|
132
|
+
reject(new CancelError('Timed out'));
|
|
133
|
+
}, timeout);
|
|
134
|
+
}
|
|
135
|
+
const tick = () => {
|
|
136
|
+
try {
|
|
137
|
+
Promise.resolve(check(signal))
|
|
138
|
+
.then((result) => {
|
|
139
|
+
if (result) {
|
|
140
|
+
timeoutId && clearTimeout(timeoutId);
|
|
141
|
+
resolve(result);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
tickTimeoutId = setTimeout(tick, interval);
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
timeoutId && clearTimeout(timeoutId);
|
|
149
|
+
reject(error);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
timeoutId && clearTimeout(timeoutId);
|
|
154
|
+
reject(error);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
tickTimeoutId = setTimeout(tick, 0);
|
|
158
|
+
});
|
|
159
|
+
|
|
131
160
|
const request = ({ method, url, data, headers = {}, signal, onProgress }) => new Promise((resolve, reject) => {
|
|
132
161
|
const xhr = new XMLHttpRequest();
|
|
133
162
|
const requestMethod = method?.toUpperCase() || 'GET';
|
|
@@ -151,7 +180,7 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
|
|
|
151
180
|
onCancel(signal, () => {
|
|
152
181
|
aborted = true;
|
|
153
182
|
xhr.abort();
|
|
154
|
-
reject(
|
|
183
|
+
reject(new CancelError());
|
|
155
184
|
});
|
|
156
185
|
xhr.onload = () => {
|
|
157
186
|
if (xhr.status != 200) {
|
|
@@ -235,7 +264,8 @@ const isFileData = (data) => {
|
|
|
235
264
|
return (data !== undefined &&
|
|
236
265
|
((typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
237
266
|
(typeof File !== 'undefined' && data instanceof File) ||
|
|
238
|
-
(typeof Buffer !== 'undefined' && data instanceof Buffer)
|
|
267
|
+
(typeof Buffer !== 'undefined' && data instanceof Buffer) ||
|
|
268
|
+
(typeof data === 'string' && data.startsWith('file:'))));
|
|
239
269
|
};
|
|
240
270
|
/**
|
|
241
271
|
* Uuid type guard.
|
|
@@ -297,9 +327,9 @@ function buildFormData(options) {
|
|
|
297
327
|
const formData = getFormData();
|
|
298
328
|
const paramsList = getFormDataParams(options);
|
|
299
329
|
for (const params of paramsList) {
|
|
300
|
-
const [key, value, ...
|
|
330
|
+
const [key, value, ...rest] = params;
|
|
301
331
|
// node form-data has another signature for append
|
|
302
|
-
formData.append(key, value, ...
|
|
332
|
+
formData.append(key, value, ...rest);
|
|
303
333
|
}
|
|
304
334
|
return formData;
|
|
305
335
|
}
|
|
@@ -355,7 +385,7 @@ const defaultSettings = {
|
|
|
355
385
|
const defaultContentType = 'application/octet-stream';
|
|
356
386
|
const defaultFilename = 'original';
|
|
357
387
|
|
|
358
|
-
var version = '
|
|
388
|
+
var version = '6.0.0';
|
|
359
389
|
|
|
360
390
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
361
391
|
const LIBRARY_VERSION = version;
|
|
@@ -367,6 +397,19 @@ function getUserAgent(options) {
|
|
|
367
397
|
});
|
|
368
398
|
}
|
|
369
399
|
|
|
400
|
+
class UploadClientError extends Error {
|
|
401
|
+
constructor(message, code, request, response, headers) {
|
|
402
|
+
super();
|
|
403
|
+
this.name = 'UploadClientError';
|
|
404
|
+
this.message = message;
|
|
405
|
+
this.code = code;
|
|
406
|
+
this.request = request;
|
|
407
|
+
this.response = response;
|
|
408
|
+
this.headers = headers;
|
|
409
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
370
413
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
371
414
|
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
372
415
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
@@ -732,33 +775,6 @@ class UploadcareFile {
|
|
|
732
775
|
}
|
|
733
776
|
}
|
|
734
777
|
|
|
735
|
-
const DEFAULT_INTERVAL = 500;
|
|
736
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
737
|
-
let timeoutId;
|
|
738
|
-
onCancel(signal, () => {
|
|
739
|
-
timeoutId && clearTimeout(timeoutId);
|
|
740
|
-
reject(cancelError('Poll cancelled'));
|
|
741
|
-
});
|
|
742
|
-
const tick = () => {
|
|
743
|
-
try {
|
|
744
|
-
Promise.resolve(check(signal))
|
|
745
|
-
.then((result) => {
|
|
746
|
-
if (result) {
|
|
747
|
-
resolve(result);
|
|
748
|
-
}
|
|
749
|
-
else {
|
|
750
|
-
timeoutId = setTimeout(tick, interval);
|
|
751
|
-
}
|
|
752
|
-
})
|
|
753
|
-
.catch((error) => reject(error));
|
|
754
|
-
}
|
|
755
|
-
catch (error) {
|
|
756
|
-
reject(error);
|
|
757
|
-
}
|
|
758
|
-
};
|
|
759
|
-
timeoutId = setTimeout(tick, 0);
|
|
760
|
-
});
|
|
761
|
-
|
|
762
778
|
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
763
779
|
return poll({
|
|
764
780
|
check: (signal) => info(file, {
|
|
@@ -1056,7 +1072,7 @@ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((
|
|
|
1056
1072
|
};
|
|
1057
1073
|
onCancel(signal, () => {
|
|
1058
1074
|
destroy();
|
|
1059
|
-
reject(
|
|
1075
|
+
reject(new CancelError('pusher cancelled'));
|
|
1060
1076
|
});
|
|
1061
1077
|
pusher.subscribe(token, (result) => {
|
|
1062
1078
|
switch (result.status) {
|
package/dist/index.node.js
CHANGED
|
@@ -5,23 +5,106 @@ import { Transform, Readable } from 'stream';
|
|
|
5
5
|
import NodeFormData from 'form-data';
|
|
6
6
|
import WebSocket from 'ws';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
function isObject(o) {
|
|
9
|
+
return Object.prototype.toString.call(o) === '[object Object]';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const SEPARATOR = /\W|_/g;
|
|
13
|
+
function camelizeString(text) {
|
|
14
|
+
return text
|
|
15
|
+
.split(SEPARATOR)
|
|
16
|
+
.map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
|
|
17
|
+
word.slice(1))
|
|
18
|
+
.join('');
|
|
19
|
+
}
|
|
20
|
+
function camelizeArrayItems(array, { ignoreKeys } = { ignoreKeys: [] }) {
|
|
21
|
+
if (!Array.isArray(array)) {
|
|
22
|
+
return array;
|
|
23
|
+
}
|
|
24
|
+
return array.map((item) => camelizeKeys(item, { ignoreKeys }));
|
|
25
|
+
}
|
|
26
|
+
function camelizeKeys(source, { ignoreKeys } = { ignoreKeys: [] }) {
|
|
27
|
+
if (Array.isArray(source)) {
|
|
28
|
+
return camelizeArrayItems(source, { ignoreKeys });
|
|
29
|
+
}
|
|
30
|
+
if (!isObject(source)) {
|
|
31
|
+
return source;
|
|
32
|
+
}
|
|
33
|
+
const result = {};
|
|
34
|
+
for (const key of Object.keys(source)) {
|
|
35
|
+
let value = source[key];
|
|
36
|
+
if (ignoreKeys.includes(key)) {
|
|
37
|
+
result[key] = value;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (isObject(value)) {
|
|
41
|
+
value = camelizeKeys(value, { ignoreKeys });
|
|
42
|
+
}
|
|
43
|
+
else if (Array.isArray(value)) {
|
|
44
|
+
value = camelizeArrayItems(value, { ignoreKeys });
|
|
45
|
+
}
|
|
46
|
+
result[camelizeString(key)] = value;
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* setTimeout as Promise.
|
|
53
|
+
*
|
|
54
|
+
* @param {number} ms Timeout in milliseconds.
|
|
55
|
+
*/
|
|
56
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
57
|
+
|
|
58
|
+
function getUserAgent$1({ libraryName, libraryVersion, userAgent, publicKey = '', integration = '' }) {
|
|
59
|
+
const languageName = 'JavaScript';
|
|
60
|
+
if (typeof userAgent === 'string') {
|
|
61
|
+
return userAgent;
|
|
62
|
+
}
|
|
63
|
+
if (typeof userAgent === 'function') {
|
|
64
|
+
return userAgent({
|
|
65
|
+
publicKey,
|
|
66
|
+
libraryName,
|
|
67
|
+
libraryVersion,
|
|
68
|
+
languageName,
|
|
69
|
+
integration
|
|
70
|
+
});
|
|
18
71
|
}
|
|
72
|
+
const mainInfo = [libraryName, libraryVersion, publicKey]
|
|
73
|
+
.filter(Boolean)
|
|
74
|
+
.join('/');
|
|
75
|
+
const additionInfo = [languageName, integration].filter(Boolean).join('; ');
|
|
76
|
+
return `${mainInfo} (${additionInfo})`;
|
|
19
77
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
78
|
+
|
|
79
|
+
const defaultOptions = {
|
|
80
|
+
factor: 2,
|
|
81
|
+
time: 100
|
|
24
82
|
};
|
|
83
|
+
function retrier(fn, options = defaultOptions) {
|
|
84
|
+
let attempts = 0;
|
|
85
|
+
function runAttempt(fn) {
|
|
86
|
+
const defaultDelayTime = Math.round(options.time * options.factor ** attempts);
|
|
87
|
+
const retry = (ms) => delay(ms ?? defaultDelayTime).then(() => {
|
|
88
|
+
attempts += 1;
|
|
89
|
+
return runAttempt(fn);
|
|
90
|
+
});
|
|
91
|
+
return fn({
|
|
92
|
+
attempt: attempts,
|
|
93
|
+
retry
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return runAttempt(fn);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
class UploadcareNetworkError extends Error {
|
|
100
|
+
constructor(progressEvent) {
|
|
101
|
+
super();
|
|
102
|
+
this.name = 'UploadcareNetworkError';
|
|
103
|
+
this.message = 'Network error';
|
|
104
|
+
Object.setPrototypeOf(this, UploadcareNetworkError.prototype);
|
|
105
|
+
this.originalProgressEvent = progressEvent;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
25
108
|
|
|
26
109
|
const onCancel = (signal, callback) => {
|
|
27
110
|
if (signal) {
|
|
@@ -34,6 +117,53 @@ const onCancel = (signal, callback) => {
|
|
|
34
117
|
}
|
|
35
118
|
};
|
|
36
119
|
|
|
120
|
+
class CancelError extends Error {
|
|
121
|
+
constructor(message = 'Request canceled') {
|
|
122
|
+
super(message);
|
|
123
|
+
this.isCancel = true;
|
|
124
|
+
Object.setPrototypeOf(this, CancelError.prototype);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const DEFAULT_INTERVAL = 500;
|
|
129
|
+
const poll = ({ check, interval = DEFAULT_INTERVAL, timeout, signal }) => new Promise((resolve, reject) => {
|
|
130
|
+
let tickTimeoutId;
|
|
131
|
+
let timeoutId;
|
|
132
|
+
onCancel(signal, () => {
|
|
133
|
+
tickTimeoutId && clearTimeout(tickTimeoutId);
|
|
134
|
+
reject(new CancelError('Poll cancelled'));
|
|
135
|
+
});
|
|
136
|
+
if (timeout) {
|
|
137
|
+
timeoutId = setTimeout(() => {
|
|
138
|
+
tickTimeoutId && clearTimeout(tickTimeoutId);
|
|
139
|
+
reject(new CancelError('Timed out'));
|
|
140
|
+
}, timeout);
|
|
141
|
+
}
|
|
142
|
+
const tick = () => {
|
|
143
|
+
try {
|
|
144
|
+
Promise.resolve(check(signal))
|
|
145
|
+
.then((result) => {
|
|
146
|
+
if (result) {
|
|
147
|
+
timeoutId && clearTimeout(timeoutId);
|
|
148
|
+
resolve(result);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
tickTimeoutId = setTimeout(tick, interval);
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
.catch((error) => {
|
|
155
|
+
timeoutId && clearTimeout(timeoutId);
|
|
156
|
+
reject(error);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
timeoutId && clearTimeout(timeoutId);
|
|
161
|
+
reject(error);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
tickTimeoutId = setTimeout(tick, 0);
|
|
165
|
+
});
|
|
166
|
+
|
|
37
167
|
// ProgressEmitter is a simple PassThrough-style transform stream which keeps
|
|
38
168
|
// track of the number of bytes which have been piped through it and will
|
|
39
169
|
// invoke the `onprogress` function whenever new number are available.
|
|
@@ -102,7 +232,7 @@ const request = (params) => {
|
|
|
102
232
|
onCancel(signal, () => {
|
|
103
233
|
aborted = true;
|
|
104
234
|
req.abort();
|
|
105
|
-
reject(
|
|
235
|
+
reject(new CancelError());
|
|
106
236
|
});
|
|
107
237
|
req.on('response', (res) => {
|
|
108
238
|
if (aborted)
|
|
@@ -162,7 +292,8 @@ const isFileData = (data) => {
|
|
|
162
292
|
return (data !== undefined &&
|
|
163
293
|
((typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
164
294
|
(typeof File !== 'undefined' && data instanceof File) ||
|
|
165
|
-
(typeof Buffer !== 'undefined' && data instanceof Buffer)
|
|
295
|
+
(typeof Buffer !== 'undefined' && data instanceof Buffer) ||
|
|
296
|
+
(typeof data === 'string' && data.startsWith('file:'))));
|
|
166
297
|
};
|
|
167
298
|
/**
|
|
168
299
|
* Uuid type guard.
|
|
@@ -224,9 +355,9 @@ function buildFormData(options) {
|
|
|
224
355
|
const formData = getFormData();
|
|
225
356
|
const paramsList = getFormDataParams(options);
|
|
226
357
|
for (const params of paramsList) {
|
|
227
|
-
const [key, value, ...
|
|
358
|
+
const [key, value, ...rest] = params;
|
|
228
359
|
// node form-data has another signature for append
|
|
229
|
-
formData.append(key, value, ...
|
|
360
|
+
formData.append(key, value, ...rest);
|
|
230
361
|
}
|
|
231
362
|
return formData;
|
|
232
363
|
}
|
|
@@ -282,108 +413,7 @@ const defaultSettings = {
|
|
|
282
413
|
const defaultContentType = 'application/octet-stream';
|
|
283
414
|
const defaultFilename = 'original';
|
|
284
415
|
|
|
285
|
-
var version = '
|
|
286
|
-
|
|
287
|
-
function isObject(o) {
|
|
288
|
-
return Object.prototype.toString.call(o) === '[object Object]';
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const SEPARATOR = /\W|_/g;
|
|
292
|
-
function camelizeString(text) {
|
|
293
|
-
return text
|
|
294
|
-
.split(SEPARATOR)
|
|
295
|
-
.map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
|
|
296
|
-
word.slice(1))
|
|
297
|
-
.join('');
|
|
298
|
-
}
|
|
299
|
-
function camelizeArrayItems(array, { ignoreKeys } = { ignoreKeys: [] }) {
|
|
300
|
-
if (!Array.isArray(array)) {
|
|
301
|
-
return array;
|
|
302
|
-
}
|
|
303
|
-
return array.map((item) => camelizeKeys(item, { ignoreKeys }));
|
|
304
|
-
}
|
|
305
|
-
function camelizeKeys(source, { ignoreKeys } = { ignoreKeys: [] }) {
|
|
306
|
-
if (Array.isArray(source)) {
|
|
307
|
-
return camelizeArrayItems(source, { ignoreKeys });
|
|
308
|
-
}
|
|
309
|
-
if (!isObject(source)) {
|
|
310
|
-
return source;
|
|
311
|
-
}
|
|
312
|
-
const result = {};
|
|
313
|
-
for (const key of Object.keys(source)) {
|
|
314
|
-
let value = source[key];
|
|
315
|
-
if (ignoreKeys.includes(key)) {
|
|
316
|
-
result[key] = value;
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
if (isObject(value)) {
|
|
320
|
-
value = camelizeKeys(value, { ignoreKeys });
|
|
321
|
-
}
|
|
322
|
-
else if (Array.isArray(value)) {
|
|
323
|
-
value = camelizeArrayItems(value, { ignoreKeys });
|
|
324
|
-
}
|
|
325
|
-
result[camelizeString(key)] = value;
|
|
326
|
-
}
|
|
327
|
-
return result;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* setTimeout as Promise.
|
|
332
|
-
*
|
|
333
|
-
* @param {number} ms Timeout in milliseconds.
|
|
334
|
-
*/
|
|
335
|
-
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
336
|
-
|
|
337
|
-
function getUserAgent$1({ libraryName, libraryVersion, userAgent, publicKey = '', integration = '' }) {
|
|
338
|
-
const languageName = 'JavaScript';
|
|
339
|
-
if (typeof userAgent === 'string') {
|
|
340
|
-
return userAgent;
|
|
341
|
-
}
|
|
342
|
-
if (typeof userAgent === 'function') {
|
|
343
|
-
return userAgent({
|
|
344
|
-
publicKey,
|
|
345
|
-
libraryName,
|
|
346
|
-
libraryVersion,
|
|
347
|
-
languageName,
|
|
348
|
-
integration
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
const mainInfo = [libraryName, libraryVersion, publicKey]
|
|
352
|
-
.filter(Boolean)
|
|
353
|
-
.join('/');
|
|
354
|
-
const additionInfo = [languageName, integration].filter(Boolean).join('; ');
|
|
355
|
-
return `${mainInfo} (${additionInfo})`;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const defaultOptions = {
|
|
359
|
-
factor: 2,
|
|
360
|
-
time: 100
|
|
361
|
-
};
|
|
362
|
-
function retrier(fn, options = defaultOptions) {
|
|
363
|
-
let attempts = 0;
|
|
364
|
-
function runAttempt(fn) {
|
|
365
|
-
const defaultDelayTime = Math.round(options.time * options.factor ** attempts);
|
|
366
|
-
const retry = (ms) => delay(ms ?? defaultDelayTime).then(() => {
|
|
367
|
-
attempts += 1;
|
|
368
|
-
return runAttempt(fn);
|
|
369
|
-
});
|
|
370
|
-
return fn({
|
|
371
|
-
attempt: attempts,
|
|
372
|
-
retry
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
return runAttempt(fn);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
class UploadcareNetworkError extends Error {
|
|
379
|
-
constructor(progressEvent) {
|
|
380
|
-
super();
|
|
381
|
-
this.name = 'UploadcareNetworkError';
|
|
382
|
-
this.message = 'Network error';
|
|
383
|
-
Object.setPrototypeOf(this, UploadcareNetworkError.prototype);
|
|
384
|
-
this.originalProgressEvent = progressEvent;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
416
|
+
var version = '6.0.0';
|
|
387
417
|
|
|
388
418
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
389
419
|
const LIBRARY_VERSION = version;
|
|
@@ -395,6 +425,19 @@ function getUserAgent(options) {
|
|
|
395
425
|
});
|
|
396
426
|
}
|
|
397
427
|
|
|
428
|
+
class UploadClientError extends Error {
|
|
429
|
+
constructor(message, code, request, response, headers) {
|
|
430
|
+
super();
|
|
431
|
+
this.name = 'UploadClientError';
|
|
432
|
+
this.message = message;
|
|
433
|
+
this.code = code;
|
|
434
|
+
this.request = request;
|
|
435
|
+
this.response = response;
|
|
436
|
+
this.headers = headers;
|
|
437
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
398
441
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
399
442
|
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
400
443
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
@@ -760,33 +803,6 @@ class UploadcareFile {
|
|
|
760
803
|
}
|
|
761
804
|
}
|
|
762
805
|
|
|
763
|
-
const DEFAULT_INTERVAL = 500;
|
|
764
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
765
|
-
let timeoutId;
|
|
766
|
-
onCancel(signal, () => {
|
|
767
|
-
timeoutId && clearTimeout(timeoutId);
|
|
768
|
-
reject(cancelError('Poll cancelled'));
|
|
769
|
-
});
|
|
770
|
-
const tick = () => {
|
|
771
|
-
try {
|
|
772
|
-
Promise.resolve(check(signal))
|
|
773
|
-
.then((result) => {
|
|
774
|
-
if (result) {
|
|
775
|
-
resolve(result);
|
|
776
|
-
}
|
|
777
|
-
else {
|
|
778
|
-
timeoutId = setTimeout(tick, interval);
|
|
779
|
-
}
|
|
780
|
-
})
|
|
781
|
-
.catch((error) => reject(error));
|
|
782
|
-
}
|
|
783
|
-
catch (error) {
|
|
784
|
-
reject(error);
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
timeoutId = setTimeout(tick, 0);
|
|
788
|
-
});
|
|
789
|
-
|
|
790
806
|
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
791
807
|
return poll({
|
|
792
808
|
check: (signal) => info(file, {
|
|
@@ -1082,7 +1098,7 @@ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((
|
|
|
1082
1098
|
};
|
|
1083
1099
|
onCancel(signal, () => {
|
|
1084
1100
|
destroy();
|
|
1085
|
-
reject(
|
|
1101
|
+
reject(new CancelError('pusher cancelled'));
|
|
1086
1102
|
});
|
|
1087
1103
|
pusher.subscribe(token, (result) => {
|
|
1088
1104
|
switch (result.status) {
|
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
class UploadClientError extends Error {
|
|
2
|
-
constructor(message, code, request, response, headers) {
|
|
3
|
-
super();
|
|
4
|
-
this.name = 'UploadClientError';
|
|
5
|
-
this.message = message;
|
|
6
|
-
this.code = code;
|
|
7
|
-
this.request = request;
|
|
8
|
-
this.response = response;
|
|
9
|
-
this.headers = headers;
|
|
10
|
-
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
const cancelError = (message = 'Request canceled') => {
|
|
14
|
-
const error = new UploadClientError(message);
|
|
15
|
-
error.isCancel = true;
|
|
16
|
-
return error;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const onCancel = (signal, callback) => {
|
|
20
|
-
if (signal) {
|
|
21
|
-
if (signal.aborted) {
|
|
22
|
-
Promise.resolve().then(callback);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
signal.addEventListener('abort', () => callback(), { once: true });
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
1
|
function isObject(o) {
|
|
31
2
|
return Object.prototype.toString.call(o) === '[object Object]';
|
|
32
3
|
}
|
|
@@ -128,6 +99,64 @@ class UploadcareNetworkError extends Error {
|
|
|
128
99
|
}
|
|
129
100
|
}
|
|
130
101
|
|
|
102
|
+
const onCancel = (signal, callback) => {
|
|
103
|
+
if (signal) {
|
|
104
|
+
if (signal.aborted) {
|
|
105
|
+
Promise.resolve().then(callback);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
signal.addEventListener('abort', () => callback(), { once: true });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
class CancelError extends Error {
|
|
114
|
+
constructor(message = 'Request canceled') {
|
|
115
|
+
super(message);
|
|
116
|
+
this.isCancel = true;
|
|
117
|
+
Object.setPrototypeOf(this, CancelError.prototype);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const DEFAULT_INTERVAL = 500;
|
|
122
|
+
const poll = ({ check, interval = DEFAULT_INTERVAL, timeout, signal }) => new Promise((resolve, reject) => {
|
|
123
|
+
let tickTimeoutId;
|
|
124
|
+
let timeoutId;
|
|
125
|
+
onCancel(signal, () => {
|
|
126
|
+
tickTimeoutId && clearTimeout(tickTimeoutId);
|
|
127
|
+
reject(new CancelError('Poll cancelled'));
|
|
128
|
+
});
|
|
129
|
+
if (timeout) {
|
|
130
|
+
timeoutId = setTimeout(() => {
|
|
131
|
+
tickTimeoutId && clearTimeout(tickTimeoutId);
|
|
132
|
+
reject(new CancelError('Timed out'));
|
|
133
|
+
}, timeout);
|
|
134
|
+
}
|
|
135
|
+
const tick = () => {
|
|
136
|
+
try {
|
|
137
|
+
Promise.resolve(check(signal))
|
|
138
|
+
.then((result) => {
|
|
139
|
+
if (result) {
|
|
140
|
+
timeoutId && clearTimeout(timeoutId);
|
|
141
|
+
resolve(result);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
tickTimeoutId = setTimeout(tick, interval);
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
timeoutId && clearTimeout(timeoutId);
|
|
149
|
+
reject(error);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
timeoutId && clearTimeout(timeoutId);
|
|
154
|
+
reject(error);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
tickTimeoutId = setTimeout(tick, 0);
|
|
158
|
+
});
|
|
159
|
+
|
|
131
160
|
const request = ({ method, url, data, headers = {}, signal, onProgress }) => new Promise((resolve, reject) => {
|
|
132
161
|
const xhr = new XMLHttpRequest();
|
|
133
162
|
const requestMethod = method?.toUpperCase() || 'GET';
|
|
@@ -151,7 +180,7 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
|
|
|
151
180
|
onCancel(signal, () => {
|
|
152
181
|
aborted = true;
|
|
153
182
|
xhr.abort();
|
|
154
|
-
reject(
|
|
183
|
+
reject(new CancelError());
|
|
155
184
|
});
|
|
156
185
|
xhr.onload = () => {
|
|
157
186
|
if (xhr.status != 200) {
|
|
@@ -222,8 +251,8 @@ const request = ({ method, url, data, headers = {}, signal, onProgress }) => new
|
|
|
222
251
|
|
|
223
252
|
const getFileOptions = ({ name }) => name ? [name] : [];
|
|
224
253
|
const transformFile = (file, name) => {
|
|
225
|
-
if (
|
|
226
|
-
return file;
|
|
254
|
+
if (typeof file === 'string' && file.startsWith('file:')) {
|
|
255
|
+
return { uri: file, name };
|
|
227
256
|
}
|
|
228
257
|
const uri = URL.createObjectURL(file);
|
|
229
258
|
const type = file.type;
|
|
@@ -238,7 +267,8 @@ const isFileData = (data) => {
|
|
|
238
267
|
return (data !== undefined &&
|
|
239
268
|
((typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
240
269
|
(typeof File !== 'undefined' && data instanceof File) ||
|
|
241
|
-
(typeof Buffer !== 'undefined' && data instanceof Buffer)
|
|
270
|
+
(typeof Buffer !== 'undefined' && data instanceof Buffer) ||
|
|
271
|
+
(typeof data === 'string' && data.startsWith('file:'))));
|
|
242
272
|
};
|
|
243
273
|
/**
|
|
244
274
|
* Uuid type guard.
|
|
@@ -300,9 +330,9 @@ function buildFormData(options) {
|
|
|
300
330
|
const formData = getFormData();
|
|
301
331
|
const paramsList = getFormDataParams(options);
|
|
302
332
|
for (const params of paramsList) {
|
|
303
|
-
const [key, value, ...
|
|
333
|
+
const [key, value, ...rest] = params;
|
|
304
334
|
// node form-data has another signature for append
|
|
305
|
-
formData.append(key, value, ...
|
|
335
|
+
formData.append(key, value, ...rest);
|
|
306
336
|
}
|
|
307
337
|
return formData;
|
|
308
338
|
}
|
|
@@ -358,7 +388,7 @@ const defaultSettings = {
|
|
|
358
388
|
const defaultContentType = 'application/octet-stream';
|
|
359
389
|
const defaultFilename = 'original';
|
|
360
390
|
|
|
361
|
-
var version = '
|
|
391
|
+
var version = '6.0.0';
|
|
362
392
|
|
|
363
393
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
364
394
|
const LIBRARY_VERSION = version;
|
|
@@ -370,6 +400,19 @@ function getUserAgent(options) {
|
|
|
370
400
|
});
|
|
371
401
|
}
|
|
372
402
|
|
|
403
|
+
class UploadClientError extends Error {
|
|
404
|
+
constructor(message, code, request, response, headers) {
|
|
405
|
+
super();
|
|
406
|
+
this.name = 'UploadClientError';
|
|
407
|
+
this.message = message;
|
|
408
|
+
this.code = code;
|
|
409
|
+
this.request = request;
|
|
410
|
+
this.response = response;
|
|
411
|
+
this.headers = headers;
|
|
412
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
373
416
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
374
417
|
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
375
418
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
@@ -735,33 +778,6 @@ class UploadcareFile {
|
|
|
735
778
|
}
|
|
736
779
|
}
|
|
737
780
|
|
|
738
|
-
const DEFAULT_INTERVAL = 500;
|
|
739
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
740
|
-
let timeoutId;
|
|
741
|
-
onCancel(signal, () => {
|
|
742
|
-
timeoutId && clearTimeout(timeoutId);
|
|
743
|
-
reject(cancelError('Poll cancelled'));
|
|
744
|
-
});
|
|
745
|
-
const tick = () => {
|
|
746
|
-
try {
|
|
747
|
-
Promise.resolve(check(signal))
|
|
748
|
-
.then((result) => {
|
|
749
|
-
if (result) {
|
|
750
|
-
resolve(result);
|
|
751
|
-
}
|
|
752
|
-
else {
|
|
753
|
-
timeoutId = setTimeout(tick, interval);
|
|
754
|
-
}
|
|
755
|
-
})
|
|
756
|
-
.catch((error) => reject(error));
|
|
757
|
-
}
|
|
758
|
-
catch (error) {
|
|
759
|
-
reject(error);
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
timeoutId = setTimeout(tick, 0);
|
|
763
|
-
});
|
|
764
|
-
|
|
765
781
|
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
766
782
|
return poll({
|
|
767
783
|
check: (signal) => info(file, {
|
|
@@ -1059,7 +1075,7 @@ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((
|
|
|
1059
1075
|
};
|
|
1060
1076
|
onCancel(signal, () => {
|
|
1061
1077
|
destroy();
|
|
1062
|
-
reject(
|
|
1078
|
+
reject(new CancelError('pusher cancelled'));
|
|
1063
1079
|
});
|
|
1064
1080
|
pusher.subscribe(token, (result) => {
|
|
1065
1081
|
switch (result.status) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uploadcare/upload-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1-alpha.0",
|
|
4
4
|
"description": "Library for work with Uploadcare Upload API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.node.js",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"koa-body": "5.0.0",
|
|
79
79
|
"mock-socket": "9.0.3",
|
|
80
80
|
"start-server-and-test": "1.14.0",
|
|
81
|
-
"@uploadcare/api-client-utils": "^
|
|
81
|
+
"@uploadcare/api-client-utils": "^6.0.0",
|
|
82
82
|
"chalk": "^4.1.2"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|