@optionfactory/ful 0.79.0 → 0.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ful.css +1 -1
- package/dist/ful.css.map +1 -1
- package/dist/ful.iife.js +398 -123
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +398 -118
- package/dist/ful.mjs.map +1 -1
- package/package.json +4 -4
package/dist/ful.iife.js
CHANGED
|
@@ -73,171 +73,451 @@ var ful = (function (exports) {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
class
|
|
77
|
-
constructor() {
|
|
78
|
-
|
|
79
|
-
this.
|
|
76
|
+
class Failure extends Error {
|
|
77
|
+
constructor(name, problems, cause) {
|
|
78
|
+
super(JSON.stringify(problems), { cause });
|
|
79
|
+
this.name = name;
|
|
80
|
+
this.problems = problems;
|
|
80
81
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class HttpClientError extends Failure {
|
|
85
|
+
constructor(status, problems, cause) {
|
|
86
|
+
super(`HttpClientError:${status}`, problems, cause);
|
|
87
|
+
this.status = status;
|
|
88
|
+
}
|
|
89
|
+
static of(type, cause) {
|
|
90
|
+
return new HttpClientError(0, [{
|
|
91
|
+
type,
|
|
92
|
+
context: null,
|
|
93
|
+
reason: cause.message,
|
|
94
|
+
details: null
|
|
95
|
+
}], cause);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Creates an HttpClientError from a Response.
|
|
99
|
+
* @param {Response} response
|
|
100
|
+
* @returns an HttpClientError
|
|
101
|
+
*/
|
|
102
|
+
static async fromResponse(response) {
|
|
103
|
+
const text = await response.text();
|
|
104
|
+
const def = [{
|
|
105
|
+
type: "GENERIC_PROBLEM",
|
|
106
|
+
context: null,
|
|
107
|
+
reason: `${response.status} ${response.statusText}: ${text}`,
|
|
108
|
+
details: null
|
|
109
|
+
}];
|
|
110
|
+
try {
|
|
111
|
+
return new HttpClientError(response.status, text ? JSON.parse(text) : def);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return new HttpClientError(response.status, def);
|
|
114
|
+
}
|
|
85
115
|
}
|
|
86
116
|
}
|
|
87
117
|
|
|
88
118
|
class CsrfTokenInterceptor {
|
|
119
|
+
#k; #v;
|
|
89
120
|
constructor() {
|
|
90
|
-
this
|
|
91
|
-
this
|
|
121
|
+
this.#k = document.querySelector("meta[name='_csrf_header']").getAttribute("content");
|
|
122
|
+
this.#v = document.querySelector("meta[name='_csrf']").getAttribute("content");
|
|
92
123
|
}
|
|
93
|
-
async intercept(request, chain){
|
|
94
|
-
|
|
95
|
-
headers.set(this.k, this.v);
|
|
96
|
-
request.options.headers = headers;
|
|
124
|
+
async intercept(request, chain) {
|
|
125
|
+
request.headers.set(this.#k, this.#v);
|
|
97
126
|
return await chain.proceed(request);
|
|
98
127
|
}
|
|
99
128
|
}
|
|
100
129
|
|
|
101
130
|
class RedirectOnUnauthorizedInterceptor {
|
|
131
|
+
#redirectUri;
|
|
102
132
|
constructor(redirectUri) {
|
|
103
|
-
this
|
|
133
|
+
this.#redirectUri = redirectUri;
|
|
104
134
|
}
|
|
105
|
-
async intercept(request, chain){
|
|
106
|
-
const response =
|
|
135
|
+
async intercept(request, chain) {
|
|
136
|
+
const response = await chain.proceed(request);
|
|
107
137
|
if (response.status !== 401) {
|
|
108
138
|
return response;
|
|
109
139
|
}
|
|
110
|
-
window.location.href = this
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
class Failure extends Error {
|
|
115
|
-
static parseProblems(status, text) {
|
|
116
|
-
const def = [{
|
|
117
|
-
type: "GENERIC_PROBLEM",
|
|
118
|
-
context: null,
|
|
119
|
-
reason: `${status}: ${text}`,
|
|
120
|
-
details: null
|
|
121
|
-
}];
|
|
122
|
-
try {
|
|
123
|
-
return text ? JSON.parse(text) : def;
|
|
124
|
-
} catch (e) {
|
|
125
|
-
return def;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
static fromResponse(status, text) {
|
|
129
|
-
return new Failure(status, Failure.parseProblems(status, text));
|
|
130
|
-
}
|
|
131
|
-
constructor(status, problems) {
|
|
132
|
-
super(JSON.stringify(problems));
|
|
133
|
-
this.name = `Failure:${status}`;
|
|
134
|
-
this.status = status;
|
|
135
|
-
this.problems = problems;
|
|
140
|
+
window.location.href = this.#redirectUri;
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
class HttpClientBuilder {
|
|
145
|
+
#interceptors;
|
|
140
146
|
constructor() {
|
|
141
|
-
this
|
|
142
|
-
}
|
|
143
|
-
withContext() {
|
|
144
|
-
this.interceptors.push(new ContextInterceptor());
|
|
145
|
-
return this;
|
|
147
|
+
this.#interceptors = [];
|
|
146
148
|
}
|
|
147
149
|
withCsrfToken() {
|
|
148
|
-
this
|
|
150
|
+
this.#interceptors.push(new CsrfTokenInterceptor());
|
|
149
151
|
return this;
|
|
150
152
|
}
|
|
151
153
|
withRedirectOnUnauthorized(redirectUri) {
|
|
152
|
-
this
|
|
154
|
+
this.#interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));
|
|
153
155
|
return this;
|
|
154
156
|
}
|
|
155
157
|
withInterceptors(...interceptors) {
|
|
156
|
-
this
|
|
158
|
+
this.#interceptors.push(...interceptors);
|
|
157
159
|
return this;
|
|
158
160
|
}
|
|
159
161
|
build() {
|
|
160
|
-
|
|
161
|
-
return new HttpClient({interceptors});
|
|
162
|
+
return new HttpClient(this.#interceptors);
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
class HttpCall {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
/**
|
|
168
|
+
*
|
|
169
|
+
* @async
|
|
170
|
+
* @param {Request} request
|
|
171
|
+
* @param {HttpInterceptorChain} chain
|
|
172
|
+
* @returns {Promise<Response>} the response
|
|
173
|
+
*/
|
|
174
|
+
async intercept(request, chain) {
|
|
175
|
+
return await fetch(request);
|
|
176
|
+
}
|
|
169
177
|
}
|
|
170
178
|
|
|
171
179
|
class HttpInterceptorChain {
|
|
172
|
-
constructor(interceptors, current){
|
|
180
|
+
constructor(interceptors, current) {
|
|
173
181
|
this.interceptors = interceptors;
|
|
174
182
|
this.current = current;
|
|
175
183
|
}
|
|
176
|
-
async proceed(request){
|
|
184
|
+
async proceed(request) {
|
|
177
185
|
const interceptor = this.interceptors[this.current];
|
|
178
186
|
return await interceptor.intercept(request, new HttpInterceptorChain(this.interceptors, this.current + 1));
|
|
179
187
|
}
|
|
180
188
|
}
|
|
181
189
|
|
|
182
|
-
|
|
183
190
|
class HttpClient {
|
|
191
|
+
#interceptors;
|
|
192
|
+
/**
|
|
193
|
+
* Creates a builder for an HttpClient.
|
|
194
|
+
* @returns {HttpRequestBuilder} the client builder
|
|
195
|
+
*/
|
|
184
196
|
static builder() {
|
|
185
197
|
return new HttpClientBuilder();
|
|
186
198
|
}
|
|
187
|
-
|
|
188
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Creates an HttpClient.
|
|
201
|
+
* @returns {[HttpInterceptor]} interceptors - a list of interceptors to be registered for every request performed by the created client.
|
|
202
|
+
*/
|
|
203
|
+
constructor(interceptors) {
|
|
204
|
+
this.#interceptors = interceptors || [];
|
|
189
205
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Performs an HTTP exchange.
|
|
208
|
+
* @async
|
|
209
|
+
* @param {string} uri - the (possibly relative) request url
|
|
210
|
+
* @param {RequestInit|undefined} options - fetch options
|
|
211
|
+
* @param {[any]|undefined} interceptors - the HttpInterceptors to be registered for this request.
|
|
212
|
+
* @returns {Promise<Response>} the response
|
|
213
|
+
*/
|
|
214
|
+
async exchange(uri, options, interceptors) {
|
|
215
|
+
const is = [...this.#interceptors, ...interceptors || [], new HttpCall()];
|
|
216
|
+
const chain = new HttpInterceptorChain(is, 0);
|
|
217
|
+
return await chain.proceed(new Request(uri, options));
|
|
195
218
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
219
|
+
/**
|
|
220
|
+
* Creates a request builder.
|
|
221
|
+
* @param {string} method - the HTTP method to be used
|
|
222
|
+
* @param {string} uri - the (possibly relative) request url
|
|
223
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
224
|
+
*/
|
|
225
|
+
request(method, uri) {
|
|
226
|
+
return HttpRequestBuilder.create(this, method, uri);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Creates a request builder.
|
|
230
|
+
* @param {string} uri - the (possibly relative) request url
|
|
231
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
232
|
+
*/
|
|
233
|
+
get(uri) {
|
|
234
|
+
return HttpRequestBuilder.create(this, 'GET', uri);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Creates a request builder.
|
|
238
|
+
* @param {string} uri - the (possibly relative) request url
|
|
239
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
240
|
+
*/
|
|
241
|
+
head(uri) {
|
|
242
|
+
return HttpRequestBuilder.create(this, 'HEAD', uri);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Creates a request builder.
|
|
246
|
+
* @param {string} uri - the (possibly relative) request url
|
|
247
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
248
|
+
*/
|
|
249
|
+
post(uri) {
|
|
250
|
+
return HttpRequestBuilder.create(this, 'POST', uri);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Creates a request builder.
|
|
254
|
+
* @param {string} uri - the (possibly relative) request url
|
|
255
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
256
|
+
*/
|
|
257
|
+
put(uri) {
|
|
258
|
+
return HttpRequestBuilder.create(this, 'PUT', uri);
|
|
203
259
|
}
|
|
204
|
-
|
|
260
|
+
/**
|
|
261
|
+
* Creates a request builder.
|
|
262
|
+
* @param {string} uri - the (possibly relative) request url
|
|
263
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
264
|
+
*/
|
|
265
|
+
patch(uri) {
|
|
266
|
+
return HttpRequestBuilder.create(this, 'PATCH', uri);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Creates a request builder.
|
|
270
|
+
* @param {string} uri - the (possibly relative) request url
|
|
271
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
272
|
+
*/
|
|
273
|
+
delete(uri) {
|
|
274
|
+
return HttpRequestBuilder.create(this, 'DELETE', uri);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
const unmarshal = async (response, type) => {
|
|
280
|
+
try {
|
|
281
|
+
return await response[type]();
|
|
282
|
+
} catch (e) {
|
|
283
|
+
throw HttpClientError.of("UNMARSHALING_PROBLEM", e);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class HttpRequestBuilder {
|
|
289
|
+
#client;
|
|
290
|
+
#method;
|
|
291
|
+
#uri;
|
|
292
|
+
#params;
|
|
293
|
+
#headers;
|
|
294
|
+
#body;
|
|
295
|
+
#options;
|
|
296
|
+
#interceptors;
|
|
297
|
+
/**
|
|
298
|
+
* Creates an HttpRequestBuilder.
|
|
299
|
+
* @param {HttpClient} client
|
|
300
|
+
* @param {string} method - the HTTP method to be used
|
|
301
|
+
* @param {string} uri - the (possibly relative) request url
|
|
302
|
+
* @returns {HttpRequestBuilder} the builder
|
|
303
|
+
*/
|
|
304
|
+
static create(client, method, uri) {
|
|
305
|
+
return new HttpRequestBuilder(
|
|
306
|
+
client,
|
|
307
|
+
method,
|
|
308
|
+
uri,
|
|
309
|
+
new URLSearchParams(),
|
|
310
|
+
new Headers(),
|
|
311
|
+
undefined,
|
|
312
|
+
{},
|
|
313
|
+
[]
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Creates an HttpRequestBuilder.
|
|
318
|
+
* @param {HttpClient} client
|
|
319
|
+
* @param {string} method - the HTTP method to be used
|
|
320
|
+
* @param {string} uri - the (possibly relative) request url
|
|
321
|
+
* @param {URLSearchParams} params
|
|
322
|
+
* @param {Headers} headers
|
|
323
|
+
* @param {any} body
|
|
324
|
+
* @param {Omit<RequestInit,"headers"|"method"|"body">} options
|
|
325
|
+
* @param {[HttpInterceptor]} interceptors
|
|
326
|
+
*/
|
|
327
|
+
constructor(client, method, uri, params, headers, body, options, interceptors) {
|
|
328
|
+
this.#client = client;
|
|
329
|
+
this.#method = method;
|
|
330
|
+
this.#uri = uri;
|
|
331
|
+
this.#params = params;
|
|
332
|
+
this.#body = body;
|
|
333
|
+
this.#headers = headers;
|
|
334
|
+
this.#options = options;
|
|
335
|
+
this.#interceptors = interceptors;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Add all passed headers to the request, overriding existing ones if that key already exists.
|
|
339
|
+
* @param {headersInit} hs
|
|
340
|
+
* @returns {HttpRequestBuilder} this builder
|
|
341
|
+
*/
|
|
342
|
+
headers(hs) {
|
|
343
|
+
for (const [k, v] of new Headers(hs).entries()) {
|
|
344
|
+
this.#headers.set(k, v);
|
|
345
|
+
}
|
|
346
|
+
return this;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Adds an header to the request, overriding it if it already exists.
|
|
350
|
+
* @param {string} k
|
|
351
|
+
* @param {string} v
|
|
352
|
+
* @returns {HttpRequestBuilder} this builder
|
|
353
|
+
*/
|
|
354
|
+
header(k, v) {
|
|
355
|
+
this.#headers.set(k, v);
|
|
356
|
+
return this;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Add all query parameters to the request, overriding existing ones if that key already exists.
|
|
360
|
+
* @param {URLSearchParams|Record<string,string>|string[][]|string} ps
|
|
361
|
+
* @returns {HttpRequestBuilder} this builder
|
|
362
|
+
*/
|
|
363
|
+
params(ps) {
|
|
364
|
+
for (const [k, v] of new URLSearchParams(ps).entries()) {
|
|
365
|
+
this.#params.set(k, v);
|
|
366
|
+
}
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Adds a query parameter to the request, overriding it if it already exists.
|
|
371
|
+
* @param {string} k
|
|
372
|
+
* @param {string} v
|
|
373
|
+
* @returns {HttpRequestBuilder} this builder
|
|
374
|
+
*/
|
|
375
|
+
param(k, v) {
|
|
376
|
+
this.#params.set(k, v);
|
|
377
|
+
return this;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Sets the request body.
|
|
381
|
+
* `Content-Type: multipart/form-data` header is automatically added by fetch when data is a FormData instance if not explicitly set.
|
|
382
|
+
* `Content-Type: application/x-www-form-urlencoded` header is automatically added by fetch when data is an URLSearchParams instance if not explicitly set.
|
|
383
|
+
* `Content-Type: text/plain` header is automatically added by fetch when data is a string instance if not explicitly set.
|
|
384
|
+
* @param {string|ArrayBuffer|Blob|DataView|File|FormData|TypedArray|URLSearchParams|ReadableStream} data
|
|
385
|
+
* @returns {HttpRequestBuilder} this builder
|
|
386
|
+
*/
|
|
387
|
+
body(data) {
|
|
388
|
+
this.#body = data;
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Sets the request body that will be serialized as json. Calling this method adds the `Content-Type application/json` header for the request.
|
|
393
|
+
* @param {any} body - the body to be serialized as json
|
|
394
|
+
* @returns {HttpRequestBuilder} this builder
|
|
395
|
+
*/
|
|
396
|
+
json(body) {
|
|
397
|
+
this.#headers.set("Content-Type", "application/json");
|
|
398
|
+
this.#body = JSON.stringify(body);
|
|
399
|
+
return this;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Sets a fetch options for the request.
|
|
403
|
+
* @param {Omit<RequestInit,"headers"|"method"|"body">} kvs
|
|
404
|
+
* @returns {HttpRequestBuilder} this builder
|
|
405
|
+
*/
|
|
406
|
+
options(kvs) {
|
|
407
|
+
for (const [k, v] of Object.entries(kvs)) {
|
|
408
|
+
this.#options[k] = v;
|
|
409
|
+
}
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Sets a fetch option for the request.
|
|
414
|
+
* @param {keyof Omit<RequestInit,"headers"|"method"|"body">} k
|
|
415
|
+
* @param {*} v
|
|
416
|
+
* @returns {HttpRequestBuilder} this builder
|
|
417
|
+
*/
|
|
418
|
+
option(k, v) {
|
|
419
|
+
this.#options[k] = v;
|
|
420
|
+
return this;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Adds interceptors to the request.
|
|
424
|
+
* @param {[HttpInterceptor]} is - the interceptor to be regisered
|
|
425
|
+
* @returns {HttpRequestBuilder} this builder
|
|
426
|
+
*/
|
|
427
|
+
interceptors(is) {
|
|
428
|
+
for (const i of is) {
|
|
429
|
+
this.#interceptors.push(i);
|
|
430
|
+
}
|
|
431
|
+
return this;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Adds an interceptor to the request.
|
|
435
|
+
* @param {HttpInterceptor} i - the interceptor to be regisered
|
|
436
|
+
* @returns {HttpRequestBuilder} this builder
|
|
437
|
+
*/
|
|
438
|
+
interceptor(i) {
|
|
439
|
+
this.#interceptors.push(i);
|
|
440
|
+
return this;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Performs an HTTP exchange using the configured client, request and interceptors.
|
|
444
|
+
* @returns {Promise<Response>} the response
|
|
445
|
+
*/
|
|
446
|
+
async exchange() {
|
|
447
|
+
const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;
|
|
448
|
+
const opts = {
|
|
449
|
+
...this.#options,
|
|
450
|
+
headers: this.#headers,
|
|
451
|
+
method: this.#method,
|
|
452
|
+
body: this.#body,
|
|
453
|
+
};
|
|
454
|
+
return await this.#client.exchange(uri, opts, this.#interceptors);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
458
|
+
* @returns {Promise<Response>} the response
|
|
459
|
+
*/
|
|
460
|
+
async fetch() {
|
|
461
|
+
const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;
|
|
462
|
+
const opts = {
|
|
463
|
+
...this.#options,
|
|
464
|
+
headers: this.#headers,
|
|
465
|
+
method: this.#method,
|
|
466
|
+
body: this.#body,
|
|
467
|
+
};
|
|
205
468
|
try {
|
|
206
|
-
const response = await this.
|
|
207
|
-
|
|
208
|
-
|
|
469
|
+
const response = await this.#client.exchange(uri, opts, this.#interceptors);
|
|
470
|
+
if (!response.ok) {
|
|
471
|
+
throw await HttpClientError.fromResponse(response);
|
|
472
|
+
}
|
|
473
|
+
return response;
|
|
209
474
|
} catch (e) {
|
|
210
475
|
if (e instanceof Failure) {
|
|
211
476
|
throw e;
|
|
212
477
|
}
|
|
213
|
-
throw
|
|
214
|
-
type: "CONNECTION_PROBLEM",
|
|
215
|
-
context: null,
|
|
216
|
-
reason: e.message,
|
|
217
|
-
details: null
|
|
218
|
-
}]);
|
|
478
|
+
throw HttpClientError.of("CONNECTION_PROBLEM", e);
|
|
219
479
|
}
|
|
220
480
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
481
|
+
/**
|
|
482
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
483
|
+
* @returns {Promise<string>} the response body, as text
|
|
484
|
+
*/
|
|
485
|
+
async fetchText() {
|
|
486
|
+
const response = await this.fetch();
|
|
487
|
+
return await unmarshal(response, 'text');
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
491
|
+
* @returns {Promise<any>} the response body, deserialized as JSON
|
|
492
|
+
*/
|
|
493
|
+
async fetchJson() {
|
|
494
|
+
const response = await this.fetch();
|
|
495
|
+
return await unmarshal(response, 'json');
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
499
|
+
* @returns {Promise<Uint8Array>} the response body, as an Uint8Array
|
|
500
|
+
*/
|
|
501
|
+
async fetchBytes() {
|
|
502
|
+
const response = await this.fetch();
|
|
503
|
+
return await unmarshal(response, 'bytes');
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
507
|
+
* @returns {Promise<Blob>} the response body, as a Blob
|
|
508
|
+
*/
|
|
509
|
+
async fetchBlob() {
|
|
510
|
+
const response = await this.fetch();
|
|
511
|
+
return await unmarshal(response, 'blob');
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
515
|
+
* @returns {Promise<ArrayBuffer>} the response body, as an ArrayBuffer
|
|
516
|
+
*/
|
|
517
|
+
async fetchArrayBuffer() {
|
|
518
|
+
const response = await this.fetch();
|
|
519
|
+
return await unmarshal(response, 'arrayBuffer');
|
|
231
520
|
}
|
|
232
|
-
}
|
|
233
|
-
function jsonPost(body, headers){
|
|
234
|
-
return jsonRequest('POST', body, headers);
|
|
235
|
-
}
|
|
236
|
-
function jsonPut(body, headers){
|
|
237
|
-
return jsonRequest('PUT', body, headers);
|
|
238
|
-
}
|
|
239
|
-
function jsonPatch(body, headers){
|
|
240
|
-
return jsonRequest('PATCH', body, headers);
|
|
241
521
|
}
|
|
242
522
|
|
|
243
523
|
class Storage {
|
|
@@ -391,10 +671,10 @@ var ful = (function (exports) {
|
|
|
391
671
|
class AuthorizationCodeFlowSession {
|
|
392
672
|
static parseToken(token) {
|
|
393
673
|
const [rawHeader, rawPayload, signature] = token.split(".");
|
|
394
|
-
const
|
|
674
|
+
const utf8decoder = new TextDecoder("utf-8");
|
|
395
675
|
return {
|
|
396
|
-
header: JSON.parse(
|
|
397
|
-
payload: JSON.parse(
|
|
676
|
+
header: JSON.parse(utf8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),
|
|
677
|
+
payload: JSON.parse(utf8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),
|
|
398
678
|
signature: signature
|
|
399
679
|
};
|
|
400
680
|
}
|
|
@@ -422,7 +702,8 @@ var ful = (function (exports) {
|
|
|
422
702
|
])
|
|
423
703
|
});
|
|
424
704
|
if (!response.ok) {
|
|
425
|
-
|
|
705
|
+
const text = await response.text();
|
|
706
|
+
throw new Error("Error:" + response.status + ": " + text);
|
|
426
707
|
}
|
|
427
708
|
const token = await response.json();
|
|
428
709
|
this.token = token;
|
|
@@ -462,18 +743,19 @@ var ful = (function (exports) {
|
|
|
462
743
|
}
|
|
463
744
|
|
|
464
745
|
class AuthorizationCodeFlowInterceptor {
|
|
746
|
+
#session;
|
|
747
|
+
#gracePeriodBefore;
|
|
748
|
+
#gracePeriodAfter;
|
|
465
749
|
constructor(session, gracePeriodBefore, gracePeriodAfter) {
|
|
466
|
-
this
|
|
467
|
-
this
|
|
468
|
-
this
|
|
750
|
+
this.#session = session;
|
|
751
|
+
this.#gracePeriodBefore = gracePeriodBefore || 2000;
|
|
752
|
+
this.#gracePeriodAfter = gracePeriodAfter || 30000;
|
|
469
753
|
}
|
|
470
754
|
async intercept(request, chain) {
|
|
471
|
-
await this
|
|
472
|
-
|
|
473
|
-
headers.set("Authorization", this.session.bearerToken());
|
|
474
|
-
request.options.headers = headers;
|
|
755
|
+
await this.#session.refreshIf(this.#gracePeriodBefore);
|
|
756
|
+
request.headers.set("Authorization", this.#session.bearerToken());
|
|
475
757
|
const response = await chain.proceed(request);
|
|
476
|
-
await this
|
|
758
|
+
await this.#session.refreshIf(this.#gracePeriodAfter);
|
|
477
759
|
return response;
|
|
478
760
|
}
|
|
479
761
|
}
|
|
@@ -925,8 +1207,6 @@ var ful = (function (exports) {
|
|
|
925
1207
|
return k;
|
|
926
1208
|
};
|
|
927
1209
|
|
|
928
|
-
/* global Infinity, CSS */
|
|
929
|
-
|
|
930
1210
|
function flatten(obj, prefix) {
|
|
931
1211
|
return Object.keys(obj).reduce((acc, k) => {
|
|
932
1212
|
const pre = prefix.length ? prefix + '.' : '';
|
|
@@ -1084,7 +1364,7 @@ var ful = (function (exports) {
|
|
|
1084
1364
|
if (!this.hasAttribute('scroll-on-error')) {
|
|
1085
1365
|
return;
|
|
1086
1366
|
}
|
|
1087
|
-
const ys = Array.from(this.querySelectorAll(`[ful-validated-field]:has(.${Form.INVALID_CLASS}) ful-field-error`))
|
|
1367
|
+
const ys = Array.from(this.querySelectorAll(`ful-errors:not([hidden]), [ful-validated-field]:has(.${Form.INVALID_CLASS}) ful-field-error`))
|
|
1088
1368
|
.map(el => el.parentElement ? el.parentElement : el)
|
|
1089
1369
|
.map(el => el.getBoundingClientRect().y + window.scrollY);
|
|
1090
1370
|
const miny = Math.min(...ys);
|
|
@@ -1359,6 +1639,7 @@ var ful = (function (exports) {
|
|
|
1359
1639
|
exports.Fragments = Fragments;
|
|
1360
1640
|
exports.Hex = Hex;
|
|
1361
1641
|
exports.HttpClient = HttpClient;
|
|
1642
|
+
exports.HttpClientError = HttpClientError;
|
|
1362
1643
|
exports.INPUT_TEMPLATE = INPUT_TEMPLATE;
|
|
1363
1644
|
exports.Input = Input;
|
|
1364
1645
|
exports.LightSlots = LightSlots;
|
|
@@ -1372,15 +1653,9 @@ var ful = (function (exports) {
|
|
|
1372
1653
|
exports.TemplatesRegistry = TemplatesRegistry;
|
|
1373
1654
|
exports.VersionedStorage = VersionedStorage;
|
|
1374
1655
|
exports.elements = elements;
|
|
1375
|
-
exports.jsonPatch = jsonPatch;
|
|
1376
|
-
exports.jsonPost = jsonPost;
|
|
1377
|
-
exports.jsonPut = jsonPut;
|
|
1378
|
-
exports.jsonRequest = jsonRequest;
|
|
1379
1656
|
exports.makeInputFragment = makeInputFragment;
|
|
1380
1657
|
exports.timing = timing;
|
|
1381
1658
|
|
|
1382
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1383
|
-
|
|
1384
1659
|
return exports;
|
|
1385
1660
|
|
|
1386
1661
|
})({});
|