@uploadcare/upload-client 3.1.2-alpha.0 → 4.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/README.md +2 -2
- package/dist/index.browser.js +1440 -1457
- package/dist/{index.js → index.node.js} +1467 -1474
- package/dist/index.react-native.js +1546 -0
- package/dist/types.d.ts +45 -37
- package/package.json +30 -37
- package/dist/index.browser.cjs +0 -1753
- package/dist/index.cjs +0 -1790
package/dist/index.browser.js
CHANGED
|
@@ -1,1547 +1,1530 @@
|
|
|
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;
|
|
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
17
|
};
|
|
18
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
|
-
}
|
|
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
28
|
};
|
|
29
29
|
|
|
30
|
-
const request = ({ method, url, data, headers = {}, signal, onProgress }) => new Promise((resolve, reject) => {
|
|
31
|
-
const xhr = new XMLHttpRequest();
|
|
32
|
-
const requestMethod = (method === null || method === void 0 ? void 0 : method.toUpperCase()) || 'GET';
|
|
33
|
-
let aborted = false;
|
|
34
|
-
xhr.open(requestMethod, url);
|
|
35
|
-
if (headers) {
|
|
36
|
-
Object.entries(headers).forEach((entry) => {
|
|
37
|
-
const [key, value] = entry;
|
|
38
|
-
typeof value !== 'undefined' &&
|
|
39
|
-
!Array.isArray(value) &&
|
|
40
|
-
xhr.setRequestHeader(key, value);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
xhr.responseType = 'text';
|
|
44
|
-
onCancel(signal, () => {
|
|
45
|
-
aborted = true;
|
|
46
|
-
xhr.abort();
|
|
47
|
-
reject(cancelError());
|
|
48
|
-
});
|
|
49
|
-
xhr.onload = () => {
|
|
50
|
-
if (xhr.status != 200) {
|
|
51
|
-
// analyze HTTP status of the response
|
|
52
|
-
reject(new Error(`Error ${xhr.status}: ${xhr.statusText}`)); // e.g. 404: Not Found
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
const request = {
|
|
56
|
-
method: requestMethod,
|
|
57
|
-
url,
|
|
58
|
-
data,
|
|
59
|
-
headers: headers || undefined,
|
|
60
|
-
signal,
|
|
61
|
-
onProgress
|
|
62
|
-
};
|
|
63
|
-
// Convert the header string into an array
|
|
64
|
-
// of individual headers
|
|
65
|
-
const headersArray = xhr
|
|
66
|
-
.getAllResponseHeaders()
|
|
67
|
-
.trim()
|
|
68
|
-
.split(/[\r\n]+/);
|
|
69
|
-
// Create a map of header names to values
|
|
70
|
-
const responseHeaders = {};
|
|
71
|
-
headersArray.forEach(function (line) {
|
|
72
|
-
const parts = line.split(': ');
|
|
73
|
-
const header = parts.shift();
|
|
74
|
-
const value = parts.join(': ');
|
|
75
|
-
if (header && typeof header !== 'undefined') {
|
|
76
|
-
responseHeaders[header] = value;
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
const responseData = xhr.response;
|
|
80
|
-
const responseStatus = xhr.status;
|
|
81
|
-
resolve({
|
|
82
|
-
request,
|
|
83
|
-
data: responseData,
|
|
84
|
-
headers: responseHeaders,
|
|
85
|
-
status: responseStatus
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
xhr.onerror = () => {
|
|
90
|
-
if (aborted)
|
|
91
|
-
return;
|
|
92
|
-
// only triggers if the request couldn't be made at all
|
|
93
|
-
reject(new Error('Network error'));
|
|
94
|
-
};
|
|
95
|
-
if (onProgress && typeof onProgress === 'function') {
|
|
96
|
-
xhr.upload.onprogress = (event) => {
|
|
97
|
-
if (event.lengthComputable) {
|
|
98
|
-
onProgress({
|
|
99
|
-
isComputable: true,
|
|
100
|
-
value: event.loaded / event.total
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
onProgress({ isComputable: false });
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
if (data) {
|
|
109
|
-
xhr.send(data);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
xhr.send();
|
|
113
|
-
}
|
|
30
|
+
const request = ({ method, url, data, headers = {}, signal, onProgress }) => new Promise((resolve, reject) => {
|
|
31
|
+
const xhr = new XMLHttpRequest();
|
|
32
|
+
const requestMethod = (method === null || method === void 0 ? void 0 : method.toUpperCase()) || 'GET';
|
|
33
|
+
let aborted = false;
|
|
34
|
+
xhr.open(requestMethod, url);
|
|
35
|
+
if (headers) {
|
|
36
|
+
Object.entries(headers).forEach((entry) => {
|
|
37
|
+
const [key, value] = entry;
|
|
38
|
+
typeof value !== 'undefined' &&
|
|
39
|
+
!Array.isArray(value) &&
|
|
40
|
+
xhr.setRequestHeader(key, value);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
xhr.responseType = 'text';
|
|
44
|
+
onCancel(signal, () => {
|
|
45
|
+
aborted = true;
|
|
46
|
+
xhr.abort();
|
|
47
|
+
reject(cancelError());
|
|
48
|
+
});
|
|
49
|
+
xhr.onload = () => {
|
|
50
|
+
if (xhr.status != 200) {
|
|
51
|
+
// analyze HTTP status of the response
|
|
52
|
+
reject(new Error(`Error ${xhr.status}: ${xhr.statusText}`)); // e.g. 404: Not Found
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const request = {
|
|
56
|
+
method: requestMethod,
|
|
57
|
+
url,
|
|
58
|
+
data,
|
|
59
|
+
headers: headers || undefined,
|
|
60
|
+
signal,
|
|
61
|
+
onProgress
|
|
62
|
+
};
|
|
63
|
+
// Convert the header string into an array
|
|
64
|
+
// of individual headers
|
|
65
|
+
const headersArray = xhr
|
|
66
|
+
.getAllResponseHeaders()
|
|
67
|
+
.trim()
|
|
68
|
+
.split(/[\r\n]+/);
|
|
69
|
+
// Create a map of header names to values
|
|
70
|
+
const responseHeaders = {};
|
|
71
|
+
headersArray.forEach(function (line) {
|
|
72
|
+
const parts = line.split(': ');
|
|
73
|
+
const header = parts.shift();
|
|
74
|
+
const value = parts.join(': ');
|
|
75
|
+
if (header && typeof header !== 'undefined') {
|
|
76
|
+
responseHeaders[header] = value;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const responseData = xhr.response;
|
|
80
|
+
const responseStatus = xhr.status;
|
|
81
|
+
resolve({
|
|
82
|
+
request,
|
|
83
|
+
data: responseData,
|
|
84
|
+
headers: responseHeaders,
|
|
85
|
+
status: responseStatus
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
xhr.onerror = () => {
|
|
90
|
+
if (aborted)
|
|
91
|
+
return;
|
|
92
|
+
// only triggers if the request couldn't be made at all
|
|
93
|
+
reject(new Error('Network error'));
|
|
94
|
+
};
|
|
95
|
+
if (onProgress && typeof onProgress === 'function') {
|
|
96
|
+
xhr.upload.onprogress = (event) => {
|
|
97
|
+
if (event.lengthComputable) {
|
|
98
|
+
onProgress({
|
|
99
|
+
isComputable: true,
|
|
100
|
+
value: event.loaded / event.total
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
onProgress({ isComputable: false });
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (data) {
|
|
109
|
+
xhr.send(data);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
xhr.send();
|
|
113
|
+
}
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
function identity(obj) {
|
|
117
|
-
return obj;
|
|
116
|
+
function identity(obj) {
|
|
117
|
+
return obj;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
const getFileOptions = ({ name }) => name ? [name] : [];
|
|
121
|
-
const transformFile = identity;
|
|
120
|
+
const getFileOptions = ({ name }) => name ? [name] : [];
|
|
121
|
+
const transformFile = identity;
|
|
122
122
|
var getFormData = () => new FormData();
|
|
123
123
|
|
|
124
|
-
/**
|
|
125
|
-
* FileData type guard.
|
|
126
|
-
*/
|
|
127
|
-
const isFileData = (data) => {
|
|
128
|
-
return (data !== undefined &&
|
|
129
|
-
((typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
130
|
-
(typeof File !== 'undefined' && data instanceof File) ||
|
|
131
|
-
(typeof Buffer !== 'undefined' && data instanceof Buffer)));
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* Uuid type guard.
|
|
135
|
-
*/
|
|
136
|
-
const isUuid = (data) => {
|
|
137
|
-
const UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
|
|
138
|
-
const regExp = new RegExp(UUID_REGEX);
|
|
139
|
-
return !isFileData(data) && regExp.test(data);
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* Url type guard.
|
|
143
|
-
*
|
|
144
|
-
* @param {NodeFile | BrowserFile | Url | Uuid} data
|
|
145
|
-
*/
|
|
146
|
-
const isUrl = (data) => {
|
|
147
|
-
const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
|
|
148
|
-
const regExp = new RegExp(URL_REGEX);
|
|
149
|
-
return !isFileData(data) && regExp.test(data);
|
|
124
|
+
/**
|
|
125
|
+
* FileData type guard.
|
|
126
|
+
*/
|
|
127
|
+
const isFileData = (data) => {
|
|
128
|
+
return (data !== undefined &&
|
|
129
|
+
((typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
130
|
+
(typeof File !== 'undefined' && data instanceof File) ||
|
|
131
|
+
(typeof Buffer !== 'undefined' && data instanceof Buffer)));
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Uuid type guard.
|
|
135
|
+
*/
|
|
136
|
+
const isUuid = (data) => {
|
|
137
|
+
const UUID_REGEX = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
|
|
138
|
+
const regExp = new RegExp(UUID_REGEX);
|
|
139
|
+
return !isFileData(data) && regExp.test(data);
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Url type guard.
|
|
143
|
+
*
|
|
144
|
+
* @param {NodeFile | BrowserFile | Url | Uuid} data
|
|
145
|
+
*/
|
|
146
|
+
const isUrl = (data) => {
|
|
147
|
+
const URL_REGEX = '^(?:\\w+:)?\\/\\/([^\\s\\.]+\\.\\S{2}|localhost[\\:?\\d]*)\\S*$';
|
|
148
|
+
const regExp = new RegExp(URL_REGEX);
|
|
149
|
+
return !isFileData(data) && regExp.test(data);
|
|
150
150
|
};
|
|
151
151
|
|
|
152
|
-
const isSimpleValue = (value) => {
|
|
153
|
-
return (typeof value === 'string' ||
|
|
154
|
-
typeof value === 'number' ||
|
|
155
|
-
typeof value === 'undefined');
|
|
156
|
-
};
|
|
157
|
-
const isObjectValue = (value) => {
|
|
158
|
-
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
159
|
-
};
|
|
160
|
-
const isFileValue = (value) => !!value &&
|
|
161
|
-
typeof value === 'object' &&
|
|
162
|
-
'data' in value &&
|
|
163
|
-
isFileData(value.data);
|
|
164
|
-
function collectParams(params, inputKey, inputValue) {
|
|
165
|
-
if (isFileValue(inputValue)) {
|
|
166
|
-
const { name, contentType } = inputValue;
|
|
167
|
-
const file = transformFile(inputValue.data); // lgtm [js/superfluous-trailing-arguments]
|
|
168
|
-
const options = getFileOptions({ name, contentType });
|
|
169
|
-
params.push([inputKey, file, ...options]);
|
|
170
|
-
}
|
|
171
|
-
else if (isObjectValue(inputValue)) {
|
|
172
|
-
for (const [key, value] of Object.entries(inputValue)) {
|
|
173
|
-
if (typeof value !== 'undefined') {
|
|
174
|
-
params.push([`${inputKey}[${key}]`, String(value)]);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else if (isSimpleValue(inputValue) && inputValue) {
|
|
179
|
-
params.push([inputKey, inputValue.toString()]);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
function getFormDataParams(options) {
|
|
183
|
-
const params = [];
|
|
184
|
-
for (const [key, value] of Object.entries(options)) {
|
|
185
|
-
collectParams(params, key, value);
|
|
186
|
-
}
|
|
187
|
-
return params;
|
|
188
|
-
}
|
|
189
|
-
function buildFormData(options) {
|
|
190
|
-
const formData = getFormData();
|
|
191
|
-
const paramsList = getFormDataParams(options);
|
|
192
|
-
for (const params of paramsList) {
|
|
193
|
-
const [key, value, ...options] = params;
|
|
194
|
-
// node form-data has another signature for append
|
|
195
|
-
formData.append(key, value, ...options);
|
|
196
|
-
}
|
|
197
|
-
return formData;
|
|
152
|
+
const isSimpleValue = (value) => {
|
|
153
|
+
return (typeof value === 'string' ||
|
|
154
|
+
typeof value === 'number' ||
|
|
155
|
+
typeof value === 'undefined');
|
|
156
|
+
};
|
|
157
|
+
const isObjectValue = (value) => {
|
|
158
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
159
|
+
};
|
|
160
|
+
const isFileValue = (value) => !!value &&
|
|
161
|
+
typeof value === 'object' &&
|
|
162
|
+
'data' in value &&
|
|
163
|
+
isFileData(value.data);
|
|
164
|
+
function collectParams(params, inputKey, inputValue) {
|
|
165
|
+
if (isFileValue(inputValue)) {
|
|
166
|
+
const { name, contentType } = inputValue;
|
|
167
|
+
const file = transformFile(inputValue.data); // lgtm [js/superfluous-trailing-arguments]
|
|
168
|
+
const options = getFileOptions({ name, contentType });
|
|
169
|
+
params.push([inputKey, file, ...options]);
|
|
170
|
+
}
|
|
171
|
+
else if (isObjectValue(inputValue)) {
|
|
172
|
+
for (const [key, value] of Object.entries(inputValue)) {
|
|
173
|
+
if (typeof value !== 'undefined') {
|
|
174
|
+
params.push([`${inputKey}[${key}]`, String(value)]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (isSimpleValue(inputValue) && inputValue) {
|
|
179
|
+
params.push([inputKey, inputValue.toString()]);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function getFormDataParams(options) {
|
|
183
|
+
const params = [];
|
|
184
|
+
for (const [key, value] of Object.entries(options)) {
|
|
185
|
+
collectParams(params, key, value);
|
|
186
|
+
}
|
|
187
|
+
return params;
|
|
188
|
+
}
|
|
189
|
+
function buildFormData(options) {
|
|
190
|
+
const formData = getFormData();
|
|
191
|
+
const paramsList = getFormDataParams(options);
|
|
192
|
+
for (const params of paramsList) {
|
|
193
|
+
const [key, value, ...options] = params;
|
|
194
|
+
// node form-data has another signature for append
|
|
195
|
+
formData.append(key, value, ...options);
|
|
196
|
+
}
|
|
197
|
+
return formData;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
const serializePair = (key, value) => typeof value !== 'undefined' ? `${key}=${encodeURIComponent(value)}` : null;
|
|
201
|
-
// TODO: generalize value transforming logic and use it here and inside `buildFormData`
|
|
202
|
-
const createQuery = (query) => Object.entries(query)
|
|
203
|
-
.reduce((params, [key, value]) => {
|
|
204
|
-
let param;
|
|
205
|
-
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
206
|
-
param = Object.entries(value)
|
|
207
|
-
.filter((entry) => typeof entry[1] !== 'undefined')
|
|
208
|
-
.map((entry) => serializePair(`${key}[${entry[0]}]`, String(entry[1])));
|
|
209
|
-
}
|
|
210
|
-
else if (Array.isArray(value)) {
|
|
211
|
-
param = value.map((val) => serializePair(`${key}[]`, val));
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
param = serializePair(key, value);
|
|
215
|
-
}
|
|
216
|
-
return params.concat(param);
|
|
217
|
-
}, [])
|
|
218
|
-
.filter((x) => !!x)
|
|
219
|
-
.join('&');
|
|
220
|
-
const getUrl = (base, path, query) => [
|
|
221
|
-
base,
|
|
222
|
-
path,
|
|
223
|
-
query && Object.keys(query).length > 0 ? '?' : '',
|
|
224
|
-
query && createQuery(query)
|
|
225
|
-
]
|
|
226
|
-
.filter(Boolean)
|
|
200
|
+
const serializePair = (key, value) => typeof value !== 'undefined' ? `${key}=${encodeURIComponent(value)}` : null;
|
|
201
|
+
// TODO: generalize value transforming logic and use it here and inside `buildFormData`
|
|
202
|
+
const createQuery = (query) => Object.entries(query)
|
|
203
|
+
.reduce((params, [key, value]) => {
|
|
204
|
+
let param;
|
|
205
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
206
|
+
param = Object.entries(value)
|
|
207
|
+
.filter((entry) => typeof entry[1] !== 'undefined')
|
|
208
|
+
.map((entry) => serializePair(`${key}[${entry[0]}]`, String(entry[1])));
|
|
209
|
+
}
|
|
210
|
+
else if (Array.isArray(value)) {
|
|
211
|
+
param = value.map((val) => serializePair(`${key}[]`, val));
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
param = serializePair(key, value);
|
|
215
|
+
}
|
|
216
|
+
return params.concat(param);
|
|
217
|
+
}, [])
|
|
218
|
+
.filter((x) => !!x)
|
|
219
|
+
.join('&');
|
|
220
|
+
const getUrl = (base, path, query) => [
|
|
221
|
+
base,
|
|
222
|
+
path,
|
|
223
|
+
query && Object.keys(query).length > 0 ? '?' : '',
|
|
224
|
+
query && createQuery(query)
|
|
225
|
+
]
|
|
226
|
+
.filter(Boolean)
|
|
227
227
|
.join('');
|
|
228
228
|
|
|
229
|
-
/*
|
|
230
|
-
Settings for future support:
|
|
231
|
-
parallelDirectUploads: 10,
|
|
232
|
-
*/
|
|
233
|
-
const defaultSettings = {
|
|
234
|
-
baseCDN: 'https://ucarecdn.com',
|
|
235
|
-
baseURL: 'https://upload.uploadcare.com',
|
|
236
|
-
maxContentLength: 50 * 1024 * 1024,
|
|
237
|
-
retryThrottledRequestMaxTimes: 1,
|
|
238
|
-
multipartMinFileSize: 25 * 1024 * 1024,
|
|
239
|
-
multipartChunkSize: 5 * 1024 * 1024,
|
|
240
|
-
multipartMinLastPartSize: 1024 * 1024,
|
|
241
|
-
maxConcurrentRequests: 4,
|
|
242
|
-
multipartMaxAttempts: 3,
|
|
243
|
-
pollingTimeoutMilliseconds: 10000,
|
|
244
|
-
pusherKey: '79ae88bd931ea68464d9'
|
|
245
|
-
};
|
|
246
|
-
const defaultContentType = 'application/octet-stream';
|
|
229
|
+
/*
|
|
230
|
+
Settings for future support:
|
|
231
|
+
parallelDirectUploads: 10,
|
|
232
|
+
*/
|
|
233
|
+
const defaultSettings = {
|
|
234
|
+
baseCDN: 'https://ucarecdn.com',
|
|
235
|
+
baseURL: 'https://upload.uploadcare.com',
|
|
236
|
+
maxContentLength: 50 * 1024 * 1024,
|
|
237
|
+
retryThrottledRequestMaxTimes: 1,
|
|
238
|
+
multipartMinFileSize: 25 * 1024 * 1024,
|
|
239
|
+
multipartChunkSize: 5 * 1024 * 1024,
|
|
240
|
+
multipartMinLastPartSize: 1024 * 1024,
|
|
241
|
+
maxConcurrentRequests: 4,
|
|
242
|
+
multipartMaxAttempts: 3,
|
|
243
|
+
pollingTimeoutMilliseconds: 10000,
|
|
244
|
+
pusherKey: '79ae88bd931ea68464d9'
|
|
245
|
+
};
|
|
246
|
+
const defaultContentType = 'application/octet-stream';
|
|
247
247
|
const defaultFilename = 'original';
|
|
248
248
|
|
|
249
249
|
var version = '3.1.1';
|
|
250
250
|
|
|
251
|
-
/**
|
|
252
|
-
* Returns User Agent based on version and settings.
|
|
253
|
-
*/
|
|
254
|
-
function getUserAgent({ userAgent, publicKey = '', integration = '' } = {}) {
|
|
255
|
-
const libraryName = 'UploadcareUploadClient';
|
|
256
|
-
const libraryVersion = version;
|
|
257
|
-
const languageName = 'JavaScript';
|
|
258
|
-
if (typeof userAgent === 'string') {
|
|
259
|
-
return userAgent;
|
|
260
|
-
}
|
|
261
|
-
if (typeof userAgent === 'function') {
|
|
262
|
-
return userAgent({
|
|
263
|
-
publicKey,
|
|
264
|
-
libraryName,
|
|
265
|
-
libraryVersion,
|
|
266
|
-
languageName,
|
|
267
|
-
integration
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
const mainInfo = [libraryName, libraryVersion, publicKey]
|
|
271
|
-
.filter(Boolean)
|
|
272
|
-
.join('/');
|
|
273
|
-
const additionInfo = [languageName, integration].filter(Boolean).join('; ');
|
|
274
|
-
return `${mainInfo} (${additionInfo})`;
|
|
251
|
+
/**
|
|
252
|
+
* Returns User Agent based on version and settings.
|
|
253
|
+
*/
|
|
254
|
+
function getUserAgent({ userAgent, publicKey = '', integration = '' } = {}) {
|
|
255
|
+
const libraryName = 'UploadcareUploadClient';
|
|
256
|
+
const libraryVersion = version;
|
|
257
|
+
const languageName = 'JavaScript';
|
|
258
|
+
if (typeof userAgent === 'string') {
|
|
259
|
+
return userAgent;
|
|
260
|
+
}
|
|
261
|
+
if (typeof userAgent === 'function') {
|
|
262
|
+
return userAgent({
|
|
263
|
+
publicKey,
|
|
264
|
+
libraryName,
|
|
265
|
+
libraryVersion,
|
|
266
|
+
languageName,
|
|
267
|
+
integration
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const mainInfo = [libraryName, libraryVersion, publicKey]
|
|
271
|
+
.filter(Boolean)
|
|
272
|
+
.join('/');
|
|
273
|
+
const additionInfo = [languageName, integration].filter(Boolean).join('; ');
|
|
274
|
+
return `${mainInfo} (${additionInfo})`;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
const SEPARATOR = /\W|_/g;
|
|
278
|
-
/**
|
|
279
|
-
* Transforms a string to camelCased.
|
|
280
|
-
*/
|
|
281
|
-
function camelize(text) {
|
|
282
|
-
return text
|
|
283
|
-
.split(SEPARATOR)
|
|
284
|
-
.map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
|
|
285
|
-
word.slice(1))
|
|
286
|
-
.join('');
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Transforms keys of an object to camelCased recursively.
|
|
290
|
-
*/
|
|
291
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
-
function camelizeKeys(source) {
|
|
293
|
-
if (!source || typeof source !== 'object') {
|
|
294
|
-
return source;
|
|
295
|
-
}
|
|
296
|
-
return Object.keys(source).reduce((accumulator, key) => {
|
|
297
|
-
accumulator[camelize(key)] =
|
|
298
|
-
typeof source[key] === 'object' ? camelizeKeys(source[key]) : source[key];
|
|
299
|
-
return accumulator;
|
|
300
|
-
}, {});
|
|
277
|
+
const SEPARATOR = /\W|_/g;
|
|
278
|
+
/**
|
|
279
|
+
* Transforms a string to camelCased.
|
|
280
|
+
*/
|
|
281
|
+
function camelize(text) {
|
|
282
|
+
return text
|
|
283
|
+
.split(SEPARATOR)
|
|
284
|
+
.map((word, index) => word.charAt(0)[index > 0 ? 'toUpperCase' : 'toLowerCase']() +
|
|
285
|
+
word.slice(1))
|
|
286
|
+
.join('');
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Transforms keys of an object to camelCased recursively.
|
|
290
|
+
*/
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
+
function camelizeKeys(source) {
|
|
293
|
+
if (!source || typeof source !== 'object') {
|
|
294
|
+
return source;
|
|
295
|
+
}
|
|
296
|
+
return Object.keys(source).reduce((accumulator, key) => {
|
|
297
|
+
accumulator[camelize(key)] =
|
|
298
|
+
typeof source[key] === 'object' ? camelizeKeys(source[key]) : source[key];
|
|
299
|
+
return accumulator;
|
|
300
|
+
}, {});
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
/**
|
|
304
|
-
* setTimeout as Promise.
|
|
305
|
-
*
|
|
306
|
-
* @param {number} ms Timeout in milliseconds.
|
|
307
|
-
*/
|
|
303
|
+
/**
|
|
304
|
+
* setTimeout as Promise.
|
|
305
|
+
*
|
|
306
|
+
* @param {number} ms Timeout in milliseconds.
|
|
307
|
+
*/
|
|
308
308
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
309
309
|
|
|
310
|
-
const defaultOptions = {
|
|
311
|
-
factor: 2,
|
|
312
|
-
time: 100
|
|
313
|
-
};
|
|
314
|
-
function retrier(fn, options = defaultOptions) {
|
|
315
|
-
let attempts = 0;
|
|
316
|
-
function runAttempt(fn) {
|
|
317
|
-
const defaultDelayTime = Math.round(options.time * Math.pow(options.factor, attempts));
|
|
318
|
-
const retry = (ms) => delay(ms !== null && ms !== void 0 ? ms : defaultDelayTime).then(() => {
|
|
319
|
-
attempts += 1;
|
|
320
|
-
return runAttempt(fn);
|
|
321
|
-
});
|
|
322
|
-
return fn({
|
|
323
|
-
attempt: attempts,
|
|
324
|
-
retry
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
return runAttempt(fn);
|
|
310
|
+
const defaultOptions = {
|
|
311
|
+
factor: 2,
|
|
312
|
+
time: 100
|
|
313
|
+
};
|
|
314
|
+
function retrier(fn, options = defaultOptions) {
|
|
315
|
+
let attempts = 0;
|
|
316
|
+
function runAttempt(fn) {
|
|
317
|
+
const defaultDelayTime = Math.round(options.time * Math.pow(options.factor, attempts));
|
|
318
|
+
const retry = (ms) => delay(ms !== null && ms !== void 0 ? ms : defaultDelayTime).then(() => {
|
|
319
|
+
attempts += 1;
|
|
320
|
+
return runAttempt(fn);
|
|
321
|
+
});
|
|
322
|
+
return fn({
|
|
323
|
+
attempt: attempts,
|
|
324
|
+
retry
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
return runAttempt(fn);
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
331
|
-
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
332
|
-
function getTimeoutFromThrottledRequest(error) {
|
|
333
|
-
const { headers } = error || {};
|
|
334
|
-
return ((headers &&
|
|
335
|
-
Number.parseInt(headers['x-throttle-wait-seconds']) * 1000) ||
|
|
336
|
-
DEFAULT_RETRY_AFTER_TIMEOUT);
|
|
337
|
-
}
|
|
338
|
-
function retryIfThrottled(fn, retryThrottledMaxTimes) {
|
|
339
|
-
return retrier(({ attempt, retry }) => fn().catch((error) => {
|
|
340
|
-
if ('response' in error &&
|
|
341
|
-
(error === null || error === void 0 ? void 0 : error.code) === REQUEST_WAS_THROTTLED_CODE &&
|
|
342
|
-
attempt < retryThrottledMaxTimes) {
|
|
343
|
-
return retry(getTimeoutFromThrottledRequest(error));
|
|
344
|
-
}
|
|
345
|
-
throw error;
|
|
346
|
-
}));
|
|
330
|
+
const REQUEST_WAS_THROTTLED_CODE = 'RequestThrottledError';
|
|
331
|
+
const DEFAULT_RETRY_AFTER_TIMEOUT = 15000;
|
|
332
|
+
function getTimeoutFromThrottledRequest(error) {
|
|
333
|
+
const { headers } = error || {};
|
|
334
|
+
return ((headers &&
|
|
335
|
+
Number.parseInt(headers['x-throttle-wait-seconds']) * 1000) ||
|
|
336
|
+
DEFAULT_RETRY_AFTER_TIMEOUT);
|
|
337
|
+
}
|
|
338
|
+
function retryIfThrottled(fn, retryThrottledMaxTimes) {
|
|
339
|
+
return retrier(({ attempt, retry }) => fn().catch((error) => {
|
|
340
|
+
if ('response' in error &&
|
|
341
|
+
(error === null || error === void 0 ? void 0 : error.code) === REQUEST_WAS_THROTTLED_CODE &&
|
|
342
|
+
attempt < retryThrottledMaxTimes) {
|
|
343
|
+
return retry(getTimeoutFromThrottledRequest(error));
|
|
344
|
+
}
|
|
345
|
+
throw error;
|
|
346
|
+
}));
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
-
function getStoreValue(store) {
|
|
350
|
-
return typeof store === 'undefined' ? 'auto' : store ? '1' : '0';
|
|
349
|
+
function getStoreValue(store) {
|
|
350
|
+
return typeof store === 'undefined' ? 'auto' : store ? '1' : '0';
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
-
/**
|
|
354
|
-
* Performs file uploading request to Uploadcare Upload API.
|
|
355
|
-
* Can be canceled and has progress.
|
|
356
|
-
*/
|
|
357
|
-
function base(file, { publicKey, fileName, contentType, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
|
|
358
|
-
return retryIfThrottled(() => {
|
|
359
|
-
var _a;
|
|
360
|
-
return request({
|
|
361
|
-
method: 'POST',
|
|
362
|
-
url: getUrl(baseURL, '/base/', {
|
|
363
|
-
jsonerrors: 1
|
|
364
|
-
}),
|
|
365
|
-
headers: {
|
|
366
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
367
|
-
},
|
|
368
|
-
data: buildFormData({
|
|
369
|
-
file: {
|
|
370
|
-
data: file,
|
|
371
|
-
name: (_a = fileName !== null && fileName !== void 0 ? fileName : file.name) !== null && _a !== void 0 ? _a : defaultFilename,
|
|
372
|
-
contentType
|
|
373
|
-
},
|
|
374
|
-
UPLOADCARE_PUB_KEY: publicKey,
|
|
375
|
-
UPLOADCARE_STORE: getStoreValue(store),
|
|
376
|
-
signature: secureSignature,
|
|
377
|
-
expire: secureExpire,
|
|
378
|
-
source: source,
|
|
379
|
-
metadata
|
|
380
|
-
}),
|
|
381
|
-
signal,
|
|
382
|
-
onProgress
|
|
383
|
-
}).then(({ data, headers, request }) => {
|
|
384
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
385
|
-
if ('error' in response) {
|
|
386
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
387
|
-
}
|
|
388
|
-
else {
|
|
389
|
-
return response;
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}, retryThrottledRequestMaxTimes);
|
|
353
|
+
/**
|
|
354
|
+
* Performs file uploading request to Uploadcare Upload API.
|
|
355
|
+
* Can be canceled and has progress.
|
|
356
|
+
*/
|
|
357
|
+
function base(file, { publicKey, fileName, contentType, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
|
|
358
|
+
return retryIfThrottled(() => {
|
|
359
|
+
var _a;
|
|
360
|
+
return request({
|
|
361
|
+
method: 'POST',
|
|
362
|
+
url: getUrl(baseURL, '/base/', {
|
|
363
|
+
jsonerrors: 1
|
|
364
|
+
}),
|
|
365
|
+
headers: {
|
|
366
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
367
|
+
},
|
|
368
|
+
data: buildFormData({
|
|
369
|
+
file: {
|
|
370
|
+
data: file,
|
|
371
|
+
name: (_a = fileName !== null && fileName !== void 0 ? fileName : file.name) !== null && _a !== void 0 ? _a : defaultFilename,
|
|
372
|
+
contentType
|
|
373
|
+
},
|
|
374
|
+
UPLOADCARE_PUB_KEY: publicKey,
|
|
375
|
+
UPLOADCARE_STORE: getStoreValue(store),
|
|
376
|
+
signature: secureSignature,
|
|
377
|
+
expire: secureExpire,
|
|
378
|
+
source: source,
|
|
379
|
+
metadata
|
|
380
|
+
}),
|
|
381
|
+
signal,
|
|
382
|
+
onProgress
|
|
383
|
+
}).then(({ data, headers, request }) => {
|
|
384
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
385
|
+
if ('error' in response) {
|
|
386
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
return response;
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
}, retryThrottledRequestMaxTimes);
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
-
var TypeEnum;
|
|
396
|
-
(function (TypeEnum) {
|
|
397
|
-
TypeEnum["Token"] = "token";
|
|
398
|
-
TypeEnum["FileInfo"] = "file_info";
|
|
399
|
-
})(TypeEnum || (TypeEnum = {}));
|
|
400
|
-
/**
|
|
401
|
-
* Uploading files from URL.
|
|
402
|
-
*/
|
|
403
|
-
function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
|
|
404
|
-
return retryIfThrottled(() => request({
|
|
405
|
-
method: 'POST',
|
|
406
|
-
headers: {
|
|
407
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
408
|
-
},
|
|
409
|
-
url: getUrl(baseURL, '/from_url/', {
|
|
410
|
-
jsonerrors: 1,
|
|
411
|
-
pub_key: publicKey,
|
|
412
|
-
source_url: sourceUrl,
|
|
413
|
-
store: getStoreValue(store),
|
|
414
|
-
filename: fileName,
|
|
415
|
-
check_URL_duplicates: checkForUrlDuplicates ? 1 : undefined,
|
|
416
|
-
save_URL_duplicates: saveUrlForRecurrentUploads ? 1 : undefined,
|
|
417
|
-
signature: secureSignature,
|
|
418
|
-
expire: secureExpire,
|
|
419
|
-
source: source,
|
|
420
|
-
metadata
|
|
421
|
-
}),
|
|
422
|
-
signal
|
|
423
|
-
}).then(({ data, headers, request }) => {
|
|
424
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
425
|
-
if ('error' in response) {
|
|
426
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
return response;
|
|
430
|
-
}
|
|
431
|
-
}), retryThrottledRequestMaxTimes);
|
|
395
|
+
var TypeEnum;
|
|
396
|
+
(function (TypeEnum) {
|
|
397
|
+
TypeEnum["Token"] = "token";
|
|
398
|
+
TypeEnum["FileInfo"] = "file_info";
|
|
399
|
+
})(TypeEnum || (TypeEnum = {}));
|
|
400
|
+
/**
|
|
401
|
+
* Uploading files from URL.
|
|
402
|
+
*/
|
|
403
|
+
function fromUrl(sourceUrl, { publicKey, baseURL = defaultSettings.baseURL, store, fileName, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, source = 'url', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
|
|
404
|
+
return retryIfThrottled(() => request({
|
|
405
|
+
method: 'POST',
|
|
406
|
+
headers: {
|
|
407
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
408
|
+
},
|
|
409
|
+
url: getUrl(baseURL, '/from_url/', {
|
|
410
|
+
jsonerrors: 1,
|
|
411
|
+
pub_key: publicKey,
|
|
412
|
+
source_url: sourceUrl,
|
|
413
|
+
store: getStoreValue(store),
|
|
414
|
+
filename: fileName,
|
|
415
|
+
check_URL_duplicates: checkForUrlDuplicates ? 1 : undefined,
|
|
416
|
+
save_URL_duplicates: saveUrlForRecurrentUploads ? 1 : undefined,
|
|
417
|
+
signature: secureSignature,
|
|
418
|
+
expire: secureExpire,
|
|
419
|
+
source: source,
|
|
420
|
+
metadata
|
|
421
|
+
}),
|
|
422
|
+
signal
|
|
423
|
+
}).then(({ data, headers, request }) => {
|
|
424
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
425
|
+
if ('error' in response) {
|
|
426
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
return response;
|
|
430
|
+
}
|
|
431
|
+
}), retryThrottledRequestMaxTimes);
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
var Status;
|
|
435
|
-
(function (Status) {
|
|
436
|
-
Status["Unknown"] = "unknown";
|
|
437
|
-
Status["Waiting"] = "waiting";
|
|
438
|
-
Status["Progress"] = "progress";
|
|
439
|
-
Status["Error"] = "error";
|
|
440
|
-
Status["Success"] = "success";
|
|
441
|
-
})(Status || (Status = {}));
|
|
442
|
-
const isErrorResponse = (response) => {
|
|
443
|
-
return 'status' in response && response.status === Status.Error;
|
|
444
|
-
};
|
|
445
|
-
/**
|
|
446
|
-
* Checking upload status and working with file tokens.
|
|
447
|
-
*/
|
|
448
|
-
function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes } = {}) {
|
|
449
|
-
return retryIfThrottled(() => request({
|
|
450
|
-
method: 'GET',
|
|
451
|
-
headers: publicKey
|
|
452
|
-
? {
|
|
453
|
-
'X-UC-User-Agent': getUserAgent({
|
|
454
|
-
publicKey,
|
|
455
|
-
integration,
|
|
456
|
-
userAgent
|
|
457
|
-
})
|
|
458
|
-
}
|
|
459
|
-
: undefined,
|
|
460
|
-
url: getUrl(baseURL, '/from_url/status/', {
|
|
461
|
-
jsonerrors: 1,
|
|
462
|
-
token
|
|
463
|
-
}),
|
|
464
|
-
signal
|
|
465
|
-
}).then(({ data, headers, request }) => {
|
|
466
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
467
|
-
if ('error' in response && !isErrorResponse(response)) {
|
|
468
|
-
throw new UploadClientError(response.error.content, undefined, request, response, headers);
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
return response;
|
|
472
|
-
}
|
|
473
|
-
}), retryThrottledRequestMaxTimes);
|
|
434
|
+
var Status;
|
|
435
|
+
(function (Status) {
|
|
436
|
+
Status["Unknown"] = "unknown";
|
|
437
|
+
Status["Waiting"] = "waiting";
|
|
438
|
+
Status["Progress"] = "progress";
|
|
439
|
+
Status["Error"] = "error";
|
|
440
|
+
Status["Success"] = "success";
|
|
441
|
+
})(Status || (Status = {}));
|
|
442
|
+
const isErrorResponse = (response) => {
|
|
443
|
+
return 'status' in response && response.status === Status.Error;
|
|
444
|
+
};
|
|
445
|
+
/**
|
|
446
|
+
* Checking upload status and working with file tokens.
|
|
447
|
+
*/
|
|
448
|
+
function fromUrlStatus(token, { publicKey, baseURL = defaultSettings.baseURL, signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes } = {}) {
|
|
449
|
+
return retryIfThrottled(() => request({
|
|
450
|
+
method: 'GET',
|
|
451
|
+
headers: publicKey
|
|
452
|
+
? {
|
|
453
|
+
'X-UC-User-Agent': getUserAgent({
|
|
454
|
+
publicKey,
|
|
455
|
+
integration,
|
|
456
|
+
userAgent
|
|
457
|
+
})
|
|
458
|
+
}
|
|
459
|
+
: undefined,
|
|
460
|
+
url: getUrl(baseURL, '/from_url/status/', {
|
|
461
|
+
jsonerrors: 1,
|
|
462
|
+
token
|
|
463
|
+
}),
|
|
464
|
+
signal
|
|
465
|
+
}).then(({ data, headers, request }) => {
|
|
466
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
467
|
+
if ('error' in response && !isErrorResponse(response)) {
|
|
468
|
+
throw new UploadClientError(response.error.content, undefined, request, response, headers);
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
return response;
|
|
472
|
+
}
|
|
473
|
+
}), retryThrottledRequestMaxTimes);
|
|
474
474
|
}
|
|
475
475
|
|
|
476
|
-
/**
|
|
477
|
-
* Create files group.
|
|
478
|
-
*/
|
|
479
|
-
function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
480
|
-
return retryIfThrottled(() => request({
|
|
481
|
-
method: 'POST',
|
|
482
|
-
headers: {
|
|
483
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
484
|
-
},
|
|
485
|
-
url: getUrl(baseURL, '/group/', {
|
|
486
|
-
jsonerrors: 1,
|
|
487
|
-
pub_key: publicKey,
|
|
488
|
-
files: uuids,
|
|
489
|
-
callback: jsonpCallback,
|
|
490
|
-
signature: secureSignature,
|
|
491
|
-
expire: secureExpire,
|
|
492
|
-
source
|
|
493
|
-
}),
|
|
494
|
-
signal
|
|
495
|
-
}).then(({ data, headers, request }) => {
|
|
496
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
497
|
-
if ('error' in response) {
|
|
498
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
499
|
-
}
|
|
500
|
-
else {
|
|
501
|
-
return response;
|
|
502
|
-
}
|
|
503
|
-
}), retryThrottledRequestMaxTimes);
|
|
476
|
+
/**
|
|
477
|
+
* Create files group.
|
|
478
|
+
*/
|
|
479
|
+
function group(uuids, { publicKey, baseURL = defaultSettings.baseURL, jsonpCallback, secureSignature, secureExpire, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
480
|
+
return retryIfThrottled(() => request({
|
|
481
|
+
method: 'POST',
|
|
482
|
+
headers: {
|
|
483
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
484
|
+
},
|
|
485
|
+
url: getUrl(baseURL, '/group/', {
|
|
486
|
+
jsonerrors: 1,
|
|
487
|
+
pub_key: publicKey,
|
|
488
|
+
files: uuids,
|
|
489
|
+
callback: jsonpCallback,
|
|
490
|
+
signature: secureSignature,
|
|
491
|
+
expire: secureExpire,
|
|
492
|
+
source
|
|
493
|
+
}),
|
|
494
|
+
signal
|
|
495
|
+
}).then(({ data, headers, request }) => {
|
|
496
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
497
|
+
if ('error' in response) {
|
|
498
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
return response;
|
|
502
|
+
}
|
|
503
|
+
}), retryThrottledRequestMaxTimes);
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
-
/**
|
|
507
|
-
* Get info about group.
|
|
508
|
-
*/
|
|
509
|
-
function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
510
|
-
return retryIfThrottled(() => request({
|
|
511
|
-
method: 'GET',
|
|
512
|
-
headers: {
|
|
513
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
514
|
-
},
|
|
515
|
-
url: getUrl(baseURL, '/group/info/', {
|
|
516
|
-
jsonerrors: 1,
|
|
517
|
-
pub_key: publicKey,
|
|
518
|
-
group_id: id,
|
|
519
|
-
source
|
|
520
|
-
}),
|
|
521
|
-
signal
|
|
522
|
-
}).then(({ data, headers, request }) => {
|
|
523
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
524
|
-
if ('error' in response) {
|
|
525
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
return response;
|
|
529
|
-
}
|
|
530
|
-
}), retryThrottledRequestMaxTimes);
|
|
506
|
+
/**
|
|
507
|
+
* Get info about group.
|
|
508
|
+
*/
|
|
509
|
+
function groupInfo(id, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
510
|
+
return retryIfThrottled(() => request({
|
|
511
|
+
method: 'GET',
|
|
512
|
+
headers: {
|
|
513
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
514
|
+
},
|
|
515
|
+
url: getUrl(baseURL, '/group/info/', {
|
|
516
|
+
jsonerrors: 1,
|
|
517
|
+
pub_key: publicKey,
|
|
518
|
+
group_id: id,
|
|
519
|
+
source
|
|
520
|
+
}),
|
|
521
|
+
signal
|
|
522
|
+
}).then(({ data, headers, request }) => {
|
|
523
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
524
|
+
if ('error' in response) {
|
|
525
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
return response;
|
|
529
|
+
}
|
|
530
|
+
}), retryThrottledRequestMaxTimes);
|
|
531
531
|
}
|
|
532
532
|
|
|
533
|
-
/**
|
|
534
|
-
* Returns a JSON dictionary holding file info.
|
|
535
|
-
*/
|
|
536
|
-
function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
537
|
-
return retryIfThrottled(() => request({
|
|
538
|
-
method: 'GET',
|
|
539
|
-
headers: {
|
|
540
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
541
|
-
},
|
|
542
|
-
url: getUrl(baseURL, '/info/', {
|
|
543
|
-
jsonerrors: 1,
|
|
544
|
-
pub_key: publicKey,
|
|
545
|
-
file_id: uuid,
|
|
546
|
-
source
|
|
547
|
-
}),
|
|
548
|
-
signal
|
|
549
|
-
}).then(({ data, headers, request }) => {
|
|
550
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
551
|
-
if ('error' in response) {
|
|
552
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
553
|
-
}
|
|
554
|
-
else {
|
|
555
|
-
return response;
|
|
556
|
-
}
|
|
557
|
-
}), retryThrottledRequestMaxTimes);
|
|
533
|
+
/**
|
|
534
|
+
* Returns a JSON dictionary holding file info.
|
|
535
|
+
*/
|
|
536
|
+
function info(uuid, { publicKey, baseURL = defaultSettings.baseURL, signal, source, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
537
|
+
return retryIfThrottled(() => request({
|
|
538
|
+
method: 'GET',
|
|
539
|
+
headers: {
|
|
540
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
541
|
+
},
|
|
542
|
+
url: getUrl(baseURL, '/info/', {
|
|
543
|
+
jsonerrors: 1,
|
|
544
|
+
pub_key: publicKey,
|
|
545
|
+
file_id: uuid,
|
|
546
|
+
source
|
|
547
|
+
}),
|
|
548
|
+
signal
|
|
549
|
+
}).then(({ data, headers, request }) => {
|
|
550
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
551
|
+
if ('error' in response) {
|
|
552
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
return response;
|
|
556
|
+
}
|
|
557
|
+
}), retryThrottledRequestMaxTimes);
|
|
558
558
|
}
|
|
559
559
|
|
|
560
|
-
/**
|
|
561
|
-
* Start multipart uploading.
|
|
562
|
-
*/
|
|
563
|
-
function multipartStart(size, { publicKey, contentType, fileName, multipartChunkSize = defaultSettings.multipartChunkSize, baseURL = '', secureSignature, secureExpire, store, signal, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
|
|
564
|
-
return retryIfThrottled(() => request({
|
|
565
|
-
method: 'POST',
|
|
566
|
-
url: getUrl(baseURL, '/multipart/start/', { jsonerrors: 1 }),
|
|
567
|
-
headers: {
|
|
568
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
569
|
-
},
|
|
570
|
-
data: buildFormData({
|
|
571
|
-
filename: fileName !== null && fileName !== void 0 ? fileName : defaultFilename,
|
|
572
|
-
size: size,
|
|
573
|
-
content_type: contentType !== null && contentType !== void 0 ? contentType : defaultContentType,
|
|
574
|
-
part_size: multipartChunkSize,
|
|
575
|
-
UPLOADCARE_STORE: getStoreValue(store),
|
|
576
|
-
UPLOADCARE_PUB_KEY: publicKey,
|
|
577
|
-
signature: secureSignature,
|
|
578
|
-
expire: secureExpire,
|
|
579
|
-
source: source,
|
|
580
|
-
metadata
|
|
581
|
-
}),
|
|
582
|
-
signal
|
|
583
|
-
}).then(({ data, headers, request }) => {
|
|
584
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
585
|
-
if ('error' in response) {
|
|
586
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
587
|
-
}
|
|
588
|
-
else {
|
|
589
|
-
// convert to array
|
|
590
|
-
response.parts = Object.keys(response.parts).map((key) => response.parts[key]);
|
|
591
|
-
return response;
|
|
592
|
-
}
|
|
593
|
-
}), retryThrottledRequestMaxTimes);
|
|
560
|
+
/**
|
|
561
|
+
* Start multipart uploading.
|
|
562
|
+
*/
|
|
563
|
+
function multipartStart(size, { publicKey, contentType, fileName, multipartChunkSize = defaultSettings.multipartChunkSize, baseURL = '', secureSignature, secureExpire, store, signal, source = 'local', integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes, metadata }) {
|
|
564
|
+
return retryIfThrottled(() => request({
|
|
565
|
+
method: 'POST',
|
|
566
|
+
url: getUrl(baseURL, '/multipart/start/', { jsonerrors: 1 }),
|
|
567
|
+
headers: {
|
|
568
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
569
|
+
},
|
|
570
|
+
data: buildFormData({
|
|
571
|
+
filename: fileName !== null && fileName !== void 0 ? fileName : defaultFilename,
|
|
572
|
+
size: size,
|
|
573
|
+
content_type: contentType !== null && contentType !== void 0 ? contentType : defaultContentType,
|
|
574
|
+
part_size: multipartChunkSize,
|
|
575
|
+
UPLOADCARE_STORE: getStoreValue(store),
|
|
576
|
+
UPLOADCARE_PUB_KEY: publicKey,
|
|
577
|
+
signature: secureSignature,
|
|
578
|
+
expire: secureExpire,
|
|
579
|
+
source: source,
|
|
580
|
+
metadata
|
|
581
|
+
}),
|
|
582
|
+
signal
|
|
583
|
+
}).then(({ data, headers, request }) => {
|
|
584
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
585
|
+
if ('error' in response) {
|
|
586
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
587
|
+
}
|
|
588
|
+
else {
|
|
589
|
+
// convert to array
|
|
590
|
+
response.parts = Object.keys(response.parts).map((key) => response.parts[key]);
|
|
591
|
+
return response;
|
|
592
|
+
}
|
|
593
|
+
}), retryThrottledRequestMaxTimes);
|
|
594
594
|
}
|
|
595
595
|
|
|
596
|
-
/**
|
|
597
|
-
* Complete multipart uploading.
|
|
598
|
-
*/
|
|
599
|
-
function multipartUpload(part, url, { signal, onProgress }) {
|
|
600
|
-
return request({
|
|
601
|
-
method: 'PUT',
|
|
602
|
-
url,
|
|
603
|
-
data: part,
|
|
604
|
-
// Upload request can't be non-computable because we always know exact size
|
|
605
|
-
onProgress: onProgress,
|
|
606
|
-
signal
|
|
607
|
-
})
|
|
608
|
-
.then((result) => {
|
|
609
|
-
// hack for node ¯\_(ツ)_/¯
|
|
610
|
-
if (onProgress)
|
|
611
|
-
onProgress({
|
|
612
|
-
isComputable: true,
|
|
613
|
-
value: 1
|
|
614
|
-
});
|
|
615
|
-
return result;
|
|
616
|
-
})
|
|
617
|
-
.then(({ status }) => ({ code: status }));
|
|
596
|
+
/**
|
|
597
|
+
* Complete multipart uploading.
|
|
598
|
+
*/
|
|
599
|
+
function multipartUpload(part, url, { signal, onProgress }) {
|
|
600
|
+
return request({
|
|
601
|
+
method: 'PUT',
|
|
602
|
+
url,
|
|
603
|
+
data: part,
|
|
604
|
+
// Upload request can't be non-computable because we always know exact size
|
|
605
|
+
onProgress: onProgress,
|
|
606
|
+
signal
|
|
607
|
+
})
|
|
608
|
+
.then((result) => {
|
|
609
|
+
// hack for node ¯\_(ツ)_/¯
|
|
610
|
+
if (onProgress)
|
|
611
|
+
onProgress({
|
|
612
|
+
isComputable: true,
|
|
613
|
+
value: 1
|
|
614
|
+
});
|
|
615
|
+
return result;
|
|
616
|
+
})
|
|
617
|
+
.then(({ status }) => ({ code: status }));
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
-
/**
|
|
621
|
-
* Complete multipart uploading.
|
|
622
|
-
*/
|
|
623
|
-
function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL, source = 'local', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
624
|
-
return retryIfThrottled(() => request({
|
|
625
|
-
method: 'POST',
|
|
626
|
-
url: getUrl(baseURL, '/multipart/complete/', { jsonerrors: 1 }),
|
|
627
|
-
headers: {
|
|
628
|
-
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
629
|
-
},
|
|
630
|
-
data: buildFormData({
|
|
631
|
-
uuid: uuid,
|
|
632
|
-
UPLOADCARE_PUB_KEY: publicKey,
|
|
633
|
-
source: source
|
|
634
|
-
}),
|
|
635
|
-
signal
|
|
636
|
-
}).then(({ data, headers, request }) => {
|
|
637
|
-
const response = camelizeKeys(JSON.parse(data));
|
|
638
|
-
if ('error' in response) {
|
|
639
|
-
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
640
|
-
}
|
|
641
|
-
else {
|
|
642
|
-
return response;
|
|
643
|
-
}
|
|
644
|
-
}), retryThrottledRequestMaxTimes);
|
|
620
|
+
/**
|
|
621
|
+
* Complete multipart uploading.
|
|
622
|
+
*/
|
|
623
|
+
function multipartComplete(uuid, { publicKey, baseURL = defaultSettings.baseURL, source = 'local', signal, integration, userAgent, retryThrottledRequestMaxTimes = defaultSettings.retryThrottledRequestMaxTimes }) {
|
|
624
|
+
return retryIfThrottled(() => request({
|
|
625
|
+
method: 'POST',
|
|
626
|
+
url: getUrl(baseURL, '/multipart/complete/', { jsonerrors: 1 }),
|
|
627
|
+
headers: {
|
|
628
|
+
'X-UC-User-Agent': getUserAgent({ publicKey, integration, userAgent })
|
|
629
|
+
},
|
|
630
|
+
data: buildFormData({
|
|
631
|
+
uuid: uuid,
|
|
632
|
+
UPLOADCARE_PUB_KEY: publicKey,
|
|
633
|
+
source: source
|
|
634
|
+
}),
|
|
635
|
+
signal
|
|
636
|
+
}).then(({ data, headers, request }) => {
|
|
637
|
+
const response = camelizeKeys(JSON.parse(data));
|
|
638
|
+
if ('error' in response) {
|
|
639
|
+
throw new UploadClientError(response.error.content, response.error.errorCode, request, response, headers);
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
return response;
|
|
643
|
+
}
|
|
644
|
+
}), retryThrottledRequestMaxTimes);
|
|
645
645
|
}
|
|
646
646
|
|
|
647
|
-
class UploadcareFile {
|
|
648
|
-
constructor(fileInfo, { baseCDN,
|
|
649
|
-
this.name = null;
|
|
650
|
-
this.size = null;
|
|
651
|
-
this.isStored = null;
|
|
652
|
-
this.isImage = null;
|
|
653
|
-
this.mimeType = null;
|
|
654
|
-
this.cdnUrl = null;
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
657
|
-
this.
|
|
658
|
-
this.
|
|
659
|
-
this.
|
|
660
|
-
this.
|
|
661
|
-
this.
|
|
662
|
-
const { uuid, s3Bucket } = fileInfo;
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
this.
|
|
670
|
-
this.
|
|
671
|
-
this.
|
|
672
|
-
this.
|
|
673
|
-
this.
|
|
674
|
-
this.
|
|
675
|
-
this.
|
|
676
|
-
this.
|
|
677
|
-
this.
|
|
678
|
-
this.
|
|
679
|
-
this.
|
|
680
|
-
this.
|
|
681
|
-
|
|
682
|
-
this.metadata = fileInfo.metadata || null;
|
|
683
|
-
}
|
|
647
|
+
class UploadcareFile {
|
|
648
|
+
constructor(fileInfo, { baseCDN, fileName }) {
|
|
649
|
+
this.name = null;
|
|
650
|
+
this.size = null;
|
|
651
|
+
this.isStored = null;
|
|
652
|
+
this.isImage = null;
|
|
653
|
+
this.mimeType = null;
|
|
654
|
+
this.cdnUrl = null;
|
|
655
|
+
this.s3Url = null;
|
|
656
|
+
this.originalFilename = null;
|
|
657
|
+
this.imageInfo = null;
|
|
658
|
+
this.videoInfo = null;
|
|
659
|
+
this.contentInfo = null;
|
|
660
|
+
this.metadata = null;
|
|
661
|
+
this.s3Bucket = null;
|
|
662
|
+
const { uuid, s3Bucket } = fileInfo;
|
|
663
|
+
const cdnUrl = `${baseCDN}/${uuid}/`;
|
|
664
|
+
const s3Url = s3Bucket
|
|
665
|
+
? `https://${s3Bucket}.s3.amazonaws.com/${uuid}/${fileInfo.filename}`
|
|
666
|
+
: null;
|
|
667
|
+
this.uuid = uuid;
|
|
668
|
+
this.name = fileName || fileInfo.filename;
|
|
669
|
+
this.size = fileInfo.size;
|
|
670
|
+
this.isStored = fileInfo.isStored;
|
|
671
|
+
this.isImage = fileInfo.isImage;
|
|
672
|
+
this.mimeType = fileInfo.mimeType;
|
|
673
|
+
this.cdnUrl = cdnUrl;
|
|
674
|
+
this.originalFilename = fileInfo.originalFilename;
|
|
675
|
+
this.imageInfo = camelizeKeys(fileInfo.imageInfo);
|
|
676
|
+
this.videoInfo = camelizeKeys(fileInfo.videoInfo);
|
|
677
|
+
this.contentInfo = camelizeKeys(fileInfo.contentInfo);
|
|
678
|
+
this.metadata = fileInfo.metadata || null;
|
|
679
|
+
this.s3Bucket = s3Bucket || null;
|
|
680
|
+
this.s3Url = s3Url;
|
|
681
|
+
}
|
|
684
682
|
}
|
|
685
683
|
|
|
686
|
-
const DEFAULT_INTERVAL = 500;
|
|
687
|
-
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
688
|
-
let timeoutId;
|
|
689
|
-
onCancel(signal, () => {
|
|
690
|
-
timeoutId && clearTimeout(timeoutId);
|
|
691
|
-
reject(cancelError('Poll cancelled'));
|
|
692
|
-
});
|
|
693
|
-
const tick = () => {
|
|
694
|
-
try {
|
|
695
|
-
Promise.resolve(check(signal))
|
|
696
|
-
.then((result) => {
|
|
697
|
-
if (result) {
|
|
698
|
-
resolve(result);
|
|
699
|
-
}
|
|
700
|
-
else {
|
|
701
|
-
timeoutId = setTimeout(tick, interval);
|
|
702
|
-
}
|
|
703
|
-
})
|
|
704
|
-
.catch((error) => reject(error));
|
|
705
|
-
}
|
|
706
|
-
catch (error) {
|
|
707
|
-
reject(error);
|
|
708
|
-
}
|
|
709
|
-
};
|
|
710
|
-
timeoutId = setTimeout(tick, 0);
|
|
684
|
+
const DEFAULT_INTERVAL = 500;
|
|
685
|
+
const poll = ({ check, interval = DEFAULT_INTERVAL, signal }) => new Promise((resolve, reject) => {
|
|
686
|
+
let timeoutId;
|
|
687
|
+
onCancel(signal, () => {
|
|
688
|
+
timeoutId && clearTimeout(timeoutId);
|
|
689
|
+
reject(cancelError('Poll cancelled'));
|
|
690
|
+
});
|
|
691
|
+
const tick = () => {
|
|
692
|
+
try {
|
|
693
|
+
Promise.resolve(check(signal))
|
|
694
|
+
.then((result) => {
|
|
695
|
+
if (result) {
|
|
696
|
+
resolve(result);
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
timeoutId = setTimeout(tick, interval);
|
|
700
|
+
}
|
|
701
|
+
})
|
|
702
|
+
.catch((error) => reject(error));
|
|
703
|
+
}
|
|
704
|
+
catch (error) {
|
|
705
|
+
reject(error);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
timeoutId = setTimeout(tick, 0);
|
|
711
709
|
});
|
|
712
710
|
|
|
713
|
-
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, signal, onProgress }) {
|
|
714
|
-
return poll({
|
|
715
|
-
check: (signal) => info(file, {
|
|
716
|
-
publicKey,
|
|
717
|
-
baseURL,
|
|
718
|
-
signal,
|
|
719
|
-
source,
|
|
720
|
-
integration,
|
|
721
|
-
userAgent,
|
|
722
|
-
retryThrottledRequestMaxTimes
|
|
723
|
-
}).then((response) => {
|
|
724
|
-
if (response.isReady) {
|
|
725
|
-
return response;
|
|
726
|
-
}
|
|
727
|
-
onProgress && onProgress({ isComputable: true, value: 1 });
|
|
728
|
-
return false;
|
|
729
|
-
}),
|
|
730
|
-
signal
|
|
731
|
-
});
|
|
711
|
+
function isReadyPoll({ file, publicKey, baseURL, source, integration, userAgent, retryThrottledRequestMaxTimes, signal, onProgress }) {
|
|
712
|
+
return poll({
|
|
713
|
+
check: (signal) => info(file, {
|
|
714
|
+
publicKey,
|
|
715
|
+
baseURL,
|
|
716
|
+
signal,
|
|
717
|
+
source,
|
|
718
|
+
integration,
|
|
719
|
+
userAgent,
|
|
720
|
+
retryThrottledRequestMaxTimes
|
|
721
|
+
}).then((response) => {
|
|
722
|
+
if (response.isReady) {
|
|
723
|
+
return response;
|
|
724
|
+
}
|
|
725
|
+
onProgress && onProgress({ isComputable: true, value: 1 });
|
|
726
|
+
return false;
|
|
727
|
+
}),
|
|
728
|
+
signal
|
|
729
|
+
});
|
|
732
730
|
}
|
|
733
731
|
|
|
734
|
-
const
|
|
735
|
-
return base(file, {
|
|
736
|
-
publicKey,
|
|
737
|
-
fileName,
|
|
738
|
-
contentType,
|
|
739
|
-
baseURL,
|
|
740
|
-
secureSignature,
|
|
741
|
-
secureExpire,
|
|
742
|
-
store,
|
|
743
|
-
signal,
|
|
744
|
-
onProgress,
|
|
745
|
-
source,
|
|
746
|
-
integration,
|
|
747
|
-
userAgent,
|
|
748
|
-
retryThrottledRequestMaxTimes,
|
|
749
|
-
metadata
|
|
750
|
-
})
|
|
751
|
-
.then(({ file }) => {
|
|
752
|
-
return isReadyPoll({
|
|
753
|
-
file,
|
|
754
|
-
publicKey,
|
|
755
|
-
baseURL,
|
|
756
|
-
source,
|
|
757
|
-
integration,
|
|
758
|
-
userAgent,
|
|
759
|
-
retryThrottledRequestMaxTimes,
|
|
760
|
-
onProgress,
|
|
761
|
-
signal
|
|
762
|
-
});
|
|
763
|
-
})
|
|
764
|
-
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
732
|
+
const uploadDirect = (file, { publicKey, fileName, baseURL, secureSignature, secureExpire, store, contentType, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN, metadata }) => {
|
|
733
|
+
return base(file, {
|
|
734
|
+
publicKey,
|
|
735
|
+
fileName,
|
|
736
|
+
contentType,
|
|
737
|
+
baseURL,
|
|
738
|
+
secureSignature,
|
|
739
|
+
secureExpire,
|
|
740
|
+
store,
|
|
741
|
+
signal,
|
|
742
|
+
onProgress,
|
|
743
|
+
source,
|
|
744
|
+
integration,
|
|
745
|
+
userAgent,
|
|
746
|
+
retryThrottledRequestMaxTimes,
|
|
747
|
+
metadata
|
|
748
|
+
})
|
|
749
|
+
.then(({ file }) => {
|
|
750
|
+
return isReadyPoll({
|
|
751
|
+
file,
|
|
752
|
+
publicKey,
|
|
753
|
+
baseURL,
|
|
754
|
+
source,
|
|
755
|
+
integration,
|
|
756
|
+
userAgent,
|
|
757
|
+
retryThrottledRequestMaxTimes,
|
|
758
|
+
onProgress,
|
|
759
|
+
signal
|
|
760
|
+
});
|
|
761
|
+
})
|
|
762
|
+
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
765
763
|
};
|
|
766
764
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
const
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
})).then((results) => {
|
|
799
|
-
if (winnerIndex === null) {
|
|
800
|
-
throw lastError;
|
|
801
|
-
}
|
|
802
|
-
else {
|
|
803
|
-
return results[winnerIndex];
|
|
804
|
-
}
|
|
805
|
-
});
|
|
765
|
+
const race = (fns, { signal } = {}) => {
|
|
766
|
+
let lastError = null;
|
|
767
|
+
let winnerIndex = null;
|
|
768
|
+
const controllers = fns.map(() => new AbortController());
|
|
769
|
+
const createStopRaceCallback = (i) => () => {
|
|
770
|
+
winnerIndex = i;
|
|
771
|
+
controllers.forEach((controller, index) => index !== i && controller.abort());
|
|
772
|
+
};
|
|
773
|
+
onCancel(signal, () => {
|
|
774
|
+
controllers.forEach((controller) => controller.abort());
|
|
775
|
+
});
|
|
776
|
+
return Promise.all(fns.map((fn, i) => {
|
|
777
|
+
const stopRace = createStopRaceCallback(i);
|
|
778
|
+
return Promise.resolve()
|
|
779
|
+
.then(() => fn({ stopRace, signal: controllers[i].signal }))
|
|
780
|
+
.then((result) => {
|
|
781
|
+
stopRace();
|
|
782
|
+
return result;
|
|
783
|
+
})
|
|
784
|
+
.catch((error) => {
|
|
785
|
+
lastError = error;
|
|
786
|
+
return null;
|
|
787
|
+
});
|
|
788
|
+
})).then((results) => {
|
|
789
|
+
if (winnerIndex === null) {
|
|
790
|
+
throw lastError;
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
return results[winnerIndex];
|
|
794
|
+
}
|
|
795
|
+
});
|
|
806
796
|
};
|
|
807
797
|
|
|
808
798
|
var WebSocket = window.WebSocket;
|
|
809
799
|
|
|
810
|
-
class Events {
|
|
811
|
-
constructor() {
|
|
812
|
-
this.events = Object.create({});
|
|
813
|
-
}
|
|
814
|
-
emit(event, data) {
|
|
815
|
-
var _a;
|
|
816
|
-
(_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(data));
|
|
817
|
-
}
|
|
818
|
-
on(event, callback) {
|
|
819
|
-
this.events[event] = this.events[event] || [];
|
|
820
|
-
this.events[event].push(callback);
|
|
821
|
-
}
|
|
822
|
-
off(event, callback) {
|
|
823
|
-
if (callback) {
|
|
824
|
-
this.events[event] = this.events[event].filter((fn) => fn !== callback);
|
|
825
|
-
}
|
|
826
|
-
else {
|
|
827
|
-
this.events[event] = [];
|
|
828
|
-
}
|
|
829
|
-
}
|
|
800
|
+
class Events {
|
|
801
|
+
constructor() {
|
|
802
|
+
this.events = Object.create({});
|
|
803
|
+
}
|
|
804
|
+
emit(event, data) {
|
|
805
|
+
var _a;
|
|
806
|
+
(_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(data));
|
|
807
|
+
}
|
|
808
|
+
on(event, callback) {
|
|
809
|
+
this.events[event] = this.events[event] || [];
|
|
810
|
+
this.events[event].push(callback);
|
|
811
|
+
}
|
|
812
|
+
off(event, callback) {
|
|
813
|
+
if (callback) {
|
|
814
|
+
this.events[event] = this.events[event].filter((fn) => fn !== callback);
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
this.events[event] = [];
|
|
818
|
+
}
|
|
819
|
+
}
|
|
830
820
|
}
|
|
831
821
|
|
|
832
|
-
const response = (type, data) => {
|
|
833
|
-
if (type === 'success') {
|
|
834
|
-
return Object.assign({ status: Status.Success }, data);
|
|
835
|
-
}
|
|
836
|
-
if (type === 'progress') {
|
|
837
|
-
return Object.assign({ status: Status.Progress }, data);
|
|
838
|
-
}
|
|
839
|
-
return Object.assign({ status: Status.Error }, data);
|
|
840
|
-
};
|
|
841
|
-
class Pusher {
|
|
842
|
-
constructor(pusherKey, disconnectTime = 30000) {
|
|
843
|
-
this.ws = undefined;
|
|
844
|
-
this.queue = [];
|
|
845
|
-
this.isConnected = false;
|
|
846
|
-
this.subscribers = 0;
|
|
847
|
-
this.emmitter = new Events();
|
|
848
|
-
this.disconnectTimeoutId = null;
|
|
849
|
-
this.key = pusherKey;
|
|
850
|
-
this.disconnectTime = disconnectTime;
|
|
851
|
-
}
|
|
852
|
-
connect() {
|
|
853
|
-
this.disconnectTimeoutId && clearTimeout(this.disconnectTimeoutId);
|
|
854
|
-
if (!this.isConnected && !this.ws) {
|
|
855
|
-
const pusherUrl = `wss://ws.pusherapp.com/app/${this.key}?protocol=5&client=js&version=1.12.2`;
|
|
856
|
-
this.ws = new WebSocket(pusherUrl);
|
|
857
|
-
this.ws.addEventListener('error', (error) => {
|
|
858
|
-
this.emmitter.emit('error', new Error(error.message));
|
|
859
|
-
});
|
|
860
|
-
this.emmitter.on('connected', () => {
|
|
861
|
-
this.isConnected = true;
|
|
862
|
-
this.queue.forEach((message) => this.send(message.event, message.data));
|
|
863
|
-
this.queue = [];
|
|
864
|
-
});
|
|
865
|
-
this.ws.addEventListener('message', (e) => {
|
|
866
|
-
const data = JSON.parse(e.data.toString());
|
|
867
|
-
switch (data.event) {
|
|
868
|
-
case 'pusher:connection_established': {
|
|
869
|
-
this.emmitter.emit('connected', undefined);
|
|
870
|
-
break;
|
|
871
|
-
}
|
|
872
|
-
case 'pusher:ping': {
|
|
873
|
-
this.send('pusher:pong', {});
|
|
874
|
-
break;
|
|
875
|
-
}
|
|
876
|
-
case 'progress':
|
|
877
|
-
case 'success':
|
|
878
|
-
case 'fail': {
|
|
879
|
-
this.emmitter.emit(data.channel, response(data.event, JSON.parse(data.data)));
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
});
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
disconnect() {
|
|
886
|
-
const actualDisconect = () => {
|
|
887
|
-
var _a;
|
|
888
|
-
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
|
|
889
|
-
this.ws = undefined;
|
|
890
|
-
this.isConnected = false;
|
|
891
|
-
};
|
|
892
|
-
if (this.disconnectTime) {
|
|
893
|
-
this.disconnectTimeoutId = setTimeout(() => {
|
|
894
|
-
actualDisconect();
|
|
895
|
-
}, this.disconnectTime);
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
actualDisconect();
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
send(event, data) {
|
|
902
|
-
var _a;
|
|
903
|
-
const str = JSON.stringify({ event, data });
|
|
904
|
-
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.send(str);
|
|
905
|
-
}
|
|
906
|
-
subscribe(token, handler) {
|
|
907
|
-
this.subscribers += 1;
|
|
908
|
-
this.connect();
|
|
909
|
-
const channel = `task-status-${token}`;
|
|
910
|
-
const message = {
|
|
911
|
-
event: 'pusher:subscribe',
|
|
912
|
-
data: { channel }
|
|
913
|
-
};
|
|
914
|
-
this.emmitter.on(channel, handler);
|
|
915
|
-
if (this.isConnected) {
|
|
916
|
-
this.send(message.event, message.data);
|
|
917
|
-
}
|
|
918
|
-
else {
|
|
919
|
-
this.queue.push(message);
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
unsubscribe(token) {
|
|
923
|
-
this.subscribers -= 1;
|
|
924
|
-
const channel = `task-status-${token}`;
|
|
925
|
-
const message = {
|
|
926
|
-
event: 'pusher:unsubscribe',
|
|
927
|
-
data: { channel }
|
|
928
|
-
};
|
|
929
|
-
this.emmitter.off(channel);
|
|
930
|
-
if (this.isConnected) {
|
|
931
|
-
this.send(message.event, message.data);
|
|
932
|
-
}
|
|
933
|
-
else {
|
|
934
|
-
this.queue = this.queue.filter((msg) => msg.data.channel !== channel);
|
|
935
|
-
}
|
|
936
|
-
if (this.subscribers === 0) {
|
|
937
|
-
this.disconnect();
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
onError(callback) {
|
|
941
|
-
this.emmitter.on('error', callback);
|
|
942
|
-
return () => this.emmitter.off('error', callback);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
let pusher = null;
|
|
946
|
-
const getPusher = (key) => {
|
|
947
|
-
if (!pusher) {
|
|
948
|
-
// no timeout for nodeJS and 30000 ms for browser
|
|
949
|
-
const disconectTimeout = typeof window === 'undefined' ? 0 : 30000;
|
|
950
|
-
pusher = new Pusher(key, disconectTimeout);
|
|
951
|
-
}
|
|
952
|
-
return pusher;
|
|
953
|
-
};
|
|
954
|
-
const preconnect = (key) => {
|
|
955
|
-
getPusher(key).connect();
|
|
822
|
+
const response = (type, data) => {
|
|
823
|
+
if (type === 'success') {
|
|
824
|
+
return Object.assign({ status: Status.Success }, data);
|
|
825
|
+
}
|
|
826
|
+
if (type === 'progress') {
|
|
827
|
+
return Object.assign({ status: Status.Progress }, data);
|
|
828
|
+
}
|
|
829
|
+
return Object.assign({ status: Status.Error }, data);
|
|
830
|
+
};
|
|
831
|
+
class Pusher {
|
|
832
|
+
constructor(pusherKey, disconnectTime = 30000) {
|
|
833
|
+
this.ws = undefined;
|
|
834
|
+
this.queue = [];
|
|
835
|
+
this.isConnected = false;
|
|
836
|
+
this.subscribers = 0;
|
|
837
|
+
this.emmitter = new Events();
|
|
838
|
+
this.disconnectTimeoutId = null;
|
|
839
|
+
this.key = pusherKey;
|
|
840
|
+
this.disconnectTime = disconnectTime;
|
|
841
|
+
}
|
|
842
|
+
connect() {
|
|
843
|
+
this.disconnectTimeoutId && clearTimeout(this.disconnectTimeoutId);
|
|
844
|
+
if (!this.isConnected && !this.ws) {
|
|
845
|
+
const pusherUrl = `wss://ws.pusherapp.com/app/${this.key}?protocol=5&client=js&version=1.12.2`;
|
|
846
|
+
this.ws = new WebSocket(pusherUrl);
|
|
847
|
+
this.ws.addEventListener('error', (error) => {
|
|
848
|
+
this.emmitter.emit('error', new Error(error.message));
|
|
849
|
+
});
|
|
850
|
+
this.emmitter.on('connected', () => {
|
|
851
|
+
this.isConnected = true;
|
|
852
|
+
this.queue.forEach((message) => this.send(message.event, message.data));
|
|
853
|
+
this.queue = [];
|
|
854
|
+
});
|
|
855
|
+
this.ws.addEventListener('message', (e) => {
|
|
856
|
+
const data = JSON.parse(e.data.toString());
|
|
857
|
+
switch (data.event) {
|
|
858
|
+
case 'pusher:connection_established': {
|
|
859
|
+
this.emmitter.emit('connected', undefined);
|
|
860
|
+
break;
|
|
861
|
+
}
|
|
862
|
+
case 'pusher:ping': {
|
|
863
|
+
this.send('pusher:pong', {});
|
|
864
|
+
break;
|
|
865
|
+
}
|
|
866
|
+
case 'progress':
|
|
867
|
+
case 'success':
|
|
868
|
+
case 'fail': {
|
|
869
|
+
this.emmitter.emit(data.channel, response(data.event, JSON.parse(data.data)));
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
disconnect() {
|
|
876
|
+
const actualDisconect = () => {
|
|
877
|
+
var _a;
|
|
878
|
+
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
|
|
879
|
+
this.ws = undefined;
|
|
880
|
+
this.isConnected = false;
|
|
881
|
+
};
|
|
882
|
+
if (this.disconnectTime) {
|
|
883
|
+
this.disconnectTimeoutId = setTimeout(() => {
|
|
884
|
+
actualDisconect();
|
|
885
|
+
}, this.disconnectTime);
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
actualDisconect();
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
send(event, data) {
|
|
892
|
+
var _a;
|
|
893
|
+
const str = JSON.stringify({ event, data });
|
|
894
|
+
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.send(str);
|
|
895
|
+
}
|
|
896
|
+
subscribe(token, handler) {
|
|
897
|
+
this.subscribers += 1;
|
|
898
|
+
this.connect();
|
|
899
|
+
const channel = `task-status-${token}`;
|
|
900
|
+
const message = {
|
|
901
|
+
event: 'pusher:subscribe',
|
|
902
|
+
data: { channel }
|
|
903
|
+
};
|
|
904
|
+
this.emmitter.on(channel, handler);
|
|
905
|
+
if (this.isConnected) {
|
|
906
|
+
this.send(message.event, message.data);
|
|
907
|
+
}
|
|
908
|
+
else {
|
|
909
|
+
this.queue.push(message);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
unsubscribe(token) {
|
|
913
|
+
this.subscribers -= 1;
|
|
914
|
+
const channel = `task-status-${token}`;
|
|
915
|
+
const message = {
|
|
916
|
+
event: 'pusher:unsubscribe',
|
|
917
|
+
data: { channel }
|
|
918
|
+
};
|
|
919
|
+
this.emmitter.off(channel);
|
|
920
|
+
if (this.isConnected) {
|
|
921
|
+
this.send(message.event, message.data);
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
this.queue = this.queue.filter((msg) => msg.data.channel !== channel);
|
|
925
|
+
}
|
|
926
|
+
if (this.subscribers === 0) {
|
|
927
|
+
this.disconnect();
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
onError(callback) {
|
|
931
|
+
this.emmitter.on('error', callback);
|
|
932
|
+
return () => this.emmitter.off('error', callback);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
let pusher = null;
|
|
936
|
+
const getPusher = (key) => {
|
|
937
|
+
if (!pusher) {
|
|
938
|
+
// no timeout for nodeJS and 30000 ms for browser
|
|
939
|
+
const disconectTimeout = typeof window === 'undefined' ? 0 : 30000;
|
|
940
|
+
pusher = new Pusher(key, disconectTimeout);
|
|
941
|
+
}
|
|
942
|
+
return pusher;
|
|
943
|
+
};
|
|
944
|
+
const preconnect = (key) => {
|
|
945
|
+
getPusher(key).connect();
|
|
956
946
|
};
|
|
957
947
|
|
|
958
|
-
function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, onProgress, signal }) {
|
|
959
|
-
return poll({
|
|
960
|
-
check: (signal) => fromUrlStatus(token, {
|
|
961
|
-
publicKey,
|
|
962
|
-
baseURL,
|
|
963
|
-
integration,
|
|
964
|
-
userAgent,
|
|
965
|
-
retryThrottledRequestMaxTimes,
|
|
966
|
-
signal
|
|
967
|
-
}).then((response) => {
|
|
968
|
-
switch (response.status) {
|
|
969
|
-
case Status.Error: {
|
|
970
|
-
return new UploadClientError(response.error, response.errorCode);
|
|
971
|
-
}
|
|
972
|
-
case Status.Waiting: {
|
|
973
|
-
return false;
|
|
974
|
-
}
|
|
975
|
-
case Status.Unknown: {
|
|
976
|
-
return new UploadClientError(`Token "${token}" was not found.`);
|
|
977
|
-
}
|
|
978
|
-
case Status.Progress: {
|
|
979
|
-
if (onProgress) {
|
|
980
|
-
if (response.total === 'unknown') {
|
|
981
|
-
onProgress({ isComputable: false });
|
|
982
|
-
}
|
|
983
|
-
else {
|
|
984
|
-
onProgress({
|
|
985
|
-
isComputable: true,
|
|
986
|
-
value: response.done / response.total
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
return false;
|
|
991
|
-
}
|
|
992
|
-
case Status.Success: {
|
|
993
|
-
if (onProgress)
|
|
994
|
-
onProgress({
|
|
995
|
-
isComputable: true,
|
|
996
|
-
value: response.done / response.total
|
|
997
|
-
});
|
|
998
|
-
return response;
|
|
999
|
-
}
|
|
1000
|
-
default: {
|
|
1001
|
-
throw new Error('Unknown status');
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
}),
|
|
1005
|
-
signal
|
|
1006
|
-
});
|
|
1007
|
-
}
|
|
1008
|
-
const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((resolve, reject) => {
|
|
1009
|
-
const pusher = getPusher(pusherKey);
|
|
1010
|
-
const unsubErrorHandler = pusher.onError(reject);
|
|
1011
|
-
const destroy = () => {
|
|
1012
|
-
unsubErrorHandler();
|
|
1013
|
-
pusher.unsubscribe(token);
|
|
1014
|
-
};
|
|
1015
|
-
onCancel(signal, () => {
|
|
1016
|
-
destroy();
|
|
1017
|
-
reject(cancelError('pusher cancelled'));
|
|
1018
|
-
});
|
|
1019
|
-
pusher.subscribe(token, (result) => {
|
|
1020
|
-
switch (result.status) {
|
|
1021
|
-
case Status.Progress: {
|
|
1022
|
-
if (onProgress) {
|
|
1023
|
-
if (result.total === 'unknown') {
|
|
1024
|
-
onProgress({ isComputable: false });
|
|
1025
|
-
}
|
|
1026
|
-
else {
|
|
1027
|
-
onProgress({
|
|
1028
|
-
isComputable: true,
|
|
1029
|
-
value: result.done / result.total
|
|
1030
|
-
});
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
break;
|
|
1034
|
-
}
|
|
1035
|
-
case Status.Success: {
|
|
1036
|
-
destroy();
|
|
1037
|
-
if (onProgress)
|
|
1038
|
-
onProgress({
|
|
1039
|
-
isComputable: true,
|
|
1040
|
-
value: result.done / result.total
|
|
1041
|
-
});
|
|
1042
|
-
resolve(result);
|
|
1043
|
-
break;
|
|
1044
|
-
}
|
|
1045
|
-
case Status.Error: {
|
|
1046
|
-
destroy();
|
|
1047
|
-
reject(new UploadClientError(result.msg, result.error_code));
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
1051
|
-
});
|
|
1052
|
-
const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, pusherKey = defaultSettings.pusherKey, metadata }) => Promise.resolve(preconnect(pusherKey))
|
|
1053
|
-
.then(() => fromUrl(sourceUrl, {
|
|
1054
|
-
publicKey,
|
|
1055
|
-
fileName,
|
|
1056
|
-
baseURL,
|
|
1057
|
-
checkForUrlDuplicates,
|
|
1058
|
-
saveUrlForRecurrentUploads,
|
|
1059
|
-
secureSignature,
|
|
1060
|
-
secureExpire,
|
|
1061
|
-
store,
|
|
1062
|
-
signal,
|
|
1063
|
-
source,
|
|
1064
|
-
integration,
|
|
1065
|
-
userAgent,
|
|
1066
|
-
retryThrottledRequestMaxTimes,
|
|
1067
|
-
metadata
|
|
1068
|
-
}))
|
|
1069
|
-
.catch((error) => {
|
|
1070
|
-
const pusher = getPusher(pusherKey);
|
|
1071
|
-
pusher === null || pusher === void 0 ? void 0 : pusher.disconnect();
|
|
1072
|
-
return Promise.reject(error);
|
|
1073
|
-
})
|
|
1074
|
-
.then((urlResponse) => {
|
|
1075
|
-
if (urlResponse.type === TypeEnum.FileInfo) {
|
|
1076
|
-
return urlResponse;
|
|
1077
|
-
}
|
|
1078
|
-
else {
|
|
1079
|
-
return race([
|
|
1080
|
-
({ signal }) => pollStrategy({
|
|
1081
|
-
token: urlResponse.token,
|
|
1082
|
-
publicKey,
|
|
1083
|
-
baseURL,
|
|
1084
|
-
integration,
|
|
1085
|
-
userAgent,
|
|
1086
|
-
retryThrottledRequestMaxTimes,
|
|
1087
|
-
onProgress,
|
|
1088
|
-
signal
|
|
1089
|
-
}),
|
|
1090
|
-
({ signal }) => pushStrategy({
|
|
1091
|
-
token: urlResponse.token,
|
|
1092
|
-
pusherKey,
|
|
1093
|
-
signal,
|
|
1094
|
-
onProgress
|
|
1095
|
-
})
|
|
1096
|
-
], { signal });
|
|
1097
|
-
}
|
|
1098
|
-
})
|
|
1099
|
-
.then((result) => {
|
|
1100
|
-
if (result instanceof UploadClientError)
|
|
1101
|
-
throw result;
|
|
1102
|
-
return result;
|
|
1103
|
-
})
|
|
1104
|
-
.then((result) => isReadyPoll({
|
|
1105
|
-
file: result.uuid,
|
|
1106
|
-
publicKey,
|
|
1107
|
-
baseURL,
|
|
1108
|
-
integration,
|
|
1109
|
-
userAgent,
|
|
1110
|
-
retryThrottledRequestMaxTimes,
|
|
1111
|
-
onProgress,
|
|
1112
|
-
signal
|
|
1113
|
-
}))
|
|
948
|
+
function pollStrategy({ token, publicKey, baseURL, integration, userAgent, retryThrottledRequestMaxTimes, onProgress, signal }) {
|
|
949
|
+
return poll({
|
|
950
|
+
check: (signal) => fromUrlStatus(token, {
|
|
951
|
+
publicKey,
|
|
952
|
+
baseURL,
|
|
953
|
+
integration,
|
|
954
|
+
userAgent,
|
|
955
|
+
retryThrottledRequestMaxTimes,
|
|
956
|
+
signal
|
|
957
|
+
}).then((response) => {
|
|
958
|
+
switch (response.status) {
|
|
959
|
+
case Status.Error: {
|
|
960
|
+
return new UploadClientError(response.error, response.errorCode);
|
|
961
|
+
}
|
|
962
|
+
case Status.Waiting: {
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
case Status.Unknown: {
|
|
966
|
+
return new UploadClientError(`Token "${token}" was not found.`);
|
|
967
|
+
}
|
|
968
|
+
case Status.Progress: {
|
|
969
|
+
if (onProgress) {
|
|
970
|
+
if (response.total === 'unknown') {
|
|
971
|
+
onProgress({ isComputable: false });
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
onProgress({
|
|
975
|
+
isComputable: true,
|
|
976
|
+
value: response.done / response.total
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return false;
|
|
981
|
+
}
|
|
982
|
+
case Status.Success: {
|
|
983
|
+
if (onProgress)
|
|
984
|
+
onProgress({
|
|
985
|
+
isComputable: true,
|
|
986
|
+
value: response.done / response.total
|
|
987
|
+
});
|
|
988
|
+
return response;
|
|
989
|
+
}
|
|
990
|
+
default: {
|
|
991
|
+
throw new Error('Unknown status');
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}),
|
|
995
|
+
signal
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
const pushStrategy = ({ token, pusherKey, signal, onProgress }) => new Promise((resolve, reject) => {
|
|
999
|
+
const pusher = getPusher(pusherKey);
|
|
1000
|
+
const unsubErrorHandler = pusher.onError(reject);
|
|
1001
|
+
const destroy = () => {
|
|
1002
|
+
unsubErrorHandler();
|
|
1003
|
+
pusher.unsubscribe(token);
|
|
1004
|
+
};
|
|
1005
|
+
onCancel(signal, () => {
|
|
1006
|
+
destroy();
|
|
1007
|
+
reject(cancelError('pusher cancelled'));
|
|
1008
|
+
});
|
|
1009
|
+
pusher.subscribe(token, (result) => {
|
|
1010
|
+
switch (result.status) {
|
|
1011
|
+
case Status.Progress: {
|
|
1012
|
+
if (onProgress) {
|
|
1013
|
+
if (result.total === 'unknown') {
|
|
1014
|
+
onProgress({ isComputable: false });
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1017
|
+
onProgress({
|
|
1018
|
+
isComputable: true,
|
|
1019
|
+
value: result.done / result.total
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
break;
|
|
1024
|
+
}
|
|
1025
|
+
case Status.Success: {
|
|
1026
|
+
destroy();
|
|
1027
|
+
if (onProgress)
|
|
1028
|
+
onProgress({
|
|
1029
|
+
isComputable: true,
|
|
1030
|
+
value: result.done / result.total
|
|
1031
|
+
});
|
|
1032
|
+
resolve(result);
|
|
1033
|
+
break;
|
|
1034
|
+
}
|
|
1035
|
+
case Status.Error: {
|
|
1036
|
+
destroy();
|
|
1037
|
+
reject(new UploadClientError(result.msg, result.error_code));
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
});
|
|
1042
|
+
const uploadFromUrl = (sourceUrl, { publicKey, fileName, baseURL, baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, pusherKey = defaultSettings.pusherKey, metadata }) => Promise.resolve(preconnect(pusherKey))
|
|
1043
|
+
.then(() => fromUrl(sourceUrl, {
|
|
1044
|
+
publicKey,
|
|
1045
|
+
fileName,
|
|
1046
|
+
baseURL,
|
|
1047
|
+
checkForUrlDuplicates,
|
|
1048
|
+
saveUrlForRecurrentUploads,
|
|
1049
|
+
secureSignature,
|
|
1050
|
+
secureExpire,
|
|
1051
|
+
store,
|
|
1052
|
+
signal,
|
|
1053
|
+
source,
|
|
1054
|
+
integration,
|
|
1055
|
+
userAgent,
|
|
1056
|
+
retryThrottledRequestMaxTimes,
|
|
1057
|
+
metadata
|
|
1058
|
+
}))
|
|
1059
|
+
.catch((error) => {
|
|
1060
|
+
const pusher = getPusher(pusherKey);
|
|
1061
|
+
pusher === null || pusher === void 0 ? void 0 : pusher.disconnect();
|
|
1062
|
+
return Promise.reject(error);
|
|
1063
|
+
})
|
|
1064
|
+
.then((urlResponse) => {
|
|
1065
|
+
if (urlResponse.type === TypeEnum.FileInfo) {
|
|
1066
|
+
return urlResponse;
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
return race([
|
|
1070
|
+
({ signal }) => pollStrategy({
|
|
1071
|
+
token: urlResponse.token,
|
|
1072
|
+
publicKey,
|
|
1073
|
+
baseURL,
|
|
1074
|
+
integration,
|
|
1075
|
+
userAgent,
|
|
1076
|
+
retryThrottledRequestMaxTimes,
|
|
1077
|
+
onProgress,
|
|
1078
|
+
signal
|
|
1079
|
+
}),
|
|
1080
|
+
({ signal }) => pushStrategy({
|
|
1081
|
+
token: urlResponse.token,
|
|
1082
|
+
pusherKey,
|
|
1083
|
+
signal,
|
|
1084
|
+
onProgress
|
|
1085
|
+
})
|
|
1086
|
+
], { signal });
|
|
1087
|
+
}
|
|
1088
|
+
})
|
|
1089
|
+
.then((result) => {
|
|
1090
|
+
if (result instanceof UploadClientError)
|
|
1091
|
+
throw result;
|
|
1092
|
+
return result;
|
|
1093
|
+
})
|
|
1094
|
+
.then((result) => isReadyPoll({
|
|
1095
|
+
file: result.uuid,
|
|
1096
|
+
publicKey,
|
|
1097
|
+
baseURL,
|
|
1098
|
+
integration,
|
|
1099
|
+
userAgent,
|
|
1100
|
+
retryThrottledRequestMaxTimes,
|
|
1101
|
+
onProgress,
|
|
1102
|
+
signal
|
|
1103
|
+
}))
|
|
1114
1104
|
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
1115
1105
|
|
|
1116
|
-
const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN }) => {
|
|
1117
|
-
return info(uuid, {
|
|
1118
|
-
publicKey,
|
|
1119
|
-
baseURL,
|
|
1120
|
-
signal,
|
|
1121
|
-
source,
|
|
1122
|
-
integration,
|
|
1123
|
-
userAgent,
|
|
1124
|
-
retryThrottledRequestMaxTimes
|
|
1125
|
-
})
|
|
1126
|
-
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
|
|
1127
|
-
.then((result) => {
|
|
1128
|
-
// hack for node ¯\_(ツ)_/¯
|
|
1129
|
-
if (onProgress)
|
|
1130
|
-
onProgress({
|
|
1131
|
-
isComputable: true,
|
|
1132
|
-
value: 1
|
|
1133
|
-
});
|
|
1134
|
-
return result;
|
|
1135
|
-
});
|
|
1106
|
+
const uploadFromUploaded = (uuid, { publicKey, fileName, baseURL, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, baseCDN }) => {
|
|
1107
|
+
return info(uuid, {
|
|
1108
|
+
publicKey,
|
|
1109
|
+
baseURL,
|
|
1110
|
+
signal,
|
|
1111
|
+
source,
|
|
1112
|
+
integration,
|
|
1113
|
+
userAgent,
|
|
1114
|
+
retryThrottledRequestMaxTimes
|
|
1115
|
+
})
|
|
1116
|
+
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN, fileName }))
|
|
1117
|
+
.then((result) => {
|
|
1118
|
+
// hack for node ¯\_(ツ)_/¯
|
|
1119
|
+
if (onProgress)
|
|
1120
|
+
onProgress({
|
|
1121
|
+
isComputable: true,
|
|
1122
|
+
value: 1
|
|
1123
|
+
});
|
|
1124
|
+
return result;
|
|
1125
|
+
});
|
|
1136
1126
|
};
|
|
1137
1127
|
|
|
1138
|
-
/**
|
|
1139
|
-
* Get file size.
|
|
1140
|
-
*/
|
|
1141
|
-
const getFileSize = (file) => {
|
|
1142
|
-
return file.length || file.size;
|
|
1143
|
-
};
|
|
1144
|
-
/**
|
|
1145
|
-
* Check if FileData is multipart data.
|
|
1146
|
-
*/
|
|
1147
|
-
const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartMinFileSize) => {
|
|
1148
|
-
return fileSize >= multipartMinFileSize;
|
|
1128
|
+
/**
|
|
1129
|
+
* Get file size.
|
|
1130
|
+
*/
|
|
1131
|
+
const getFileSize = (file) => {
|
|
1132
|
+
return file.length || file.size;
|
|
1133
|
+
};
|
|
1134
|
+
/**
|
|
1135
|
+
* Check if FileData is multipart data.
|
|
1136
|
+
*/
|
|
1137
|
+
const isMultipart = (fileSize, multipartMinFileSize = defaultSettings.multipartMinFileSize) => {
|
|
1138
|
+
return fileSize >= multipartMinFileSize;
|
|
1149
1139
|
};
|
|
1150
1140
|
|
|
1151
|
-
const sliceChunk = (file, index, fileSize, chunkSize) => {
|
|
1152
|
-
const start = chunkSize * index;
|
|
1153
|
-
const end = Math.min(start + chunkSize, fileSize);
|
|
1154
|
-
return file.slice(start, end);
|
|
1141
|
+
const sliceChunk = (file, index, fileSize, chunkSize) => {
|
|
1142
|
+
const start = chunkSize * index;
|
|
1143
|
+
const end = Math.min(start + chunkSize, fileSize);
|
|
1144
|
+
return file.slice(start, end);
|
|
1155
1145
|
};
|
|
1156
1146
|
|
|
1157
|
-
function prepareChunks(file, fileSize, chunkSize) {
|
|
1158
|
-
return (index) => sliceChunk(file, index, fileSize, chunkSize);
|
|
1147
|
+
function prepareChunks(file, fileSize, chunkSize) {
|
|
1148
|
+
return (index) => sliceChunk(file, index, fileSize, chunkSize);
|
|
1159
1149
|
}
|
|
1160
1150
|
|
|
1161
|
-
const runWithConcurrency = (concurrency, tasks) => {
|
|
1162
|
-
return new Promise((resolve, reject) => {
|
|
1163
|
-
const results = [];
|
|
1164
|
-
let rejected = false;
|
|
1165
|
-
let settled = tasks.length;
|
|
1166
|
-
const forRun = [...tasks];
|
|
1167
|
-
const run = () => {
|
|
1168
|
-
const index = tasks.length - forRun.length;
|
|
1169
|
-
const next = forRun.shift();
|
|
1170
|
-
if (next) {
|
|
1171
|
-
next()
|
|
1172
|
-
.then((result) => {
|
|
1173
|
-
if (rejected)
|
|
1174
|
-
return;
|
|
1175
|
-
results[index] = result;
|
|
1176
|
-
settled -= 1;
|
|
1177
|
-
if (settled) {
|
|
1178
|
-
run();
|
|
1179
|
-
}
|
|
1180
|
-
else {
|
|
1181
|
-
resolve(results);
|
|
1182
|
-
}
|
|
1183
|
-
})
|
|
1184
|
-
.catch((error) => {
|
|
1185
|
-
rejected = true;
|
|
1186
|
-
reject(error);
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
};
|
|
1190
|
-
for (let i = 0; i < concurrency; i++) {
|
|
1191
|
-
run();
|
|
1192
|
-
}
|
|
1193
|
-
});
|
|
1151
|
+
const runWithConcurrency = (concurrency, tasks) => {
|
|
1152
|
+
return new Promise((resolve, reject) => {
|
|
1153
|
+
const results = [];
|
|
1154
|
+
let rejected = false;
|
|
1155
|
+
let settled = tasks.length;
|
|
1156
|
+
const forRun = [...tasks];
|
|
1157
|
+
const run = () => {
|
|
1158
|
+
const index = tasks.length - forRun.length;
|
|
1159
|
+
const next = forRun.shift();
|
|
1160
|
+
if (next) {
|
|
1161
|
+
next()
|
|
1162
|
+
.then((result) => {
|
|
1163
|
+
if (rejected)
|
|
1164
|
+
return;
|
|
1165
|
+
results[index] = result;
|
|
1166
|
+
settled -= 1;
|
|
1167
|
+
if (settled) {
|
|
1168
|
+
run();
|
|
1169
|
+
}
|
|
1170
|
+
else {
|
|
1171
|
+
resolve(results);
|
|
1172
|
+
}
|
|
1173
|
+
})
|
|
1174
|
+
.catch((error) => {
|
|
1175
|
+
rejected = true;
|
|
1176
|
+
reject(error);
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
for (let i = 0; i < concurrency; i++) {
|
|
1181
|
+
run();
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1194
1184
|
};
|
|
1195
1185
|
|
|
1196
|
-
const uploadPartWithRetry = (chunk, url, { publicKey, onProgress, signal, integration, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
|
|
1197
|
-
publicKey,
|
|
1198
|
-
onProgress,
|
|
1199
|
-
signal,
|
|
1200
|
-
integration
|
|
1201
|
-
}).catch((error) => {
|
|
1202
|
-
if (attempt < multipartMaxAttempts) {
|
|
1203
|
-
return retry();
|
|
1204
|
-
}
|
|
1205
|
-
throw error;
|
|
1206
|
-
}));
|
|
1207
|
-
const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, maxConcurrentRequests = defaultSettings.maxConcurrentRequests, multipartMaxAttempts = defaultSettings.multipartMaxAttempts, baseCDN, metadata }) => {
|
|
1208
|
-
const size = fileSize || getFileSize(file);
|
|
1209
|
-
let progressValues;
|
|
1210
|
-
const createProgressHandler = (totalChunks, chunkIdx) => {
|
|
1211
|
-
if (!onProgress)
|
|
1212
|
-
return;
|
|
1213
|
-
if (!progressValues) {
|
|
1214
|
-
progressValues = Array(totalChunks).fill(0);
|
|
1215
|
-
}
|
|
1216
|
-
const sum = (values) => values.reduce((sum, next) => sum + next, 0);
|
|
1217
|
-
return (info) => {
|
|
1218
|
-
if (!info.isComputable) {
|
|
1219
|
-
return;
|
|
1220
|
-
}
|
|
1221
|
-
progressValues[chunkIdx] = info.value;
|
|
1222
|
-
onProgress({
|
|
1223
|
-
isComputable: true,
|
|
1224
|
-
value: sum(progressValues) / totalChunks
|
|
1225
|
-
});
|
|
1226
|
-
};
|
|
1227
|
-
};
|
|
1228
|
-
return multipartStart(size, {
|
|
1229
|
-
publicKey,
|
|
1230
|
-
contentType,
|
|
1231
|
-
fileName: fileName !== null && fileName !== void 0 ? fileName : file.name,
|
|
1232
|
-
baseURL,
|
|
1233
|
-
secureSignature,
|
|
1234
|
-
secureExpire,
|
|
1235
|
-
store,
|
|
1236
|
-
signal,
|
|
1237
|
-
source,
|
|
1238
|
-
integration,
|
|
1239
|
-
userAgent,
|
|
1240
|
-
retryThrottledRequestMaxTimes,
|
|
1241
|
-
metadata
|
|
1242
|
-
})
|
|
1243
|
-
.then(({ uuid, parts }) => {
|
|
1244
|
-
const getChunk = prepareChunks(file, size, multipartChunkSize);
|
|
1245
|
-
return Promise.all([
|
|
1246
|
-
uuid,
|
|
1247
|
-
runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(index), url, {
|
|
1248
|
-
publicKey,
|
|
1249
|
-
onProgress: createProgressHandler(parts.length, index),
|
|
1250
|
-
signal,
|
|
1251
|
-
integration,
|
|
1252
|
-
multipartMaxAttempts
|
|
1253
|
-
})))
|
|
1254
|
-
]);
|
|
1255
|
-
})
|
|
1256
|
-
.then(([uuid]) => multipartComplete(uuid, {
|
|
1257
|
-
publicKey,
|
|
1258
|
-
baseURL,
|
|
1259
|
-
source,
|
|
1260
|
-
integration,
|
|
1261
|
-
userAgent,
|
|
1262
|
-
retryThrottledRequestMaxTimes
|
|
1263
|
-
}))
|
|
1264
|
-
.then((fileInfo) => {
|
|
1265
|
-
if (fileInfo.isReady) {
|
|
1266
|
-
return fileInfo;
|
|
1267
|
-
}
|
|
1268
|
-
else {
|
|
1269
|
-
return isReadyPoll({
|
|
1270
|
-
file: fileInfo.uuid,
|
|
1271
|
-
publicKey,
|
|
1272
|
-
baseURL,
|
|
1273
|
-
source,
|
|
1274
|
-
integration,
|
|
1275
|
-
userAgent,
|
|
1276
|
-
retryThrottledRequestMaxTimes,
|
|
1277
|
-
onProgress,
|
|
1278
|
-
signal
|
|
1279
|
-
});
|
|
1280
|
-
}
|
|
1281
|
-
})
|
|
1282
|
-
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
1186
|
+
const uploadPartWithRetry = (chunk, url, { publicKey, onProgress, signal, integration, multipartMaxAttempts }) => retrier(({ attempt, retry }) => multipartUpload(chunk, url, {
|
|
1187
|
+
publicKey,
|
|
1188
|
+
onProgress,
|
|
1189
|
+
signal,
|
|
1190
|
+
integration
|
|
1191
|
+
}).catch((error) => {
|
|
1192
|
+
if (attempt < multipartMaxAttempts) {
|
|
1193
|
+
return retry();
|
|
1194
|
+
}
|
|
1195
|
+
throw error;
|
|
1196
|
+
}));
|
|
1197
|
+
const uploadMultipart = (file, { publicKey, fileName, fileSize, baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, maxConcurrentRequests = defaultSettings.maxConcurrentRequests, multipartMaxAttempts = defaultSettings.multipartMaxAttempts, baseCDN, metadata }) => {
|
|
1198
|
+
const size = fileSize || getFileSize(file);
|
|
1199
|
+
let progressValues;
|
|
1200
|
+
const createProgressHandler = (totalChunks, chunkIdx) => {
|
|
1201
|
+
if (!onProgress)
|
|
1202
|
+
return;
|
|
1203
|
+
if (!progressValues) {
|
|
1204
|
+
progressValues = Array(totalChunks).fill(0);
|
|
1205
|
+
}
|
|
1206
|
+
const sum = (values) => values.reduce((sum, next) => sum + next, 0);
|
|
1207
|
+
return (info) => {
|
|
1208
|
+
if (!info.isComputable) {
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
progressValues[chunkIdx] = info.value;
|
|
1212
|
+
onProgress({
|
|
1213
|
+
isComputable: true,
|
|
1214
|
+
value: sum(progressValues) / totalChunks
|
|
1215
|
+
});
|
|
1216
|
+
};
|
|
1217
|
+
};
|
|
1218
|
+
return multipartStart(size, {
|
|
1219
|
+
publicKey,
|
|
1220
|
+
contentType,
|
|
1221
|
+
fileName: fileName !== null && fileName !== void 0 ? fileName : file.name,
|
|
1222
|
+
baseURL,
|
|
1223
|
+
secureSignature,
|
|
1224
|
+
secureExpire,
|
|
1225
|
+
store,
|
|
1226
|
+
signal,
|
|
1227
|
+
source,
|
|
1228
|
+
integration,
|
|
1229
|
+
userAgent,
|
|
1230
|
+
retryThrottledRequestMaxTimes,
|
|
1231
|
+
metadata
|
|
1232
|
+
})
|
|
1233
|
+
.then(({ uuid, parts }) => {
|
|
1234
|
+
const getChunk = prepareChunks(file, size, multipartChunkSize);
|
|
1235
|
+
return Promise.all([
|
|
1236
|
+
uuid,
|
|
1237
|
+
runWithConcurrency(maxConcurrentRequests, parts.map((url, index) => () => uploadPartWithRetry(getChunk(index), url, {
|
|
1238
|
+
publicKey,
|
|
1239
|
+
onProgress: createProgressHandler(parts.length, index),
|
|
1240
|
+
signal,
|
|
1241
|
+
integration,
|
|
1242
|
+
multipartMaxAttempts
|
|
1243
|
+
})))
|
|
1244
|
+
]);
|
|
1245
|
+
})
|
|
1246
|
+
.then(([uuid]) => multipartComplete(uuid, {
|
|
1247
|
+
publicKey,
|
|
1248
|
+
baseURL,
|
|
1249
|
+
source,
|
|
1250
|
+
integration,
|
|
1251
|
+
userAgent,
|
|
1252
|
+
retryThrottledRequestMaxTimes
|
|
1253
|
+
}))
|
|
1254
|
+
.then((fileInfo) => {
|
|
1255
|
+
if (fileInfo.isReady) {
|
|
1256
|
+
return fileInfo;
|
|
1257
|
+
}
|
|
1258
|
+
else {
|
|
1259
|
+
return isReadyPoll({
|
|
1260
|
+
file: fileInfo.uuid,
|
|
1261
|
+
publicKey,
|
|
1262
|
+
baseURL,
|
|
1263
|
+
source,
|
|
1264
|
+
integration,
|
|
1265
|
+
userAgent,
|
|
1266
|
+
retryThrottledRequestMaxTimes,
|
|
1267
|
+
onProgress,
|
|
1268
|
+
signal
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
})
|
|
1272
|
+
.then((fileInfo) => new UploadcareFile(fileInfo, { baseCDN }));
|
|
1283
1273
|
};
|
|
1284
1274
|
|
|
1285
|
-
/**
|
|
1286
|
-
* Uploads file from provided data.
|
|
1287
|
-
*/
|
|
1288
|
-
function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartMinFileSize, multipartChunkSize, multipartMaxAttempts, maxConcurrentRequests, baseCDN = defaultSettings.baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, pusherKey, metadata }) {
|
|
1289
|
-
if (isFileData(data)) {
|
|
1290
|
-
const fileSize = getFileSize(data);
|
|
1291
|
-
if (isMultipart(fileSize, multipartMinFileSize)) {
|
|
1292
|
-
return uploadMultipart(data, {
|
|
1293
|
-
publicKey,
|
|
1294
|
-
contentType,
|
|
1295
|
-
multipartChunkSize,
|
|
1296
|
-
multipartMaxAttempts,
|
|
1297
|
-
fileName,
|
|
1298
|
-
baseURL,
|
|
1299
|
-
secureSignature,
|
|
1300
|
-
secureExpire,
|
|
1301
|
-
store,
|
|
1302
|
-
signal,
|
|
1303
|
-
onProgress,
|
|
1304
|
-
source,
|
|
1305
|
-
integration,
|
|
1306
|
-
userAgent,
|
|
1307
|
-
maxConcurrentRequests,
|
|
1308
|
-
retryThrottledRequestMaxTimes,
|
|
1309
|
-
baseCDN,
|
|
1310
|
-
metadata
|
|
1311
|
-
});
|
|
1312
|
-
}
|
|
1313
|
-
return
|
|
1314
|
-
publicKey,
|
|
1315
|
-
fileName,
|
|
1316
|
-
contentType,
|
|
1317
|
-
baseURL,
|
|
1318
|
-
secureSignature,
|
|
1319
|
-
secureExpire,
|
|
1320
|
-
store,
|
|
1321
|
-
signal,
|
|
1322
|
-
onProgress,
|
|
1323
|
-
source,
|
|
1324
|
-
integration,
|
|
1325
|
-
userAgent,
|
|
1326
|
-
retryThrottledRequestMaxTimes,
|
|
1327
|
-
baseCDN,
|
|
1328
|
-
metadata
|
|
1329
|
-
});
|
|
1330
|
-
}
|
|
1331
|
-
if (isUrl(data)) {
|
|
1332
|
-
return uploadFromUrl(data, {
|
|
1333
|
-
publicKey,
|
|
1334
|
-
fileName,
|
|
1335
|
-
baseURL,
|
|
1336
|
-
baseCDN,
|
|
1337
|
-
checkForUrlDuplicates,
|
|
1338
|
-
saveUrlForRecurrentUploads,
|
|
1339
|
-
secureSignature,
|
|
1340
|
-
secureExpire,
|
|
1341
|
-
store,
|
|
1342
|
-
signal,
|
|
1343
|
-
onProgress,
|
|
1344
|
-
source,
|
|
1345
|
-
integration,
|
|
1346
|
-
userAgent,
|
|
1347
|
-
retryThrottledRequestMaxTimes,
|
|
1348
|
-
pusherKey,
|
|
1349
|
-
metadata
|
|
1350
|
-
});
|
|
1351
|
-
}
|
|
1352
|
-
if (isUuid(data)) {
|
|
1353
|
-
return uploadFromUploaded(data, {
|
|
1354
|
-
publicKey,
|
|
1355
|
-
fileName,
|
|
1356
|
-
baseURL,
|
|
1357
|
-
signal,
|
|
1358
|
-
onProgress,
|
|
1359
|
-
source,
|
|
1360
|
-
integration,
|
|
1361
|
-
userAgent,
|
|
1362
|
-
retryThrottledRequestMaxTimes,
|
|
1363
|
-
baseCDN
|
|
1364
|
-
});
|
|
1365
|
-
}
|
|
1366
|
-
throw new TypeError(`File uploading from "${data}" is not supported`);
|
|
1275
|
+
/**
|
|
1276
|
+
* Uploads file from provided data.
|
|
1277
|
+
*/
|
|
1278
|
+
function uploadFile(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartMinFileSize, multipartChunkSize, multipartMaxAttempts, maxConcurrentRequests, baseCDN = defaultSettings.baseCDN, checkForUrlDuplicates, saveUrlForRecurrentUploads, pusherKey, metadata }) {
|
|
1279
|
+
if (isFileData(data)) {
|
|
1280
|
+
const fileSize = getFileSize(data);
|
|
1281
|
+
if (isMultipart(fileSize, multipartMinFileSize)) {
|
|
1282
|
+
return uploadMultipart(data, {
|
|
1283
|
+
publicKey,
|
|
1284
|
+
contentType,
|
|
1285
|
+
multipartChunkSize,
|
|
1286
|
+
multipartMaxAttempts,
|
|
1287
|
+
fileName,
|
|
1288
|
+
baseURL,
|
|
1289
|
+
secureSignature,
|
|
1290
|
+
secureExpire,
|
|
1291
|
+
store,
|
|
1292
|
+
signal,
|
|
1293
|
+
onProgress,
|
|
1294
|
+
source,
|
|
1295
|
+
integration,
|
|
1296
|
+
userAgent,
|
|
1297
|
+
maxConcurrentRequests,
|
|
1298
|
+
retryThrottledRequestMaxTimes,
|
|
1299
|
+
baseCDN,
|
|
1300
|
+
metadata
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
return uploadDirect(data, {
|
|
1304
|
+
publicKey,
|
|
1305
|
+
fileName,
|
|
1306
|
+
contentType,
|
|
1307
|
+
baseURL,
|
|
1308
|
+
secureSignature,
|
|
1309
|
+
secureExpire,
|
|
1310
|
+
store,
|
|
1311
|
+
signal,
|
|
1312
|
+
onProgress,
|
|
1313
|
+
source,
|
|
1314
|
+
integration,
|
|
1315
|
+
userAgent,
|
|
1316
|
+
retryThrottledRequestMaxTimes,
|
|
1317
|
+
baseCDN,
|
|
1318
|
+
metadata
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
if (isUrl(data)) {
|
|
1322
|
+
return uploadFromUrl(data, {
|
|
1323
|
+
publicKey,
|
|
1324
|
+
fileName,
|
|
1325
|
+
baseURL,
|
|
1326
|
+
baseCDN,
|
|
1327
|
+
checkForUrlDuplicates,
|
|
1328
|
+
saveUrlForRecurrentUploads,
|
|
1329
|
+
secureSignature,
|
|
1330
|
+
secureExpire,
|
|
1331
|
+
store,
|
|
1332
|
+
signal,
|
|
1333
|
+
onProgress,
|
|
1334
|
+
source,
|
|
1335
|
+
integration,
|
|
1336
|
+
userAgent,
|
|
1337
|
+
retryThrottledRequestMaxTimes,
|
|
1338
|
+
pusherKey,
|
|
1339
|
+
metadata
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
if (isUuid(data)) {
|
|
1343
|
+
return uploadFromUploaded(data, {
|
|
1344
|
+
publicKey,
|
|
1345
|
+
fileName,
|
|
1346
|
+
baseURL,
|
|
1347
|
+
signal,
|
|
1348
|
+
onProgress,
|
|
1349
|
+
source,
|
|
1350
|
+
integration,
|
|
1351
|
+
userAgent,
|
|
1352
|
+
retryThrottledRequestMaxTimes,
|
|
1353
|
+
baseCDN
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
throw new TypeError(`File uploading from "${data}" is not supported`);
|
|
1367
1357
|
}
|
|
1368
1358
|
|
|
1369
|
-
class UploadcareGroup {
|
|
1370
|
-
constructor(groupInfo, files) {
|
|
1371
|
-
this.storedAt = null;
|
|
1372
|
-
this.uuid = groupInfo.id;
|
|
1373
|
-
this.filesCount = groupInfo.filesCount;
|
|
1374
|
-
this.totalSize = Object.values(groupInfo.files).reduce((acc, file) => acc + file.size, 0);
|
|
1375
|
-
this.isStored = !!groupInfo.datetimeStored;
|
|
1376
|
-
this.isImage = !!Object.values(groupInfo.files).filter((file) => file.isImage).length;
|
|
1377
|
-
this.cdnUrl = groupInfo.cdnUrl;
|
|
1378
|
-
this.files = files;
|
|
1379
|
-
this.createdAt = groupInfo.datetimeCreated;
|
|
1380
|
-
this.storedAt = groupInfo.datetimeStored;
|
|
1381
|
-
}
|
|
1359
|
+
class UploadcareGroup {
|
|
1360
|
+
constructor(groupInfo, files) {
|
|
1361
|
+
this.storedAt = null;
|
|
1362
|
+
this.uuid = groupInfo.id;
|
|
1363
|
+
this.filesCount = groupInfo.filesCount;
|
|
1364
|
+
this.totalSize = Object.values(groupInfo.files).reduce((acc, file) => acc + file.size, 0);
|
|
1365
|
+
this.isStored = !!groupInfo.datetimeStored;
|
|
1366
|
+
this.isImage = !!Object.values(groupInfo.files).filter((file) => file.isImage).length;
|
|
1367
|
+
this.cdnUrl = groupInfo.cdnUrl;
|
|
1368
|
+
this.files = files;
|
|
1369
|
+
this.createdAt = groupInfo.datetimeCreated;
|
|
1370
|
+
this.storedAt = groupInfo.datetimeStored;
|
|
1371
|
+
}
|
|
1382
1372
|
}
|
|
1383
1373
|
|
|
1384
|
-
/**
|
|
1385
|
-
* FileData type guard.
|
|
1386
|
-
*/
|
|
1387
|
-
const isFileDataArray = (data) => {
|
|
1388
|
-
for (const item of data) {
|
|
1389
|
-
if (!isFileData(item)) {
|
|
1390
|
-
return false;
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
return true;
|
|
1394
|
-
};
|
|
1395
|
-
/**
|
|
1396
|
-
* Uuid type guard.
|
|
1397
|
-
*/
|
|
1398
|
-
const isUuidArray = (data) => {
|
|
1399
|
-
for (const item of data) {
|
|
1400
|
-
if (!isUuid(item)) {
|
|
1401
|
-
return false;
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
return true;
|
|
1405
|
-
};
|
|
1406
|
-
/**
|
|
1407
|
-
* Url type guard.
|
|
1408
|
-
*/
|
|
1409
|
-
const isUrlArray = (data) => {
|
|
1410
|
-
for (const item of data) {
|
|
1411
|
-
if (!isUrl(item)) {
|
|
1412
|
-
return false;
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
return true;
|
|
1374
|
+
/**
|
|
1375
|
+
* FileData type guard.
|
|
1376
|
+
*/
|
|
1377
|
+
const isFileDataArray = (data) => {
|
|
1378
|
+
for (const item of data) {
|
|
1379
|
+
if (!isFileData(item)) {
|
|
1380
|
+
return false;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
return true;
|
|
1384
|
+
};
|
|
1385
|
+
/**
|
|
1386
|
+
* Uuid type guard.
|
|
1387
|
+
*/
|
|
1388
|
+
const isUuidArray = (data) => {
|
|
1389
|
+
for (const item of data) {
|
|
1390
|
+
if (!isUuid(item)) {
|
|
1391
|
+
return false;
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return true;
|
|
1395
|
+
};
|
|
1396
|
+
/**
|
|
1397
|
+
* Url type guard.
|
|
1398
|
+
*/
|
|
1399
|
+
const isUrlArray = (data) => {
|
|
1400
|
+
for (const item of data) {
|
|
1401
|
+
if (!isUrl(item)) {
|
|
1402
|
+
return false;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
return true;
|
|
1416
1406
|
};
|
|
1417
1407
|
|
|
1418
|
-
function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, baseCDN = defaultSettings.baseCDN, jsonpCallback
|
|
1419
|
-
if (!isFileDataArray(data) && !isUrlArray(data) && !isUuidArray(data)) {
|
|
1420
|
-
throw new TypeError(`Group uploading from "${data}" is not supported`);
|
|
1421
|
-
}
|
|
1422
|
-
let progressValues;
|
|
1423
|
-
let isStillComputable = true;
|
|
1424
|
-
const filesCount = data.length;
|
|
1425
|
-
const createProgressHandler = (size, index) => {
|
|
1426
|
-
if (!onProgress)
|
|
1427
|
-
return;
|
|
1428
|
-
if (!progressValues) {
|
|
1429
|
-
progressValues = Array(size).fill(0);
|
|
1430
|
-
}
|
|
1431
|
-
const normalize = (values) => values.reduce((sum, next) => sum + next) / size;
|
|
1432
|
-
return (info) => {
|
|
1433
|
-
if (!info.isComputable || !isStillComputable) {
|
|
1434
|
-
isStillComputable = false;
|
|
1435
|
-
onProgress({ isComputable: false });
|
|
1436
|
-
return;
|
|
1437
|
-
}
|
|
1438
|
-
progressValues[index] = info.value;
|
|
1439
|
-
onProgress({ isComputable: true, value: normalize(progressValues) });
|
|
1440
|
-
};
|
|
1441
|
-
};
|
|
1442
|
-
return Promise.all(data.map((file, index) => uploadFile(file, {
|
|
1443
|
-
publicKey,
|
|
1444
|
-
fileName,
|
|
1445
|
-
baseURL,
|
|
1446
|
-
secureSignature,
|
|
1447
|
-
secureExpire,
|
|
1448
|
-
store,
|
|
1449
|
-
signal,
|
|
1450
|
-
onProgress: createProgressHandler(filesCount, index),
|
|
1451
|
-
source,
|
|
1452
|
-
integration,
|
|
1453
|
-
userAgent,
|
|
1454
|
-
retryThrottledRequestMaxTimes,
|
|
1455
|
-
contentType,
|
|
1456
|
-
multipartChunkSize,
|
|
1457
|
-
baseCDN
|
|
1458
|
-
}))).then((files) => {
|
|
1459
|
-
const uuids = files.map((file) => file.uuid);
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
})
|
|
1479
|
-
.then((groupInfo) => new UploadcareGroup(groupInfo, filesInGroup))
|
|
1480
|
-
.then((group) => {
|
|
1481
|
-
onProgress && onProgress({ isComputable: true, value: 1 });
|
|
1482
|
-
return group;
|
|
1483
|
-
});
|
|
1484
|
-
});
|
|
1408
|
+
function uploadFileGroup(data, { publicKey, fileName, baseURL = defaultSettings.baseURL, secureSignature, secureExpire, store, signal, onProgress, source, integration, userAgent, retryThrottledRequestMaxTimes, contentType, multipartChunkSize = defaultSettings.multipartChunkSize, baseCDN = defaultSettings.baseCDN, jsonpCallback }) {
|
|
1409
|
+
if (!isFileDataArray(data) && !isUrlArray(data) && !isUuidArray(data)) {
|
|
1410
|
+
throw new TypeError(`Group uploading from "${data}" is not supported`);
|
|
1411
|
+
}
|
|
1412
|
+
let progressValues;
|
|
1413
|
+
let isStillComputable = true;
|
|
1414
|
+
const filesCount = data.length;
|
|
1415
|
+
const createProgressHandler = (size, index) => {
|
|
1416
|
+
if (!onProgress)
|
|
1417
|
+
return;
|
|
1418
|
+
if (!progressValues) {
|
|
1419
|
+
progressValues = Array(size).fill(0);
|
|
1420
|
+
}
|
|
1421
|
+
const normalize = (values) => values.reduce((sum, next) => sum + next) / size;
|
|
1422
|
+
return (info) => {
|
|
1423
|
+
if (!info.isComputable || !isStillComputable) {
|
|
1424
|
+
isStillComputable = false;
|
|
1425
|
+
onProgress({ isComputable: false });
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1428
|
+
progressValues[index] = info.value;
|
|
1429
|
+
onProgress({ isComputable: true, value: normalize(progressValues) });
|
|
1430
|
+
};
|
|
1431
|
+
};
|
|
1432
|
+
return Promise.all(data.map((file, index) => uploadFile(file, {
|
|
1433
|
+
publicKey,
|
|
1434
|
+
fileName,
|
|
1435
|
+
baseURL,
|
|
1436
|
+
secureSignature,
|
|
1437
|
+
secureExpire,
|
|
1438
|
+
store,
|
|
1439
|
+
signal,
|
|
1440
|
+
onProgress: createProgressHandler(filesCount, index),
|
|
1441
|
+
source,
|
|
1442
|
+
integration,
|
|
1443
|
+
userAgent,
|
|
1444
|
+
retryThrottledRequestMaxTimes,
|
|
1445
|
+
contentType,
|
|
1446
|
+
multipartChunkSize,
|
|
1447
|
+
baseCDN
|
|
1448
|
+
}))).then((files) => {
|
|
1449
|
+
const uuids = files.map((file) => file.uuid);
|
|
1450
|
+
return group(uuids, {
|
|
1451
|
+
publicKey,
|
|
1452
|
+
baseURL,
|
|
1453
|
+
jsonpCallback,
|
|
1454
|
+
secureSignature,
|
|
1455
|
+
secureExpire,
|
|
1456
|
+
signal,
|
|
1457
|
+
source,
|
|
1458
|
+
integration,
|
|
1459
|
+
userAgent,
|
|
1460
|
+
retryThrottledRequestMaxTimes
|
|
1461
|
+
})
|
|
1462
|
+
.then((groupInfo) => new UploadcareGroup(groupInfo, files))
|
|
1463
|
+
.then((group) => {
|
|
1464
|
+
onProgress && onProgress({ isComputable: true, value: 1 });
|
|
1465
|
+
return group;
|
|
1466
|
+
});
|
|
1467
|
+
});
|
|
1485
1468
|
}
|
|
1486
1469
|
|
|
1487
|
-
/**
|
|
1488
|
-
* Populate options with settings.
|
|
1489
|
-
*/
|
|
1490
|
-
const populateOptionsWithSettings = (options, settings) => (Object.assign(Object.assign({}, settings), options));
|
|
1491
|
-
class UploadClient {
|
|
1492
|
-
constructor(settings) {
|
|
1493
|
-
this.settings = Object.assign({}, defaultSettings, settings);
|
|
1494
|
-
}
|
|
1495
|
-
updateSettings(newSettings) {
|
|
1496
|
-
this.settings = Object.assign(this.settings, newSettings);
|
|
1497
|
-
}
|
|
1498
|
-
getSettings() {
|
|
1499
|
-
return this.settings;
|
|
1500
|
-
}
|
|
1501
|
-
base(file, options) {
|
|
1502
|
-
const settings = this.getSettings();
|
|
1503
|
-
return base(file, populateOptionsWithSettings(options, settings));
|
|
1504
|
-
}
|
|
1505
|
-
info(uuid, options) {
|
|
1506
|
-
const settings = this.getSettings();
|
|
1507
|
-
return info(uuid, populateOptionsWithSettings(options, settings));
|
|
1508
|
-
}
|
|
1509
|
-
fromUrl(sourceUrl, options) {
|
|
1510
|
-
const settings = this.getSettings();
|
|
1511
|
-
return fromUrl(sourceUrl, populateOptionsWithSettings(options, settings));
|
|
1512
|
-
}
|
|
1513
|
-
fromUrlStatus(token, options) {
|
|
1514
|
-
const settings = this.getSettings();
|
|
1515
|
-
return fromUrlStatus(token, populateOptionsWithSettings(options, settings));
|
|
1516
|
-
}
|
|
1517
|
-
group(uuids, options) {
|
|
1518
|
-
const settings = this.getSettings();
|
|
1519
|
-
return group(uuids, populateOptionsWithSettings(options, settings));
|
|
1520
|
-
}
|
|
1521
|
-
groupInfo(id, options) {
|
|
1522
|
-
const settings = this.getSettings();
|
|
1523
|
-
return groupInfo(id, populateOptionsWithSettings(options, settings));
|
|
1524
|
-
}
|
|
1525
|
-
multipartStart(size, options) {
|
|
1526
|
-
const settings = this.getSettings();
|
|
1527
|
-
return multipartStart(size, populateOptionsWithSettings(options, settings));
|
|
1528
|
-
}
|
|
1529
|
-
multipartUpload(part, url, options) {
|
|
1530
|
-
const settings = this.getSettings();
|
|
1531
|
-
return multipartUpload(part, url, populateOptionsWithSettings(options, settings));
|
|
1532
|
-
}
|
|
1533
|
-
multipartComplete(uuid, options) {
|
|
1534
|
-
const settings = this.getSettings();
|
|
1535
|
-
return multipartComplete(uuid, populateOptionsWithSettings(options, settings));
|
|
1536
|
-
}
|
|
1537
|
-
uploadFile(data, options) {
|
|
1538
|
-
const settings = this.getSettings();
|
|
1539
|
-
return uploadFile(data, populateOptionsWithSettings(options, settings));
|
|
1540
|
-
}
|
|
1541
|
-
uploadFileGroup(data, options) {
|
|
1542
|
-
const settings = this.getSettings();
|
|
1543
|
-
return uploadFileGroup(data, populateOptionsWithSettings(options, settings));
|
|
1544
|
-
}
|
|
1470
|
+
/**
|
|
1471
|
+
* Populate options with settings.
|
|
1472
|
+
*/
|
|
1473
|
+
const populateOptionsWithSettings = (options, settings) => (Object.assign(Object.assign({}, settings), options));
|
|
1474
|
+
class UploadClient {
|
|
1475
|
+
constructor(settings) {
|
|
1476
|
+
this.settings = Object.assign({}, defaultSettings, settings);
|
|
1477
|
+
}
|
|
1478
|
+
updateSettings(newSettings) {
|
|
1479
|
+
this.settings = Object.assign(this.settings, newSettings);
|
|
1480
|
+
}
|
|
1481
|
+
getSettings() {
|
|
1482
|
+
return this.settings;
|
|
1483
|
+
}
|
|
1484
|
+
base(file, options = {}) {
|
|
1485
|
+
const settings = this.getSettings();
|
|
1486
|
+
return base(file, populateOptionsWithSettings(options, settings));
|
|
1487
|
+
}
|
|
1488
|
+
info(uuid, options = {}) {
|
|
1489
|
+
const settings = this.getSettings();
|
|
1490
|
+
return info(uuid, populateOptionsWithSettings(options, settings));
|
|
1491
|
+
}
|
|
1492
|
+
fromUrl(sourceUrl, options = {}) {
|
|
1493
|
+
const settings = this.getSettings();
|
|
1494
|
+
return fromUrl(sourceUrl, populateOptionsWithSettings(options, settings));
|
|
1495
|
+
}
|
|
1496
|
+
fromUrlStatus(token, options = {}) {
|
|
1497
|
+
const settings = this.getSettings();
|
|
1498
|
+
return fromUrlStatus(token, populateOptionsWithSettings(options, settings));
|
|
1499
|
+
}
|
|
1500
|
+
group(uuids, options = {}) {
|
|
1501
|
+
const settings = this.getSettings();
|
|
1502
|
+
return group(uuids, populateOptionsWithSettings(options, settings));
|
|
1503
|
+
}
|
|
1504
|
+
groupInfo(id, options = {}) {
|
|
1505
|
+
const settings = this.getSettings();
|
|
1506
|
+
return groupInfo(id, populateOptionsWithSettings(options, settings));
|
|
1507
|
+
}
|
|
1508
|
+
multipartStart(size, options = {}) {
|
|
1509
|
+
const settings = this.getSettings();
|
|
1510
|
+
return multipartStart(size, populateOptionsWithSettings(options, settings));
|
|
1511
|
+
}
|
|
1512
|
+
multipartUpload(part, url, options = {}) {
|
|
1513
|
+
const settings = this.getSettings();
|
|
1514
|
+
return multipartUpload(part, url, populateOptionsWithSettings(options, settings));
|
|
1515
|
+
}
|
|
1516
|
+
multipartComplete(uuid, options = {}) {
|
|
1517
|
+
const settings = this.getSettings();
|
|
1518
|
+
return multipartComplete(uuid, populateOptionsWithSettings(options, settings));
|
|
1519
|
+
}
|
|
1520
|
+
uploadFile(data, options = {}) {
|
|
1521
|
+
const settings = this.getSettings();
|
|
1522
|
+
return uploadFile(data, populateOptionsWithSettings(options, settings));
|
|
1523
|
+
}
|
|
1524
|
+
uploadFileGroup(data, options = {}) {
|
|
1525
|
+
const settings = this.getSettings();
|
|
1526
|
+
return uploadFileGroup(data, populateOptionsWithSettings(options, settings));
|
|
1527
|
+
}
|
|
1545
1528
|
}
|
|
1546
1529
|
|
|
1547
|
-
export {
|
|
1530
|
+
export { UploadClient, UploadClientError, UploadcareFile, UploadcareGroup, base, fromUrl, fromUrlStatus, group, groupInfo, info, multipartComplete, multipartStart, multipartUpload, uploadDirect, uploadFile, uploadFileGroup, uploadFromUploaded, uploadFromUrl, uploadMultipart };
|