@uploadcare/upload-client 5.1.2 → 6.0.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 +83 -63
- package/dist/index.node.js +169 -149
- package/dist/index.react-native.js +83 -63
- 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) {
|
|
@@ -355,7 +384,7 @@ const defaultSettings = {
|
|
|
355
384
|
const defaultContentType = 'application/octet-stream';
|
|
356
385
|
const defaultFilename = 'original';
|
|
357
386
|
|
|
358
|
-
var version = '
|
|
387
|
+
var version = '6.0.0';
|
|
359
388
|
|
|
360
389
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
361
390
|
const LIBRARY_VERSION = version;
|
|
@@ -367,14 +396,32 @@ function getUserAgent(options) {
|
|
|
367
396
|
});
|
|
368
397
|
}
|
|
369
398
|
|
|
399
|
+
class UploadClientError extends Error {
|
|
400
|
+
constructor(message, code, request, response, headers) {
|
|
401
|
+
super();
|
|
402
|
+
this.name = 'UploadClientError';
|
|
403
|
+
this.message = message;
|
|
404
|
+
this.code = code;
|
|
405
|
+
this.request = request;
|
|
406
|
+
this.response = response;
|
|
407
|
+
this.headers = headers;
|
|
408
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
370
412
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
371
|
-
const
|
|
413
|
+
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
372
414
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
373
415
|
function getTimeoutFromThrottledRequest(error) {
|
|
374
416
|
const { headers } = error || {};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
417
|
+
if (!headers || typeof headers['retry-after'] !== 'string') {
|
|
418
|
+
return DEFAULT_RETRY_AFTER_TIMEOUT;
|
|
419
|
+
}
|
|
420
|
+
const seconds = parseInt(headers['retry-after'], 10);
|
|
421
|
+
if (!Number.isFinite(seconds)) {
|
|
422
|
+
return DEFAULT_RETRY_AFTER_TIMEOUT;
|
|
423
|
+
}
|
|
424
|
+
return seconds * 1000;
|
|
378
425
|
}
|
|
379
426
|
function retryIfFailed(fn, options) {
|
|
380
427
|
const { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes } = options;
|
|
@@ -727,33 +774,6 @@ class UploadcareFile {
|
|
|
727
774
|
}
|
|
728
775
|
}
|
|
729
776
|
|
|
730
|
-
const DEFAULT_INTERVAL = 500;
|
|
731
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
732
|
-
let timeoutId;
|
|
733
|
-
onCancel(signal, () => {
|
|
734
|
-
timeoutId && clearTimeout(timeoutId);
|
|
735
|
-
reject(cancelError('Poll cancelled'));
|
|
736
|
-
});
|
|
737
|
-
const tick = () => {
|
|
738
|
-
try {
|
|
739
|
-
Promise.resolve(check(signal))
|
|
740
|
-
.then((result) => {
|
|
741
|
-
if (result) {
|
|
742
|
-
resolve(result);
|
|
743
|
-
}
|
|
744
|
-
else {
|
|
745
|
-
timeoutId = setTimeout(tick, interval);
|
|
746
|
-
}
|
|
747
|
-
})
|
|
748
|
-
.catch((error) => reject(error));
|
|
749
|
-
}
|
|
750
|
-
catch (error) {
|
|
751
|
-
reject(error);
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
timeoutId = setTimeout(tick, 0);
|
|
755
|
-
});
|
|
756
|
-
|
|
757
777
|
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
758
778
|
return poll({
|
|
759
779
|
check: (signal) => info(file, {
|
|
@@ -1051,7 +1071,7 @@ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((
|
|
|
1051
1071
|
};
|
|
1052
1072
|
onCancel(signal, () => {
|
|
1053
1073
|
destroy();
|
|
1054
|
-
reject(
|
|
1074
|
+
reject(new CancelError('pusher cancelled'));
|
|
1055
1075
|
});
|
|
1056
1076
|
pusher.subscribe(token, (result) => {
|
|
1057
1077
|
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;
|
|
18
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;
|
|
19
49
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const mainInfo = [libraryName, libraryVersion, publicKey]
|
|
73
|
+
.filter(Boolean)
|
|
74
|
+
.join('/');
|
|
75
|
+
const additionInfo = [languageName, integration].filter(Boolean).join('; ');
|
|
76
|
+
return `${mainInfo} (${additionInfo})`;
|
|
77
|
+
}
|
|
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)
|
|
@@ -282,108 +412,7 @@ const defaultSettings = {
|
|
|
282
412
|
const defaultContentType = 'application/octet-stream';
|
|
283
413
|
const defaultFilename = 'original';
|
|
284
414
|
|
|
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
|
-
}
|
|
415
|
+
var version = '6.0.0';
|
|
387
416
|
|
|
388
417
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
389
418
|
const LIBRARY_VERSION = version;
|
|
@@ -395,14 +424,32 @@ function getUserAgent(options) {
|
|
|
395
424
|
});
|
|
396
425
|
}
|
|
397
426
|
|
|
427
|
+
class UploadClientError extends Error {
|
|
428
|
+
constructor(message, code, request, response, headers) {
|
|
429
|
+
super();
|
|
430
|
+
this.name = 'UploadClientError';
|
|
431
|
+
this.message = message;
|
|
432
|
+
this.code = code;
|
|
433
|
+
this.request = request;
|
|
434
|
+
this.response = response;
|
|
435
|
+
this.headers = headers;
|
|
436
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
398
440
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
399
|
-
const
|
|
441
|
+
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
400
442
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
401
443
|
function getTimeoutFromThrottledRequest(error) {
|
|
402
444
|
const { headers } = error || {};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
445
|
+
if (!headers || typeof headers['retry-after'] !== 'string') {
|
|
446
|
+
return DEFAULT_RETRY_AFTER_TIMEOUT;
|
|
447
|
+
}
|
|
448
|
+
const seconds = parseInt(headers['retry-after'], 10);
|
|
449
|
+
if (!Number.isFinite(seconds)) {
|
|
450
|
+
return DEFAULT_RETRY_AFTER_TIMEOUT;
|
|
451
|
+
}
|
|
452
|
+
return seconds * 1000;
|
|
406
453
|
}
|
|
407
454
|
function retryIfFailed(fn, options) {
|
|
408
455
|
const { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes } = options;
|
|
@@ -755,33 +802,6 @@ class UploadcareFile {
|
|
|
755
802
|
}
|
|
756
803
|
}
|
|
757
804
|
|
|
758
|
-
const DEFAULT_INTERVAL = 500;
|
|
759
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
760
|
-
let timeoutId;
|
|
761
|
-
onCancel(signal, () => {
|
|
762
|
-
timeoutId && clearTimeout(timeoutId);
|
|
763
|
-
reject(cancelError('Poll cancelled'));
|
|
764
|
-
});
|
|
765
|
-
const tick = () => {
|
|
766
|
-
try {
|
|
767
|
-
Promise.resolve(check(signal))
|
|
768
|
-
.then((result) => {
|
|
769
|
-
if (result) {
|
|
770
|
-
resolve(result);
|
|
771
|
-
}
|
|
772
|
-
else {
|
|
773
|
-
timeoutId = setTimeout(tick, interval);
|
|
774
|
-
}
|
|
775
|
-
})
|
|
776
|
-
.catch((error) => reject(error));
|
|
777
|
-
}
|
|
778
|
-
catch (error) {
|
|
779
|
-
reject(error);
|
|
780
|
-
}
|
|
781
|
-
};
|
|
782
|
-
timeoutId = setTimeout(tick, 0);
|
|
783
|
-
});
|
|
784
|
-
|
|
785
805
|
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
786
806
|
return poll({
|
|
787
807
|
check: (signal) => info(file, {
|
|
@@ -1077,7 +1097,7 @@ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((
|
|
|
1077
1097
|
};
|
|
1078
1098
|
onCancel(signal, () => {
|
|
1079
1099
|
destroy();
|
|
1080
|
-
reject(
|
|
1100
|
+
reject(new CancelError('pusher cancelled'));
|
|
1081
1101
|
});
|
|
1082
1102
|
pusher.subscribe(token, (result) => {
|
|
1083
1103
|
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) {
|
|
@@ -358,7 +387,7 @@ const defaultSettings = {
|
|
|
358
387
|
const defaultContentType = 'application/octet-stream';
|
|
359
388
|
const defaultFilename = 'original';
|
|
360
389
|
|
|
361
|
-
var version = '
|
|
390
|
+
var version = '6.0.0';
|
|
362
391
|
|
|
363
392
|
const LIBRARY_NAME = 'UploadcareUploadClient';
|
|
364
393
|
const LIBRARY_VERSION = version;
|
|
@@ -370,14 +399,32 @@ function getUserAgent(options) {
|
|
|
370
399
|
});
|
|
371
400
|
}
|
|
372
401
|
|
|
402
|
+
class UploadClientError extends Error {
|
|
403
|
+
constructor(message, code, request, response, headers) {
|
|
404
|
+
super();
|
|
405
|
+
this.name = 'UploadClientError';
|
|
406
|
+
this.message = message;
|
|
407
|
+
this.code = code;
|
|
408
|
+
this.request = request;
|
|
409
|
+
this.response = response;
|
|
410
|
+
this.headers = headers;
|
|
411
|
+
Object.setPrototypeOf(this, UploadClientError.prototype);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
373
415
|
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
374
|
-
const
|
|
416
|
+
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
375
417
|
const DEFAULT_NETWORK_ERROR_TIMEOUT = 1000;
|
|
376
418
|
function getTimeoutFromThrottledRequest(error) {
|
|
377
419
|
const { headers } = error || {};
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
420
|
+
if (!headers || typeof headers['retry-after'] !== 'string') {
|
|
421
|
+
return DEFAULT_RETRY_AFTER_TIMEOUT;
|
|
422
|
+
}
|
|
423
|
+
const seconds = parseInt(headers['retry-after'], 10);
|
|
424
|
+
if (!Number.isFinite(seconds)) {
|
|
425
|
+
return DEFAULT_RETRY_AFTER_TIMEOUT;
|
|
426
|
+
}
|
|
427
|
+
return seconds * 1000;
|
|
381
428
|
}
|
|
382
429
|
function retryIfFailed(fn, options) {
|
|
383
430
|
const { retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes } = options;
|
|
@@ -730,33 +777,6 @@ class UploadcareFile {
|
|
|
730
777
|
}
|
|
731
778
|
}
|
|
732
779
|
|
|
733
|
-
const DEFAULT_INTERVAL = 500;
|
|
734
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
735
|
-
let timeoutId;
|
|
736
|
-
onCancel(signal, () => {
|
|
737
|
-
timeoutId && clearTimeout(timeoutId);
|
|
738
|
-
reject(cancelError('Poll cancelled'));
|
|
739
|
-
});
|
|
740
|
-
const tick = () => {
|
|
741
|
-
try {
|
|
742
|
-
Promise.resolve(check(signal))
|
|
743
|
-
.then((result) => {
|
|
744
|
-
if (result) {
|
|
745
|
-
resolve(result);
|
|
746
|
-
}
|
|
747
|
-
else {
|
|
748
|
-
timeoutId = setTimeout(tick, interval);
|
|
749
|
-
}
|
|
750
|
-
})
|
|
751
|
-
.catch((error) => reject(error));
|
|
752
|
-
}
|
|
753
|
-
catch (error) {
|
|
754
|
-
reject(error);
|
|
755
|
-
}
|
|
756
|
-
};
|
|
757
|
-
timeoutId = setTimeout(tick, 0);
|
|
758
|
-
});
|
|
759
|
-
|
|
760
780
|
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, retryNetworkErrorMaxTimes, signal, onProgress }) {
|
|
761
781
|
return poll({
|
|
762
782
|
check: (signal) => info(file, {
|
|
@@ -1054,7 +1074,7 @@ const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((
|
|
|
1054
1074
|
};
|
|
1055
1075
|
onCancel(signal, () => {
|
|
1056
1076
|
destroy();
|
|
1057
|
-
reject(
|
|
1077
|
+
reject(new CancelError('pusher cancelled'));
|
|
1058
1078
|
});
|
|
1059
1079
|
pusher.subscribe(token, (result) => {
|
|
1060
1080
|
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.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": {
|