skapi-js 1.2.14-beta.3 → 1.2.14-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle-report-commonjs.html +2 -2
- package/dist/bundle-report-esm.html +2 -2
- package/dist/bundle-report-node-esm.html +2 -2
- package/dist/bundle-report.html +2 -2
- package/dist/skapi.cjs +1 -1
- package/dist/skapi.cjs.map +1 -1
- package/dist/skapi.js +1 -1
- package/dist/skapi.js.map +1 -1
- package/dist/skapi.mjs +1 -1
- package/dist/skapi.mjs.map +1 -1
- package/dist/skapi.node.mjs +1 -1
- package/dist/skapi.node.mjs.map +1 -1
- package/js/package.json +6 -5
- package/js/src/Types.d.ts +40 -2
- package/js/src/main/skapi.d.ts +41 -29
- package/js/src/main/skapi.js +48 -60
- package/js/src/main/skapi.js.map +1 -1
- package/js/src/methods/admin.d.ts +2 -4
- package/js/src/methods/database.d.ts +8 -0
- package/js/src/methods/database.js +285 -8
- package/js/src/methods/database.js.map +1 -1
- package/js/src/methods/param_restrictions.d.ts +8 -4
- package/js/src/methods/param_restrictions.js +72 -6
- package/js/src/methods/param_restrictions.js.map +1 -1
- package/js/src/methods/request.js +1 -1
- package/js/src/methods/request.js.map +1 -1
- package/js/src/methods/subscription.d.ts +0 -6
- package/js/src/methods/subscription.js +0 -28
- package/js/src/methods/subscription.js.map +1 -1
- package/js/src/methods/vivian.d.ts +18 -3
- package/js/src/methods/vivian.js +20 -10
- package/js/src/methods/vivian.js.map +1 -1
- package/js/src/utils/network.js +16 -11
- package/js/src/utils/network.js.map +1 -1
- package/js/src/utils/utils.d.ts +3 -1
- package/js/src/utils/utils.js +15 -3
- package/js/src/utils/utils.js.map +1 -1
- package/package.json +6 -5
- package/js/Main.d.ts +0 -6
- package/js/Main.js +0 -6
- package/js/Main.js.map +0 -1
- package/js/Types.d.ts +0 -305
- package/js/Types.js +0 -2
- package/js/Types.js.map +0 -1
- package/js/main/error.d.ts +0 -9
- package/js/main/error.js +0 -46
- package/js/main/error.js.map +0 -1
- package/js/main/skapi.d.ts +0 -443
- package/js/main/skapi.js +0 -853
- package/js/main/skapi.js.map +0 -1
- package/js/methods/admin.d.ts +0 -61
- package/js/methods/admin.js +0 -325
- package/js/methods/admin.js.map +0 -1
- package/js/methods/database.d.ts +0 -65
- package/js/methods/database.js +0 -947
- package/js/methods/database.js.map +0 -1
- package/js/methods/notification.d.ts +0 -21
- package/js/methods/notification.js +0 -81
- package/js/methods/notification.js.map +0 -1
- package/js/methods/param_restrictions.d.ts +0 -21
- package/js/methods/param_restrictions.js +0 -144
- package/js/methods/param_restrictions.js.map +0 -1
- package/js/methods/realtime.d.ts +0 -35
- package/js/methods/realtime.js +0 -408
- package/js/methods/realtime.js.map +0 -1
- package/js/methods/request.d.ts +0 -43
- package/js/methods/request.js +0 -132
- package/js/methods/request.js.map +0 -1
- package/js/methods/subscription.d.ts +0 -53
- package/js/methods/subscription.js +0 -337
- package/js/methods/subscription.js.map +0 -1
- package/js/methods/user.d.ts +0 -176
- package/js/methods/user.js +0 -1120
- package/js/methods/user.js.map +0 -1
- package/js/methods/vivian.d.ts +0 -3
- package/js/methods/vivian.js +0 -36
- package/js/methods/vivian.js.map +0 -1
- package/js/methods/webrtc.d.ts +0 -26
- package/js/methods/webrtc.js +0 -608
- package/js/methods/webrtc.js.map +0 -1
- package/js/polyfills/global.d.ts +0 -3
- package/js/polyfills/global.js +0 -235
- package/js/polyfills/global.js.map +0 -1
- package/js/utils/network.d.ts +0 -24
- package/js/utils/network.js +0 -707
- package/js/utils/network.js.map +0 -1
- package/js/utils/utils.d.ts +0 -40
- package/js/utils/utils.js +0 -651
- package/js/utils/utils.js.map +0 -1
- package/js/utils/validator.d.ts +0 -24
- package/js/utils/validator.js +0 -293
- package/js/utils/validator.js.map +0 -1
package/js/utils/network.js
DELETED
|
@@ -1,707 +0,0 @@
|
|
|
1
|
-
import SkapiError from '../main/error';
|
|
2
|
-
import validator from './validator';
|
|
3
|
-
import { MD5, generateRandom, extractFormData } from './utils';
|
|
4
|
-
import { getJwtToken } from '../methods/user';
|
|
5
|
-
import Qpass from "qpass";
|
|
6
|
-
let queue = null;
|
|
7
|
-
const hasSubmitEvent = typeof SubmitEvent !== 'undefined';
|
|
8
|
-
const hasHTMLFormElement = typeof HTMLFormElement !== 'undefined';
|
|
9
|
-
const hasFormData = typeof FormData !== 'undefined';
|
|
10
|
-
let privateCounter_admin = 0;
|
|
11
|
-
let publicCounter_admin = 0;
|
|
12
|
-
let privateCounter_record = 0;
|
|
13
|
-
let publicCounter_record = 0;
|
|
14
|
-
async function getEndpoint(dest, auth) {
|
|
15
|
-
const endpoints = await Promise.all([
|
|
16
|
-
this.admin_endpoint,
|
|
17
|
-
this.record_endpoint
|
|
18
|
-
]);
|
|
19
|
-
const admin = endpoints[0];
|
|
20
|
-
const record = endpoints[1];
|
|
21
|
-
let params = dest.split('?');
|
|
22
|
-
let query = params.length > 1 ? '?' + params[1] : '';
|
|
23
|
-
dest = params[0];
|
|
24
|
-
switch (dest) {
|
|
25
|
-
case 'get-users':
|
|
26
|
-
return admin.get_users_private + dest + query;
|
|
27
|
-
case 'service':
|
|
28
|
-
return admin.service_public + dest + query;
|
|
29
|
-
case 'get-newsletters':
|
|
30
|
-
case 'get-public-newsletters':
|
|
31
|
-
case 'subscribe-newsletter':
|
|
32
|
-
case 'subscribe-public-newsletter':
|
|
33
|
-
case 'signupkey':
|
|
34
|
-
case 'admin-newsletter-request':
|
|
35
|
-
return (auth ? admin.extra_private : admin.extra_public) + dest + query;
|
|
36
|
-
case 'admin-signup':
|
|
37
|
-
case 'confirm-signup':
|
|
38
|
-
case 'client-secret-request':
|
|
39
|
-
case 'client-secret-request-public':
|
|
40
|
-
case 'openid-logger':
|
|
41
|
-
return (auth ? admin.extra_private_2 : admin.extra_public_2) + dest + query;
|
|
42
|
-
case 'block-account':
|
|
43
|
-
case 'admin-edit-profile':
|
|
44
|
-
return admin.admin_private + dest + query;
|
|
45
|
-
case 'remove-account':
|
|
46
|
-
case 'post-secure':
|
|
47
|
-
case 'recover-account':
|
|
48
|
-
case 'mock':
|
|
49
|
-
case 'grant-access':
|
|
50
|
-
case 'last-verified-email':
|
|
51
|
-
case 'ticket':
|
|
52
|
-
case 'register-ticket':
|
|
53
|
-
case 'get-newsletter-subscription':
|
|
54
|
-
case 'request-username-change':
|
|
55
|
-
case 'send-inquiry':
|
|
56
|
-
case 'register-newsletter-group':
|
|
57
|
-
case 'newsletter-group-endpoint':
|
|
58
|
-
case 'invitation-list':
|
|
59
|
-
const gateways_admin = auth
|
|
60
|
-
? [admin.admin_private, admin.admin_private_2]
|
|
61
|
-
: [admin.admin_public, admin.admin_public_2];
|
|
62
|
-
const counter_admin = auth ? privateCounter_admin : publicCounter_admin;
|
|
63
|
-
const selectedGateway_admin = gateways_admin[counter_admin % gateways_admin.length];
|
|
64
|
-
if (auth) {
|
|
65
|
-
privateCounter_admin++;
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
publicCounter_admin++;
|
|
69
|
-
}
|
|
70
|
-
return selectedGateway_admin + dest + query;
|
|
71
|
-
case 'post-record':
|
|
72
|
-
return (auth ? record.post_private : record.post_public) + dest + query;
|
|
73
|
-
case 'get-records':
|
|
74
|
-
return (auth ? record.get_private : record.get_public) + dest + query;
|
|
75
|
-
case 'del-files':
|
|
76
|
-
case 'del-records':
|
|
77
|
-
return record.del_private + dest + query;
|
|
78
|
-
case 'store-subscription':
|
|
79
|
-
case 'get-vapid-public-key':
|
|
80
|
-
case 'push-notification':
|
|
81
|
-
case 'delete-subscription':
|
|
82
|
-
case 'subscription':
|
|
83
|
-
case 'get-subscription':
|
|
84
|
-
case 'get-table':
|
|
85
|
-
case 'get-tag':
|
|
86
|
-
case 'get-uniqueid':
|
|
87
|
-
case 'get-index':
|
|
88
|
-
case 'get-signed-url':
|
|
89
|
-
case 'grant-private-access':
|
|
90
|
-
case 'request-private-access-key':
|
|
91
|
-
case 'get-ws-group':
|
|
92
|
-
case 'check-schema':
|
|
93
|
-
case 'get-feed':
|
|
94
|
-
case 'castspell':
|
|
95
|
-
case 'dopamine':
|
|
96
|
-
case 'getspell':
|
|
97
|
-
const gateways_record = auth
|
|
98
|
-
? [record.record_private, record.record_private_2]
|
|
99
|
-
: [record.record_public, record.record_public_2];
|
|
100
|
-
const counter_record = auth ? privateCounter_record : publicCounter_record;
|
|
101
|
-
const selectedGateway_record = gateways_record[counter_record % gateways_record.length];
|
|
102
|
-
if (auth) {
|
|
103
|
-
privateCounter_record++;
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
publicCounter_record++;
|
|
107
|
-
}
|
|
108
|
-
return selectedGateway_record + dest + query;
|
|
109
|
-
default:
|
|
110
|
-
return validator.Url(dest) + query;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
const __pendingRequest = {};
|
|
114
|
-
export function terminatePendingRequests() {
|
|
115
|
-
if (queue) {
|
|
116
|
-
queue.terminate();
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
export async function request(url, data = null, options, _etc) {
|
|
120
|
-
this.log('request', { url, data, options, _etc: _etc || {} });
|
|
121
|
-
options = options || {};
|
|
122
|
-
let { auth = false, method = 'post', bypassAwaitConnection = false, } = options;
|
|
123
|
-
method = method.toUpperCase();
|
|
124
|
-
let __connection = null;
|
|
125
|
-
let service = data?.service || this.service;
|
|
126
|
-
let owner = data?.owner || this.owner;
|
|
127
|
-
let token = null;
|
|
128
|
-
let endpoint = await getEndpoint.bind(this)(url, !!auth);
|
|
129
|
-
if (!bypassAwaitConnection) {
|
|
130
|
-
__connection = await this.__connection;
|
|
131
|
-
if (!__connection) {
|
|
132
|
-
throw new SkapiError('Invalid connection. The service could have been disabled, or has a restricted CORS.', { code: 'INVALID_REQUEST' });
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (auth) {
|
|
136
|
-
token = await getJwtToken.bind(this)();
|
|
137
|
-
}
|
|
138
|
-
let fetchOptions = {};
|
|
139
|
-
let { fetchMore = false, progress } = options?.fetchOptions || {};
|
|
140
|
-
if (options?.fetchOptions && Object.keys(options.fetchOptions).length) {
|
|
141
|
-
for (let k of ['limit', 'startKey', 'ascending']) {
|
|
142
|
-
if (options.fetchOptions.hasOwnProperty(k)) {
|
|
143
|
-
fetchOptions[k] = options.fetchOptions[k];
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
fetchOptions = validator.Params(fetchOptions, {
|
|
147
|
-
limit: v => {
|
|
148
|
-
if (typeof v !== 'number') {
|
|
149
|
-
throw new SkapiError('Fetch limit should be a number.', { code: 'INVALID_REQUEST' });
|
|
150
|
-
}
|
|
151
|
-
if (v > 1000) {
|
|
152
|
-
throw new SkapiError('Fetch limit should be below 1000.', { code: 'INVALID_REQUEST' });
|
|
153
|
-
}
|
|
154
|
-
return v;
|
|
155
|
-
},
|
|
156
|
-
startKey: v => v,
|
|
157
|
-
ascending: 'boolean'
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
let required = _etc?.ignoreService ? {} : { service, owner };
|
|
161
|
-
Object.assign(required, fetchOptions);
|
|
162
|
-
data = extractFormData(data).data;
|
|
163
|
-
if (!data) {
|
|
164
|
-
data = required;
|
|
165
|
-
}
|
|
166
|
-
else if (data && typeof data === 'object') {
|
|
167
|
-
data = Object.assign(required, data);
|
|
168
|
-
}
|
|
169
|
-
let hashedParams = (() => {
|
|
170
|
-
if (data && typeof data === 'object' && Object.keys(data).length && !(data instanceof FormData)) {
|
|
171
|
-
function sortObject(obj) {
|
|
172
|
-
if (typeof obj === 'object' && obj !== null) {
|
|
173
|
-
return Object.keys(obj)
|
|
174
|
-
.sort()
|
|
175
|
-
.reduce((res, key) => {
|
|
176
|
-
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
177
|
-
res[key] = sortObject(obj[key]);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
res[key] = obj[key];
|
|
181
|
-
}
|
|
182
|
-
return res;
|
|
183
|
-
}, {});
|
|
184
|
-
}
|
|
185
|
-
return obj;
|
|
186
|
-
}
|
|
187
|
-
;
|
|
188
|
-
return MD5.hash(url + '/' + JSON.stringify(sortObject(data)));
|
|
189
|
-
}
|
|
190
|
-
return MD5.hash(url + '/' + this.service);
|
|
191
|
-
})();
|
|
192
|
-
let { requestKey, requestKeyWithStartKey } = load_startKey_keys.bind(this)({
|
|
193
|
-
params: data,
|
|
194
|
-
url,
|
|
195
|
-
fetchMore,
|
|
196
|
-
hashedParams
|
|
197
|
-
});
|
|
198
|
-
if (!requestKey || requestKey && typeof requestKey === 'object') {
|
|
199
|
-
return requestKey;
|
|
200
|
-
}
|
|
201
|
-
this.log('requestKey', requestKeyWithStartKey);
|
|
202
|
-
if (typeof requestKeyWithStartKey === 'string' && __pendingRequest[requestKeyWithStartKey] instanceof Promise) {
|
|
203
|
-
this.log('request:returning pending', requestKeyWithStartKey);
|
|
204
|
-
return __pendingRequest[requestKeyWithStartKey];
|
|
205
|
-
}
|
|
206
|
-
let headers = {
|
|
207
|
-
'Accept': '*/*',
|
|
208
|
-
"Content-Type": options.hasOwnProperty('contentType') ? options.contentType === null ? 'application/x-www-form-urlencoded' : options.contentType || 'application/json' : 'application/json'
|
|
209
|
-
};
|
|
210
|
-
if (token) {
|
|
211
|
-
headers.Authorization = token;
|
|
212
|
-
}
|
|
213
|
-
let meta = {
|
|
214
|
-
public_identifier: this.__public_identifier,
|
|
215
|
-
service,
|
|
216
|
-
owner
|
|
217
|
-
};
|
|
218
|
-
headers['Content-Meta'] = JSON.stringify(meta);
|
|
219
|
-
let opt = { headers };
|
|
220
|
-
if (options?.responseType) {
|
|
221
|
-
opt.responseType = options.responseType;
|
|
222
|
-
}
|
|
223
|
-
if (method === 'GET') {
|
|
224
|
-
if (data) {
|
|
225
|
-
let query = [];
|
|
226
|
-
query = Object.keys(data)
|
|
227
|
-
.map(k => {
|
|
228
|
-
let value = data[k];
|
|
229
|
-
if (typeof value !== 'string') {
|
|
230
|
-
value = JSON.stringify(value);
|
|
231
|
-
}
|
|
232
|
-
return encodeURIComponent(k) + '=' + encodeURIComponent(value);
|
|
233
|
-
});
|
|
234
|
-
if (query.length) {
|
|
235
|
-
if (endpoint.substring(endpoint.length - 1) !== '?') {
|
|
236
|
-
endpoint = endpoint + '?';
|
|
237
|
-
}
|
|
238
|
-
endpoint += query.join('&');
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
opt.body = null;
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
opt.body = data ? JSON.stringify(data) : null;
|
|
245
|
-
}
|
|
246
|
-
opt.method = method;
|
|
247
|
-
if (queue === null) {
|
|
248
|
-
let config = {
|
|
249
|
-
batchSize: this.requestBatchSize,
|
|
250
|
-
breakWhenError: false,
|
|
251
|
-
onProgress: (progress) => {
|
|
252
|
-
this.onBatchProcess.forEach((cb) => cb(progress));
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
queue = new Qpass(config);
|
|
256
|
-
}
|
|
257
|
-
return new Promise((res, rej) => {
|
|
258
|
-
queue.add([async () => {
|
|
259
|
-
let promise = _fetch.bind(this)(endpoint, opt, progress);
|
|
260
|
-
__pendingRequest[requestKeyWithStartKey] = promise;
|
|
261
|
-
try {
|
|
262
|
-
let result = update_startKey_keys.bind(this)({
|
|
263
|
-
hashedParam: requestKey,
|
|
264
|
-
requestKeyWithStartKey,
|
|
265
|
-
url,
|
|
266
|
-
fetched: await promise
|
|
267
|
-
});
|
|
268
|
-
delete __pendingRequest[requestKeyWithStartKey];
|
|
269
|
-
this.log('request:end', result);
|
|
270
|
-
res(result);
|
|
271
|
-
return result;
|
|
272
|
-
}
|
|
273
|
-
catch (err) {
|
|
274
|
-
delete __pendingRequest[requestKeyWithStartKey];
|
|
275
|
-
this.log('request:err', err);
|
|
276
|
-
rej(err);
|
|
277
|
-
throw err;
|
|
278
|
-
}
|
|
279
|
-
}]);
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
function load_startKey_keys(option) {
|
|
283
|
-
let { params = {}, url, fetchMore = false, hashedParams } = option || {};
|
|
284
|
-
if (params.startKey) {
|
|
285
|
-
if (!(typeof params.startKey === 'object' && Object.keys(params.startKey).length) &&
|
|
286
|
-
params.startKey !== 'start' && params.startKey !== 'end') {
|
|
287
|
-
throw new SkapiError(`"${params.startKey}" is invalid startKey key.`, { code: 'INVALID_PARAMETER' });
|
|
288
|
-
}
|
|
289
|
-
if (params.startKey === 'start') {
|
|
290
|
-
fetchMore = false;
|
|
291
|
-
delete params.startKey;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
if (!fetchMore) {
|
|
295
|
-
if (this.__cached_requests?.[url]?.[hashedParams]) {
|
|
296
|
-
delete this.__cached_requests[url][hashedParams];
|
|
297
|
-
}
|
|
298
|
-
if (this.__startKeyHistory?.[url]?.[hashedParams]) {
|
|
299
|
-
if (Array.isArray(this.__startKeyHistory[url][hashedParams]) && this.__startKeyHistory[url][hashedParams].length) {
|
|
300
|
-
for (let p of this.__startKeyHistory[url][hashedParams]) {
|
|
301
|
-
let hashedParams_cached = hashedParams + MD5.hash(p);
|
|
302
|
-
if (this.__cached_requests?.[url] && this.__cached_requests?.[url]?.[hashedParams_cached]) {
|
|
303
|
-
delete this.__cached_requests[url][hashedParams_cached];
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
delete this.__startKeyHistory[url][hashedParams];
|
|
308
|
-
}
|
|
309
|
-
return { requestKeyWithStartKey: hashedParams, requestKey: hashedParams };
|
|
310
|
-
}
|
|
311
|
-
if (!Array.isArray(this.__startKeyHistory?.[url]?.[hashedParams])) {
|
|
312
|
-
return { requestKeyWithStartKey: hashedParams, requestKey: hashedParams };
|
|
313
|
-
}
|
|
314
|
-
let list_of_startKeys = this.__startKeyHistory[url][hashedParams];
|
|
315
|
-
let last_startKey_key = list_of_startKeys[list_of_startKeys.length - 1];
|
|
316
|
-
let requestKeyWithStartKey = hashedParams;
|
|
317
|
-
if (last_startKey_key) {
|
|
318
|
-
if (last_startKey_key === 'end') {
|
|
319
|
-
return {
|
|
320
|
-
requestKey: {
|
|
321
|
-
list: [],
|
|
322
|
-
startKey: 'end',
|
|
323
|
-
endOfList: true,
|
|
324
|
-
startKeyHistory: list_of_startKeys
|
|
325
|
-
},
|
|
326
|
-
requestKeyWithStartKey
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
requestKeyWithStartKey += MD5.hash(last_startKey_key);
|
|
330
|
-
params.startKey = JSON.parse(last_startKey_key);
|
|
331
|
-
}
|
|
332
|
-
if (this.__cached_requests?.[url]?.[requestKeyWithStartKey]) {
|
|
333
|
-
return { requestKey: this.__cached_requests[url][requestKeyWithStartKey], requestKeyWithStartKey };
|
|
334
|
-
}
|
|
335
|
-
return { requestKeyWithStartKey, requestKey: hashedParams };
|
|
336
|
-
}
|
|
337
|
-
function _fetch(url, opt, progress) {
|
|
338
|
-
return new Promise((res, rej) => {
|
|
339
|
-
let xhr = new XMLHttpRequest();
|
|
340
|
-
xhr.open(opt.method || 'GET', url);
|
|
341
|
-
for (var k in opt.headers || {}) {
|
|
342
|
-
xhr.setRequestHeader(k, opt.headers[k]);
|
|
343
|
-
}
|
|
344
|
-
if (opt.responseType) {
|
|
345
|
-
xhr.responseType = opt.responseType;
|
|
346
|
-
}
|
|
347
|
-
xhr.onload = () => {
|
|
348
|
-
if (xhr.status < 400) {
|
|
349
|
-
if (opt.responseType == 'json' || opt.responseType == 'blob') {
|
|
350
|
-
res(xhr.response);
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
let result = xhr.responseText;
|
|
354
|
-
try {
|
|
355
|
-
result = JSON.parse(result);
|
|
356
|
-
}
|
|
357
|
-
catch (err) { }
|
|
358
|
-
res(result);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
else if (xhr.status === 429) {
|
|
362
|
-
let retryAfter = xhr.getResponseHeader('Retry-After');
|
|
363
|
-
if (retryAfter) {
|
|
364
|
-
setTimeout(() => {
|
|
365
|
-
_fetch(url, opt, progress).then(res, rej);
|
|
366
|
-
}, parseInt(retryAfter) * 1000);
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
rej('Too many requests');
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else {
|
|
373
|
-
let status = xhr.status;
|
|
374
|
-
let errCode = [
|
|
375
|
-
'INVALID_CORS',
|
|
376
|
-
'INVALID_REQUEST',
|
|
377
|
-
'SERVICE_DISABLED',
|
|
378
|
-
'INVALID_PARAMETER',
|
|
379
|
-
'ERROR',
|
|
380
|
-
'EXISTS',
|
|
381
|
-
'NOT_EXISTS'
|
|
382
|
-
];
|
|
383
|
-
let result = opt.responseType == 'blob' ? xhr.response : xhr.responseText;
|
|
384
|
-
try {
|
|
385
|
-
result = JSON.parse(result);
|
|
386
|
-
}
|
|
387
|
-
catch (err) { }
|
|
388
|
-
if (typeof result === 'string') {
|
|
389
|
-
let errMsg = result.split(':');
|
|
390
|
-
let code = errMsg.splice(0, 1)[0].trim();
|
|
391
|
-
let msg = errMsg.join(':').trim();
|
|
392
|
-
rej(new SkapiError(msg, { code: (errCode.includes(code) ? code : 'ERROR') }));
|
|
393
|
-
}
|
|
394
|
-
else if (typeof result === 'object' && result?.message) {
|
|
395
|
-
let code = (result?.code || (status ? status.toString() : null) || 'ERROR');
|
|
396
|
-
let message = result.message;
|
|
397
|
-
let cause = result?.cause;
|
|
398
|
-
if (typeof message === 'string') {
|
|
399
|
-
message = message.trim();
|
|
400
|
-
}
|
|
401
|
-
rej(new SkapiError(message, { cause, code }));
|
|
402
|
-
}
|
|
403
|
-
else {
|
|
404
|
-
rej(result);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
xhr.onerror = () => rej('Network error');
|
|
409
|
-
xhr.onabort = () => rej('Aborted');
|
|
410
|
-
xhr.ontimeout = () => rej('Timeout');
|
|
411
|
-
if (typeof progress === 'function') {
|
|
412
|
-
xhr.onprogress = (p) => {
|
|
413
|
-
progress({
|
|
414
|
-
status: 'download',
|
|
415
|
-
progress: p.loaded / p.total * 100,
|
|
416
|
-
loaded: p.loaded,
|
|
417
|
-
total: p.total,
|
|
418
|
-
abort: () => xhr.abort()
|
|
419
|
-
});
|
|
420
|
-
};
|
|
421
|
-
if (xhr.upload) {
|
|
422
|
-
xhr.upload.onprogress = (p) => {
|
|
423
|
-
progress({
|
|
424
|
-
status: 'upload',
|
|
425
|
-
progress: p.loaded / p.total * 100,
|
|
426
|
-
loaded: p.loaded,
|
|
427
|
-
total: p.total,
|
|
428
|
-
abort: () => xhr.abort()
|
|
429
|
-
});
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
xhr.send(opt.body);
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
function update_startKey_keys(option) {
|
|
437
|
-
let { hashedParam, requestKeyWithStartKey, url, fetched } = option;
|
|
438
|
-
if (!fetched?.startKey) {
|
|
439
|
-
return fetched;
|
|
440
|
-
}
|
|
441
|
-
if (!this.__startKeyHistory.hasOwnProperty(url)) {
|
|
442
|
-
this.__startKeyHistory[url] = {};
|
|
443
|
-
}
|
|
444
|
-
if (!this.__startKeyHistory[url].hasOwnProperty(hashedParam)) {
|
|
445
|
-
this.__startKeyHistory[url][hashedParam] = [];
|
|
446
|
-
}
|
|
447
|
-
let startKey_string = fetched.startKey === 'end' ? 'end' : JSON.stringify(fetched.startKey);
|
|
448
|
-
if (!this.__startKeyHistory[url][hashedParam].includes(startKey_string)) {
|
|
449
|
-
this.__startKeyHistory[url][hashedParam].push(startKey_string);
|
|
450
|
-
}
|
|
451
|
-
if (!this.__cached_requests?.[url]) {
|
|
452
|
-
this.__cached_requests[url] = {};
|
|
453
|
-
}
|
|
454
|
-
this.__cached_requests[url][requestKeyWithStartKey] = fetched;
|
|
455
|
-
return Object.assign({ startKeyHistory: this.__startKeyHistory[url][hashedParam] }, fetched);
|
|
456
|
-
}
|
|
457
|
-
export async function uploadFiles(fileList, params) {
|
|
458
|
-
await this.__connection;
|
|
459
|
-
let { record_id, service = this.service, progress } = params;
|
|
460
|
-
if (!record_id) {
|
|
461
|
-
throw new SkapiError('"record_id" is required.', { code: 'INVALID_PARAMETER' });
|
|
462
|
-
}
|
|
463
|
-
if (hasSubmitEvent && fileList instanceof SubmitEvent) {
|
|
464
|
-
fileList = fileList.target;
|
|
465
|
-
}
|
|
466
|
-
if (hasHTMLFormElement && fileList instanceof HTMLFormElement) {
|
|
467
|
-
fileList = new FormData(fileList);
|
|
468
|
-
}
|
|
469
|
-
if (!hasFormData || !(fileList instanceof FormData)) {
|
|
470
|
-
throw new SkapiError('"fileList" should be a FormData or HTMLFormElement.', { code: 'INVALID_PARAMETER' });
|
|
471
|
-
}
|
|
472
|
-
let reserved_key = generateRandom();
|
|
473
|
-
let getSignedParams = {
|
|
474
|
-
reserved_key,
|
|
475
|
-
service,
|
|
476
|
-
request: 'post'
|
|
477
|
-
};
|
|
478
|
-
if (params?.record_id) {
|
|
479
|
-
getSignedParams.id = params.record_id;
|
|
480
|
-
}
|
|
481
|
-
let xhr;
|
|
482
|
-
let fetchProgress = (url, body, progressCallback) => {
|
|
483
|
-
return new Promise((res, rej) => {
|
|
484
|
-
xhr = new XMLHttpRequest();
|
|
485
|
-
xhr.open('POST', url);
|
|
486
|
-
xhr.onload = () => {
|
|
487
|
-
let result = xhr.responseText;
|
|
488
|
-
try {
|
|
489
|
-
result = JSON.parse(result);
|
|
490
|
-
}
|
|
491
|
-
catch (err) { }
|
|
492
|
-
if (xhr.status >= 200 && xhr.status < 300) {
|
|
493
|
-
res(result);
|
|
494
|
-
}
|
|
495
|
-
else if (xhr.status === 429) {
|
|
496
|
-
let retryAfter = xhr.getResponseHeader('Retry-After');
|
|
497
|
-
if (retryAfter) {
|
|
498
|
-
setTimeout(() => {
|
|
499
|
-
fetchProgress(url, body, progressCallback).then(res, rej);
|
|
500
|
-
}, parseInt(retryAfter) * 1000);
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
rej('Too many requests');
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
else {
|
|
507
|
-
rej(result);
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
xhr.onerror = () => rej('Network error');
|
|
511
|
-
xhr.onabort = () => rej('Aborted');
|
|
512
|
-
xhr.ontimeout = () => rej('Timeout');
|
|
513
|
-
if (xhr.upload && typeof progressCallback === 'function') {
|
|
514
|
-
xhr.upload.onprogress = progressCallback;
|
|
515
|
-
}
|
|
516
|
-
xhr.send(body);
|
|
517
|
-
});
|
|
518
|
-
};
|
|
519
|
-
function toBase62(num) {
|
|
520
|
-
const base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
521
|
-
if (num === 0)
|
|
522
|
-
return base62Chars[0];
|
|
523
|
-
let result = '';
|
|
524
|
-
while (num > 0) {
|
|
525
|
-
result = base62Chars[num % 62] + result;
|
|
526
|
-
num = Math.floor(num / 62);
|
|
527
|
-
}
|
|
528
|
-
return result;
|
|
529
|
-
}
|
|
530
|
-
if (queue === null) {
|
|
531
|
-
queue = new Qpass({
|
|
532
|
-
batchSize: this.requestBatchSize,
|
|
533
|
-
breakWhenError: false
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
return new Promise((res, rej) => {
|
|
537
|
-
queue.add([async () => {
|
|
538
|
-
let completed = [];
|
|
539
|
-
let failed = [];
|
|
540
|
-
let bin_endpoints = [];
|
|
541
|
-
for (let [key, f] of fileList.entries()) {
|
|
542
|
-
if (!(f instanceof File)) {
|
|
543
|
-
continue;
|
|
544
|
-
}
|
|
545
|
-
let signedParams = Object.assign({
|
|
546
|
-
key: key + '/' + f.name,
|
|
547
|
-
sizeKey: toBase62(f.size),
|
|
548
|
-
contentType: f.type || null
|
|
549
|
-
}, getSignedParams);
|
|
550
|
-
let { fields = null, url, cdn } = await request.bind(this)('get-signed-url', signedParams, { auth: !!this.__user });
|
|
551
|
-
bin_endpoints.push(cdn);
|
|
552
|
-
let form = new FormData();
|
|
553
|
-
for (let name in fields) {
|
|
554
|
-
form.append(name, fields[name]);
|
|
555
|
-
}
|
|
556
|
-
form.append('file', f);
|
|
557
|
-
try {
|
|
558
|
-
await fetchProgress(url, form, typeof progress === 'function' ? (p) => progress({
|
|
559
|
-
status: 'upload',
|
|
560
|
-
progress: p.loaded / p.total * 100,
|
|
561
|
-
currentFile: f,
|
|
562
|
-
completed,
|
|
563
|
-
failed,
|
|
564
|
-
loaded: p.loaded,
|
|
565
|
-
total: p.total,
|
|
566
|
-
abort: () => xhr.abort()
|
|
567
|
-
}) : null);
|
|
568
|
-
completed.push(f);
|
|
569
|
-
}
|
|
570
|
-
catch (err) {
|
|
571
|
-
failed.push(f);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
res({ completed, failed, bin_endpoints });
|
|
575
|
-
return { completed, failed, bin_endpoints };
|
|
576
|
-
}]);
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
const pendPromise = {};
|
|
580
|
-
export function formHandler(options) {
|
|
581
|
-
let { preventMultipleCalls = false } = options || {};
|
|
582
|
-
return function (target, propertyKey, descriptor) {
|
|
583
|
-
const fn = descriptor.value;
|
|
584
|
-
descriptor.value = function (...arg) {
|
|
585
|
-
let form = arg[0];
|
|
586
|
-
let storeResponseKey = true;
|
|
587
|
-
let formEl = null;
|
|
588
|
-
let actionDestination = '';
|
|
589
|
-
let fileBase64String = {};
|
|
590
|
-
let refreshPage = false;
|
|
591
|
-
if (hasSubmitEvent && form instanceof SubmitEvent) {
|
|
592
|
-
form.preventDefault();
|
|
593
|
-
let currentUrl = window.location.href;
|
|
594
|
-
formEl = form.target;
|
|
595
|
-
let href = new URL(formEl.action);
|
|
596
|
-
actionDestination = href.href;
|
|
597
|
-
let placeholders = actionDestination ? actionDestination.match(/(?<=\{).*?(?=\})/g) : '';
|
|
598
|
-
if (placeholders) {
|
|
599
|
-
for (let p of placeholders) {
|
|
600
|
-
if (!p) {
|
|
601
|
-
continue;
|
|
602
|
-
}
|
|
603
|
-
let inputElement = formEl.querySelector(`[name="${p}"]`);
|
|
604
|
-
if (!inputElement) {
|
|
605
|
-
continue;
|
|
606
|
-
}
|
|
607
|
-
if (inputElement.type === 'file') {
|
|
608
|
-
for (let i = 0; i <= inputElement.files.length - 1; i++) {
|
|
609
|
-
if (!inputElement.files[i])
|
|
610
|
-
continue;
|
|
611
|
-
if (!fileBase64String[p]) {
|
|
612
|
-
fileBase64String[p] = [];
|
|
613
|
-
}
|
|
614
|
-
fileBase64String[p].push(new Promise((res, rej) => {
|
|
615
|
-
let reader = new FileReader();
|
|
616
|
-
reader.onload = function () {
|
|
617
|
-
res(reader.result);
|
|
618
|
-
};
|
|
619
|
-
reader.readAsDataURL(inputElement.files[i]);
|
|
620
|
-
reader.onerror = rej;
|
|
621
|
-
}));
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
else {
|
|
625
|
-
actionDestination = actionDestination.replace(`{${p}}`, inputElement.value);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
if (formEl.getAttribute('action') === null) {
|
|
630
|
-
storeResponseKey = false;
|
|
631
|
-
}
|
|
632
|
-
else {
|
|
633
|
-
refreshPage = href.href === currentUrl;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
const handleResponse = async (response) => {
|
|
637
|
-
if (actionDestination) {
|
|
638
|
-
for (let k in fileBase64String) {
|
|
639
|
-
if (fileBase64String[k].length) {
|
|
640
|
-
actionDestination = actionDestination.replace(`{${k}}`, (await Promise.all(fileBase64String[k])).join(','));
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
if (formEl) {
|
|
645
|
-
if (storeResponseKey) {
|
|
646
|
-
window.sessionStorage.setItem(`${this.service}:${MD5.hash(actionDestination)}`, JSON.stringify(response));
|
|
647
|
-
if (refreshPage) {
|
|
648
|
-
window.location.replace(actionDestination);
|
|
649
|
-
}
|
|
650
|
-
else {
|
|
651
|
-
window.location.href = actionDestination;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
return response;
|
|
656
|
-
};
|
|
657
|
-
let response;
|
|
658
|
-
let handleError = (err) => {
|
|
659
|
-
if (err instanceof SkapiError) {
|
|
660
|
-
err.name = propertyKey + '()';
|
|
661
|
-
}
|
|
662
|
-
else {
|
|
663
|
-
err = err instanceof Error ? err : new SkapiError(err, { name: propertyKey + '()' });
|
|
664
|
-
}
|
|
665
|
-
throw err;
|
|
666
|
-
};
|
|
667
|
-
const executeMethod = async () => {
|
|
668
|
-
try {
|
|
669
|
-
response = fn.bind(this)(...arg);
|
|
670
|
-
if (response instanceof Promise) {
|
|
671
|
-
let resolved = await response;
|
|
672
|
-
await handleResponse(resolved);
|
|
673
|
-
return response;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
catch (err) {
|
|
677
|
-
throw handleError(err);
|
|
678
|
-
}
|
|
679
|
-
};
|
|
680
|
-
if (preventMultipleCalls) {
|
|
681
|
-
if (!pendPromise?.[propertyKey]) {
|
|
682
|
-
pendPromise[propertyKey] = executeMethod().finally(() => {
|
|
683
|
-
delete pendPromise[propertyKey];
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
return pendPromise[propertyKey];
|
|
687
|
-
}
|
|
688
|
-
return executeMethod();
|
|
689
|
-
};
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
export async function getFormResponse() {
|
|
693
|
-
await this.__connection;
|
|
694
|
-
let responseKey = `${this.service}:${MD5.hash(window.location.href.split('?')[0])}`;
|
|
695
|
-
let stored = window.sessionStorage.getItem(responseKey);
|
|
696
|
-
window.sessionStorage.removeItem(responseKey);
|
|
697
|
-
if (stored !== null) {
|
|
698
|
-
try {
|
|
699
|
-
stored = JSON.parse(stored);
|
|
700
|
-
}
|
|
701
|
-
catch (err) { }
|
|
702
|
-
return stored;
|
|
703
|
-
}
|
|
704
|
-
return null;
|
|
705
|
-
}
|
|
706
|
-
;
|
|
707
|
-
//# sourceMappingURL=network.js.map
|