@optionfactory/ful 0.80.0 → 0.91.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.iife.js +567 -158
- 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 +567 -153
- package/dist/ful.mjs.map +1 -1
- package/package.json +10 -7
package/dist/ful.iife.js
CHANGED
|
@@ -73,171 +73,563 @@ var ful = (function (exports) {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
/**
|
|
77
|
+
* @typedef {{ type: string; context: string?; reason: string; details: any?; }} Problem
|
|
78
|
+
*/
|
|
79
|
+
class Failure extends Error {
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* @param {string} message
|
|
83
|
+
* @param {Problem[]} problems
|
|
84
|
+
* @param {*} cause
|
|
85
|
+
*/
|
|
86
|
+
constructor(message, problems, cause) {
|
|
87
|
+
super(message, { cause });
|
|
88
|
+
this.name = 'Failure';
|
|
89
|
+
this.problems = problems;
|
|
80
90
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @typedef {Int8Array| Uint8Array| Uint8ClampedArray| Int16Array| Uint16Array| Int32Array| Uint32Array| Float32Array| Float64Array| BigInt64Array| BigUint64Array} TypedArray
|
|
95
|
+
*/
|
|
96
|
+
/**
|
|
97
|
+
* @typedef HttpInterceptor
|
|
98
|
+
* @property {function(Request,HttpInterceptorChain):Promise<Response>} intercept
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
class HttpClientError extends Failure {
|
|
102
|
+
/**
|
|
103
|
+
* @param {string} message
|
|
104
|
+
* @param {number} status
|
|
105
|
+
* @param {{ type: string; context: string?; reason: string; details: any?; }[]} problems
|
|
106
|
+
* @param {Error|undefined} [cause]
|
|
107
|
+
*/
|
|
108
|
+
constructor(message, status, problems, cause) {
|
|
109
|
+
super(message, problems, cause);
|
|
110
|
+
this.name = 'HttpClientError';
|
|
111
|
+
this.status = status;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
* @param {string} type
|
|
116
|
+
* @param {any} cause
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
119
|
+
static of(type, cause) {
|
|
120
|
+
return new HttpClientError(cause.message, 0, [{
|
|
121
|
+
type,
|
|
122
|
+
context: null,
|
|
123
|
+
reason: cause.message,
|
|
124
|
+
details: null
|
|
125
|
+
}], cause);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Creates an HttpClientError from a Response.
|
|
129
|
+
* @param {Response} response
|
|
130
|
+
* @returns an HttpClientError
|
|
131
|
+
*/
|
|
132
|
+
static async fromResponse(response) {
|
|
133
|
+
const text = await response.text();
|
|
134
|
+
const message = `${response.status} ${response.statusText}: ${text}`;
|
|
135
|
+
const fallback = [{
|
|
136
|
+
type: "GENERIC_PROBLEM",
|
|
137
|
+
context: null,
|
|
138
|
+
reason: message,
|
|
139
|
+
details: null
|
|
140
|
+
}];
|
|
141
|
+
try {
|
|
142
|
+
return new HttpClientError(message, response.status, text ? JSON.parse(text) : fallback);
|
|
143
|
+
} catch (e) {
|
|
144
|
+
return new HttpClientError(message, response.status, fallback);
|
|
145
|
+
}
|
|
85
146
|
}
|
|
86
147
|
}
|
|
87
148
|
|
|
149
|
+
/**
|
|
150
|
+
* @implements {HttpInterceptor}
|
|
151
|
+
*/
|
|
88
152
|
class CsrfTokenInterceptor {
|
|
153
|
+
#k; #v;
|
|
89
154
|
constructor() {
|
|
90
|
-
this
|
|
91
|
-
this
|
|
92
|
-
}
|
|
93
|
-
async intercept(request, chain){
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
155
|
+
this.#k = document.querySelector("meta[name='_csrf_header']")?.getAttribute("content");
|
|
156
|
+
this.#v = document.querySelector("meta[name='_csrf']")?.getAttribute("content");
|
|
157
|
+
}
|
|
158
|
+
async intercept(request, chain) {
|
|
159
|
+
if(this.#k && this.#v) {
|
|
160
|
+
request.headers.set(this.#k, this.#v);
|
|
161
|
+
}
|
|
97
162
|
return await chain.proceed(request);
|
|
98
163
|
}
|
|
99
164
|
}
|
|
100
|
-
|
|
165
|
+
/**
|
|
166
|
+
* @implements {HttpInterceptor}
|
|
167
|
+
*/
|
|
101
168
|
class RedirectOnUnauthorizedInterceptor {
|
|
169
|
+
#redirectUri;
|
|
170
|
+
/**
|
|
171
|
+
* @param {string} redirectUri
|
|
172
|
+
*/
|
|
102
173
|
constructor(redirectUri) {
|
|
103
|
-
this
|
|
174
|
+
this.#redirectUri = redirectUri;
|
|
104
175
|
}
|
|
105
|
-
async intercept(request, chain){
|
|
106
|
-
const response =
|
|
107
|
-
if (response.status
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
window.location.href = this.redirectUri;
|
|
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;
|
|
176
|
+
async intercept(request, chain) {
|
|
177
|
+
const response = await chain.proceed(request);
|
|
178
|
+
if (response.status === 401) {
|
|
179
|
+
window.location.href = this.#redirectUri;
|
|
126
180
|
}
|
|
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;
|
|
181
|
+
return response;
|
|
136
182
|
}
|
|
137
183
|
}
|
|
138
184
|
|
|
139
185
|
class HttpClientBuilder {
|
|
186
|
+
/**
|
|
187
|
+
* @type {HttpInterceptor[]}
|
|
188
|
+
*/
|
|
189
|
+
#interceptors;
|
|
140
190
|
constructor() {
|
|
141
|
-
this
|
|
142
|
-
}
|
|
143
|
-
withContext() {
|
|
144
|
-
this.interceptors.push(new ContextInterceptor());
|
|
145
|
-
return this;
|
|
191
|
+
this.#interceptors = [];
|
|
146
192
|
}
|
|
147
193
|
withCsrfToken() {
|
|
148
|
-
this
|
|
194
|
+
this.#interceptors.push(new CsrfTokenInterceptor());
|
|
149
195
|
return this;
|
|
150
196
|
}
|
|
151
197
|
withRedirectOnUnauthorized(redirectUri) {
|
|
152
|
-
this
|
|
198
|
+
this.#interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));
|
|
153
199
|
return this;
|
|
154
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* @param {...HttpInterceptor} interceptors
|
|
203
|
+
*/
|
|
155
204
|
withInterceptors(...interceptors) {
|
|
156
|
-
this
|
|
205
|
+
this.#interceptors.push(...interceptors);
|
|
157
206
|
return this;
|
|
158
207
|
}
|
|
159
208
|
build() {
|
|
160
|
-
|
|
161
|
-
return new HttpClient({interceptors});
|
|
209
|
+
return new HttpClient(this.#interceptors);
|
|
162
210
|
}
|
|
163
211
|
}
|
|
164
212
|
|
|
213
|
+
/**
|
|
214
|
+
* @implements {HttpInterceptor}
|
|
215
|
+
*/
|
|
165
216
|
class HttpCall {
|
|
166
|
-
async intercept(request, chain){
|
|
167
|
-
return await fetch(request
|
|
168
|
-
}
|
|
217
|
+
async intercept(request, chain) {
|
|
218
|
+
return await fetch(request);
|
|
219
|
+
}
|
|
169
220
|
}
|
|
170
221
|
|
|
171
222
|
class HttpInterceptorChain {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
223
|
+
#interceptors;
|
|
224
|
+
#current;
|
|
225
|
+
/**
|
|
226
|
+
*
|
|
227
|
+
* @param {HttpInterceptor[]} interceptors
|
|
228
|
+
* @param {number} current
|
|
229
|
+
*/
|
|
230
|
+
constructor(interceptors, current) {
|
|
231
|
+
this.#interceptors = interceptors;
|
|
232
|
+
this.#current = current;
|
|
175
233
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
234
|
+
/**
|
|
235
|
+
*
|
|
236
|
+
* @param {Request} request
|
|
237
|
+
* @returns {Promise<Response>} the response
|
|
238
|
+
*/
|
|
239
|
+
async proceed(request) {
|
|
240
|
+
const interceptor = this.#interceptors[this.#current];
|
|
241
|
+
return await interceptor.intercept(request, new HttpInterceptorChain(this.#interceptors, this.#current + 1));
|
|
179
242
|
}
|
|
180
243
|
}
|
|
181
244
|
|
|
182
|
-
|
|
183
245
|
class HttpClient {
|
|
246
|
+
#interceptors;
|
|
247
|
+
/**
|
|
248
|
+
* Creates a builder for an HttpClient.
|
|
249
|
+
* @returns {HttpClientBuilder} the client builder
|
|
250
|
+
*/
|
|
184
251
|
static builder() {
|
|
185
252
|
return new HttpClientBuilder();
|
|
186
253
|
}
|
|
187
|
-
|
|
188
|
-
|
|
254
|
+
/**
|
|
255
|
+
* Creates an HttpClient.
|
|
256
|
+
* @param {HttpInterceptor[]|undefined} interceptors - a list of interceptors to be registered for every request performed by the created client.
|
|
257
|
+
*/
|
|
258
|
+
constructor(interceptors) {
|
|
259
|
+
this.#interceptors = interceptors || [];
|
|
189
260
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Performs an HTTP exchange.
|
|
263
|
+
* @async
|
|
264
|
+
* @param {string} uri - the (possibly relative) request url
|
|
265
|
+
* @param {RequestInit|undefined} options - fetch options
|
|
266
|
+
* @param {HttpInterceptor[]|undefined} interceptors - the HttpInterceptors to be registered for this exchange.
|
|
267
|
+
* @returns {Promise<Response>} the response
|
|
268
|
+
*/
|
|
269
|
+
async exchange(uri, options, interceptors) {
|
|
270
|
+
const is = [...this.#interceptors, ...interceptors || [], new HttpCall()];
|
|
271
|
+
const chain = new HttpInterceptorChain(is, 0);
|
|
272
|
+
return await chain.proceed(new Request(uri, options));
|
|
195
273
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
274
|
+
/**
|
|
275
|
+
* Creates a request builder.
|
|
276
|
+
* @param {string} method - the HTTP method to be used
|
|
277
|
+
* @param {string} uri - the (possibly relative) request url
|
|
278
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
279
|
+
*/
|
|
280
|
+
request(method, uri) {
|
|
281
|
+
return HttpRequestBuilder.create(this, method, uri);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Creates a request builder.
|
|
285
|
+
* @param {string} uri - the (possibly relative) request url
|
|
286
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
287
|
+
*/
|
|
288
|
+
get(uri) {
|
|
289
|
+
return HttpRequestBuilder.create(this, 'GET', uri);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Creates a request builder.
|
|
293
|
+
* @param {string} uri - the (possibly relative) request url
|
|
294
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
295
|
+
*/
|
|
296
|
+
head(uri) {
|
|
297
|
+
return HttpRequestBuilder.create(this, 'HEAD', uri);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Creates a request builder.
|
|
301
|
+
* @param {string} uri - the (possibly relative) request url
|
|
302
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
303
|
+
*/
|
|
304
|
+
post(uri) {
|
|
305
|
+
return HttpRequestBuilder.create(this, 'POST', uri);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Creates a request builder.
|
|
309
|
+
* @param {string} uri - the (possibly relative) request url
|
|
310
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
311
|
+
*/
|
|
312
|
+
put(uri) {
|
|
313
|
+
return HttpRequestBuilder.create(this, 'PUT', uri);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Creates a request builder.
|
|
317
|
+
* @param {string} uri - the (possibly relative) request url
|
|
318
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
319
|
+
*/
|
|
320
|
+
patch(uri) {
|
|
321
|
+
return HttpRequestBuilder.create(this, 'PATCH', uri);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Creates a request builder.
|
|
325
|
+
* @param {string} uri - the (possibly relative) request url
|
|
326
|
+
* @returns {HttpRequestBuilder} the request builder
|
|
327
|
+
*/
|
|
328
|
+
delete(uri) {
|
|
329
|
+
return HttpRequestBuilder.create(this, 'DELETE', uri);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
*
|
|
335
|
+
* @param {Response} response
|
|
336
|
+
* @param {'text'|'json'|'blob'|'arrayBuffer'} type
|
|
337
|
+
* @returns
|
|
338
|
+
*/
|
|
339
|
+
const unmarshal = async (response, type) => {
|
|
340
|
+
try {
|
|
341
|
+
return await response[type]();
|
|
342
|
+
} catch (ex) {
|
|
343
|
+
throw HttpClientError.of("UNMARSHALING_PROBLEM", ex);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class HttpRequestBuilder {
|
|
349
|
+
#client;
|
|
350
|
+
#method;
|
|
351
|
+
#uri;
|
|
352
|
+
#params;
|
|
353
|
+
#headers;
|
|
354
|
+
#body;
|
|
355
|
+
#options;
|
|
356
|
+
#interceptors;
|
|
357
|
+
/**
|
|
358
|
+
* Creates an HttpRequestBuilder.
|
|
359
|
+
* @param {HttpClient} client
|
|
360
|
+
* @param {string} method - the HTTP method to be used
|
|
361
|
+
* @param {string} uri - the (possibly relative) request url
|
|
362
|
+
* @returns {HttpRequestBuilder} the builder
|
|
363
|
+
*/
|
|
364
|
+
static create(client, method, uri) {
|
|
365
|
+
return new HttpRequestBuilder(
|
|
366
|
+
client,
|
|
367
|
+
method,
|
|
368
|
+
uri,
|
|
369
|
+
new URLSearchParams(),
|
|
370
|
+
new Headers(),
|
|
371
|
+
undefined,
|
|
372
|
+
{},
|
|
373
|
+
[]
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Creates an HttpRequestBuilder.
|
|
378
|
+
* @param {HttpClient} client
|
|
379
|
+
* @param {string} method - the HTTP method to be used
|
|
380
|
+
* @param {string} uri - the (possibly relative) request url
|
|
381
|
+
* @param {URLSearchParams} params
|
|
382
|
+
* @param {Headers} headers
|
|
383
|
+
* @param {any} body
|
|
384
|
+
* @param {Omit<RequestInit,"headers"|"method"|"body">} options
|
|
385
|
+
* @param {HttpInterceptor[]} interceptors
|
|
386
|
+
*/
|
|
387
|
+
constructor(client, method, uri, params, headers, body, options, interceptors) {
|
|
388
|
+
this.#client = client;
|
|
389
|
+
this.#method = method;
|
|
390
|
+
this.#uri = uri;
|
|
391
|
+
this.#params = params;
|
|
392
|
+
this.#body = body;
|
|
393
|
+
this.#headers = headers;
|
|
394
|
+
this.#options = options;
|
|
395
|
+
this.#interceptors = interceptors;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Add all passed headers to the request, overriding existing ones if that key already exists.
|
|
399
|
+
* @param {HeadersInit} hs
|
|
400
|
+
* @returns {HttpRequestBuilder} this builder
|
|
401
|
+
*/
|
|
402
|
+
headers(hs) {
|
|
403
|
+
for (const [k, v] of new Headers(hs).entries()) {
|
|
404
|
+
this.#headers.set(k, v);
|
|
405
|
+
}
|
|
406
|
+
return this;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Adds an header to the request, overriding it if it already exists.
|
|
410
|
+
* @param {string} k
|
|
411
|
+
* @param {string} v
|
|
412
|
+
* @returns {HttpRequestBuilder} this builder
|
|
413
|
+
*/
|
|
414
|
+
header(k, v) {
|
|
415
|
+
this.#headers.set(k, v);
|
|
416
|
+
return this;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Add all query parameters to the request, overriding existing ones if that key already exists.
|
|
420
|
+
* @param {URLSearchParams|Record<string,string>|string[][]|string} ps
|
|
421
|
+
* @returns {HttpRequestBuilder} this builder
|
|
422
|
+
*/
|
|
423
|
+
params(ps) {
|
|
424
|
+
for (const [k, v] of new URLSearchParams(ps).entries()) {
|
|
425
|
+
this.#params.set(k, v);
|
|
426
|
+
}
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Adds a query parameter to the request, overriding it if it already exists.
|
|
431
|
+
* @param {string} k
|
|
432
|
+
* @param {string} v
|
|
433
|
+
* @returns {HttpRequestBuilder} this builder
|
|
434
|
+
*/
|
|
435
|
+
param(k, v) {
|
|
436
|
+
this.#params.set(k, v);
|
|
437
|
+
return this;
|
|
203
438
|
}
|
|
204
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Sets the request body.
|
|
441
|
+
* `Content-Type: multipart/form-data` header is automatically added by fetch when data is a FormData instance if not explicitly set.
|
|
442
|
+
* `Content-Type: application/x-www-form-urlencoded` header is automatically added by fetch when data is an URLSearchParams instance if not explicitly set.
|
|
443
|
+
* `Content-Type: text/plain` header is automatically added by fetch when data is a string instance if not explicitly set.
|
|
444
|
+
* @param {string|ArrayBuffer|Blob|DataView|File|FormData|TypedArray|URLSearchParams|ReadableStream} data
|
|
445
|
+
* @returns {HttpRequestBuilder} this builder
|
|
446
|
+
*/
|
|
447
|
+
body(data) {
|
|
448
|
+
this.#body = data;
|
|
449
|
+
return this;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Sets the request body that will be serialized as json. Calling this method adds the `Content-Type application/json` header for the request.
|
|
453
|
+
* @param {any} body - the body to be serialized as json
|
|
454
|
+
* @returns {HttpRequestBuilder} this builder
|
|
455
|
+
*/
|
|
456
|
+
json(body) {
|
|
457
|
+
this.#headers.set("Content-Type", "application/json");
|
|
458
|
+
this.#body = JSON.stringify(body);
|
|
459
|
+
return this;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Sets the request body as a FormData configured using the callback.
|
|
463
|
+
* `Content-Type: multipart/form-data` header is automatically added by fetch if not explicitly set.
|
|
464
|
+
* @param {function(HttpMultipartRequestCustomizer):void} callback
|
|
465
|
+
*/
|
|
466
|
+
multipart(callback) {
|
|
467
|
+
const formData = new FormData();
|
|
468
|
+
const builder = new HttpMultipartRequestCustomizer(formData);
|
|
469
|
+
callback(builder);
|
|
470
|
+
this.#body = formData;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Sets a fetch options for the request.
|
|
474
|
+
* @param {Omit<RequestInit,"headers"|"method"|"body">} kvs
|
|
475
|
+
* @returns {HttpRequestBuilder} this builder
|
|
476
|
+
*/
|
|
477
|
+
options(kvs) {
|
|
478
|
+
for (const [k, v] of Object.entries(kvs)) {
|
|
479
|
+
// @ts-ignore
|
|
480
|
+
this.#options[k] = v;
|
|
481
|
+
}
|
|
482
|
+
return this;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Sets a fetch option for the request.
|
|
486
|
+
* @param {keyof Omit<RequestInit,"headers"|"method"|"body">} k
|
|
487
|
+
* @param {*} v
|
|
488
|
+
* @returns {HttpRequestBuilder} this builder
|
|
489
|
+
*/
|
|
490
|
+
option(k, v) {
|
|
491
|
+
this.#options[k] = v;
|
|
492
|
+
return this;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Adds interceptors to the request.
|
|
496
|
+
* @param {[HttpInterceptor]} is - the interceptor to be regisered
|
|
497
|
+
* @returns {HttpRequestBuilder} this builder
|
|
498
|
+
*/
|
|
499
|
+
interceptors(is) {
|
|
500
|
+
for (const i of is) {
|
|
501
|
+
this.#interceptors.push(i);
|
|
502
|
+
}
|
|
503
|
+
return this;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Adds an interceptor to the request.
|
|
507
|
+
* @param {HttpInterceptor} i - the interceptor to be regisered
|
|
508
|
+
* @returns {HttpRequestBuilder} this builder
|
|
509
|
+
*/
|
|
510
|
+
interceptor(i) {
|
|
511
|
+
this.#interceptors.push(i);
|
|
512
|
+
return this;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Performs an HTTP exchange using the configured client, request and interceptors.
|
|
516
|
+
* @returns {Promise<Response>} the response
|
|
517
|
+
*/
|
|
518
|
+
async exchange() {
|
|
519
|
+
const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;
|
|
520
|
+
const opts = {
|
|
521
|
+
...this.#options,
|
|
522
|
+
headers: this.#headers,
|
|
523
|
+
method: this.#method,
|
|
524
|
+
body: this.#body,
|
|
525
|
+
};
|
|
526
|
+
return await this.#client.exchange(uri, opts, this.#interceptors);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
530
|
+
* @returns {Promise<Response>} the response
|
|
531
|
+
*/
|
|
532
|
+
async fetch() {
|
|
533
|
+
const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;
|
|
534
|
+
const opts = {
|
|
535
|
+
...this.#options,
|
|
536
|
+
headers: this.#headers,
|
|
537
|
+
method: this.#method,
|
|
538
|
+
body: this.#body,
|
|
539
|
+
};
|
|
205
540
|
try {
|
|
206
|
-
const response = await this.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
541
|
+
const response = await this.#client.exchange(uri, opts, this.#interceptors);
|
|
542
|
+
if (!response.ok) {
|
|
543
|
+
throw await HttpClientError.fromResponse(response);
|
|
544
|
+
}
|
|
545
|
+
return response;
|
|
546
|
+
} catch (ex) {
|
|
547
|
+
if (ex instanceof Failure) {
|
|
548
|
+
throw ex;
|
|
212
549
|
}
|
|
213
|
-
throw
|
|
214
|
-
type: "CONNECTION_PROBLEM",
|
|
215
|
-
context: null,
|
|
216
|
-
reason: e.message,
|
|
217
|
-
details: null
|
|
218
|
-
}]);
|
|
550
|
+
throw HttpClientError.of("CONNECTION_PROBLEM", ex);
|
|
219
551
|
}
|
|
220
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
555
|
+
* @returns {Promise<string>} the response body, as text
|
|
556
|
+
*/
|
|
557
|
+
async fetchText() {
|
|
558
|
+
const response = await this.fetch();
|
|
559
|
+
return await unmarshal(response, 'text');
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
563
|
+
* @returns {Promise<any>} the response body, deserialized as JSON
|
|
564
|
+
*/
|
|
565
|
+
async fetchJson() {
|
|
566
|
+
const response = await this.fetch();
|
|
567
|
+
return await unmarshal(response, 'json');
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
571
|
+
* @returns {Promise<Blob>} the response body, as a Blob
|
|
572
|
+
*/
|
|
573
|
+
async fetchBlob() {
|
|
574
|
+
const response = await this.fetch();
|
|
575
|
+
return await unmarshal(response, 'blob');
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
|
|
579
|
+
* @returns {Promise<ArrayBuffer>} the response body, as an ArrayBuffer
|
|
580
|
+
*/
|
|
581
|
+
async fetchArrayBuffer() {
|
|
582
|
+
const response = await this.fetch();
|
|
583
|
+
return await unmarshal(response, 'arrayBuffer');
|
|
584
|
+
}
|
|
221
585
|
}
|
|
222
586
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
587
|
+
|
|
588
|
+
class HttpMultipartRequestCustomizer {
|
|
589
|
+
#formData;
|
|
590
|
+
/**
|
|
591
|
+
*
|
|
592
|
+
* @param {FormData} formData
|
|
593
|
+
*/
|
|
594
|
+
constructor(formData){
|
|
595
|
+
this.#formData = formData;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Appends a value to the FormData.
|
|
599
|
+
* @param {string} name
|
|
600
|
+
* @param {*} value
|
|
601
|
+
* @returns this builder
|
|
602
|
+
*/
|
|
603
|
+
field(name, value){
|
|
604
|
+
this.#formData.append(name, value);
|
|
605
|
+
return this;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Appends a Blob to the FormData.
|
|
609
|
+
* If `filename` is omitted, FormData defaults are applied:
|
|
610
|
+
* The default filename for Blob objects is "blob";
|
|
611
|
+
* The default filename for File objects is the file's filename.
|
|
612
|
+
* @param {string} name
|
|
613
|
+
* @param {Blob} value
|
|
614
|
+
* @param {string|undefined} filename
|
|
615
|
+
* @returns this builder
|
|
616
|
+
*/
|
|
617
|
+
blob(name, value, filename){
|
|
618
|
+
this.#formData.append(name, value, filename);
|
|
619
|
+
return this;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Appends a JSON serialized blob to the FormData.
|
|
623
|
+
* @param {string} name
|
|
624
|
+
* @param {any} value
|
|
625
|
+
* @param {string|undefined} filename
|
|
626
|
+
* @returns this builder
|
|
627
|
+
*/
|
|
628
|
+
json(name, value, filename){
|
|
629
|
+
const blob = new Blob([JSON.stringify(value)], {type: 'application/json'});
|
|
630
|
+
this.#formData.append(name, blob, filename);
|
|
631
|
+
return this;
|
|
231
632
|
}
|
|
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
633
|
}
|
|
242
634
|
|
|
243
635
|
class Storage {
|
|
@@ -336,7 +728,7 @@ var ful = (function (exports) {
|
|
|
336
728
|
Object.entries(additionalParams || {}).forEach(kv => {
|
|
337
729
|
url.searchParams.set(kv[0], kv[1]);
|
|
338
730
|
});
|
|
339
|
-
window.location = url;
|
|
731
|
+
window.location.href = url.toString();
|
|
340
732
|
}
|
|
341
733
|
async registration(additionalParams){
|
|
342
734
|
await this.action(this.uri.registration, additionalParams);
|
|
@@ -346,7 +738,7 @@ var ful = (function (exports) {
|
|
|
346
738
|
kc_action: kcAction
|
|
347
739
|
});
|
|
348
740
|
}
|
|
349
|
-
async
|
|
741
|
+
async #tokenExchange(code, state) {
|
|
350
742
|
window.history.replaceState('', "", this.uri.redirect);
|
|
351
743
|
const stateAndVerifier = this.storage.pop(AuthorizationCodeFlow.PKCE_AND_STATE_KEY);
|
|
352
744
|
if (stateAndVerifier.state !== state) {
|
|
@@ -379,7 +771,7 @@ var ful = (function (exports) {
|
|
|
379
771
|
if (code && this.storage.load(AuthorizationCodeFlow.PKCE_AND_STATE_KEY)) {
|
|
380
772
|
//if callback from keycloak and we have our state still stored
|
|
381
773
|
const state = url.searchParams.get("state");
|
|
382
|
-
return await this
|
|
774
|
+
return await this.#tokenExchange(code, state);
|
|
383
775
|
}
|
|
384
776
|
//if not authorized
|
|
385
777
|
await this.action(this.uri.auth, {});
|
|
@@ -391,10 +783,10 @@ var ful = (function (exports) {
|
|
|
391
783
|
class AuthorizationCodeFlowSession {
|
|
392
784
|
static parseToken(token) {
|
|
393
785
|
const [rawHeader, rawPayload, signature] = token.split(".");
|
|
394
|
-
const
|
|
786
|
+
const utf8decoder = new TextDecoder("utf-8");
|
|
395
787
|
return {
|
|
396
|
-
header: JSON.parse(
|
|
397
|
-
payload: JSON.parse(
|
|
788
|
+
header: JSON.parse(utf8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),
|
|
789
|
+
payload: JSON.parse(utf8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),
|
|
398
790
|
signature: signature
|
|
399
791
|
};
|
|
400
792
|
}
|
|
@@ -422,7 +814,8 @@ var ful = (function (exports) {
|
|
|
422
814
|
])
|
|
423
815
|
});
|
|
424
816
|
if (!response.ok) {
|
|
425
|
-
|
|
817
|
+
const text = await response.text();
|
|
818
|
+
throw new Error("Error:" + response.status + ": " + text);
|
|
426
819
|
}
|
|
427
820
|
const token = await response.json();
|
|
428
821
|
this.token = token;
|
|
@@ -449,7 +842,7 @@ var ful = (function (exports) {
|
|
|
449
842
|
const url = new URL(this.uri.logout);
|
|
450
843
|
url.searchParams.set("post_logout_redirect_uri", this.uri.redirect);
|
|
451
844
|
url.searchParams.set("id_token_hint", this.token.id_token);
|
|
452
|
-
window.location = url;
|
|
845
|
+
window.location.href = url.toString();
|
|
453
846
|
}
|
|
454
847
|
|
|
455
848
|
bearerToken() {
|
|
@@ -462,18 +855,19 @@ var ful = (function (exports) {
|
|
|
462
855
|
}
|
|
463
856
|
|
|
464
857
|
class AuthorizationCodeFlowInterceptor {
|
|
858
|
+
#session;
|
|
859
|
+
#gracePeriodBefore;
|
|
860
|
+
#gracePeriodAfter;
|
|
465
861
|
constructor(session, gracePeriodBefore, gracePeriodAfter) {
|
|
466
|
-
this
|
|
467
|
-
this
|
|
468
|
-
this
|
|
862
|
+
this.#session = session;
|
|
863
|
+
this.#gracePeriodBefore = gracePeriodBefore || 2000;
|
|
864
|
+
this.#gracePeriodAfter = gracePeriodAfter || 30000;
|
|
469
865
|
}
|
|
470
866
|
async intercept(request, chain) {
|
|
471
|
-
await this
|
|
472
|
-
|
|
473
|
-
headers.set("Authorization", this.session.bearerToken());
|
|
474
|
-
request.options.headers = headers;
|
|
867
|
+
await this.#session.refreshIf(this.#gracePeriodBefore);
|
|
868
|
+
request.headers.set("Authorization", this.#session.bearerToken());
|
|
475
869
|
const response = await chain.proceed(request);
|
|
476
|
-
await this
|
|
870
|
+
await this.#session.refreshIf(this.#gracePeriodAfter);
|
|
477
871
|
return response;
|
|
478
872
|
}
|
|
479
873
|
}
|
|
@@ -507,7 +901,7 @@ var ful = (function (exports) {
|
|
|
507
901
|
};
|
|
508
902
|
|
|
509
903
|
return function () {
|
|
510
|
-
args = arguments;
|
|
904
|
+
args = [...arguments];
|
|
511
905
|
previousTimestamp = new Date().getTime();
|
|
512
906
|
if (tid === null) {
|
|
513
907
|
tid = setTimeout(later, timeoutMs);
|
|
@@ -541,7 +935,7 @@ var ful = (function (exports) {
|
|
|
541
935
|
previousTimestamp = now;
|
|
542
936
|
}
|
|
543
937
|
const remaining = timeoutMs - (now - previousTimestamp);
|
|
544
|
-
args = arguments;
|
|
938
|
+
args = [...arguments];
|
|
545
939
|
if (remaining <= 0 || remaining > timeoutMs) {
|
|
546
940
|
if (tid !== null) {
|
|
547
941
|
clearTimeout(tid);
|
|
@@ -647,16 +1041,18 @@ var ful = (function (exports) {
|
|
|
647
1041
|
.forEach(a => {
|
|
648
1042
|
const target = a.substring(prefix.length);
|
|
649
1043
|
if (target === 'class') {
|
|
650
|
-
|
|
1044
|
+
const classes = from.getAttribute(prefix + "class")?.split(" ").filter(a => a.length) ?? [];
|
|
1045
|
+
to.classList.add(...classes);
|
|
651
1046
|
return;
|
|
652
1047
|
}
|
|
1048
|
+
// @ts-ignore
|
|
653
1049
|
to.setAttribute(target, from.getAttribute(a));
|
|
654
1050
|
});
|
|
655
1051
|
}
|
|
656
1052
|
/**
|
|
657
1053
|
*
|
|
658
1054
|
* @param {HTMLElement} el
|
|
659
|
-
* @param {
|
|
1055
|
+
* @param {string} attr
|
|
660
1056
|
* @param {boolean} value
|
|
661
1057
|
*/
|
|
662
1058
|
static toggle(el, attr, value) {
|
|
@@ -683,19 +1079,21 @@ var ful = (function (exports) {
|
|
|
683
1079
|
* @returns the slots
|
|
684
1080
|
*/
|
|
685
1081
|
static from(el) {
|
|
1082
|
+
/** @type [string, Element][] */
|
|
686
1083
|
const namedSlots = Array.from(el.childNodes)
|
|
687
|
-
.filter(el => el
|
|
1084
|
+
.filter(el => el instanceof Element)
|
|
1085
|
+
.filter(el => el.matches('[slot]'))
|
|
688
1086
|
.map(el => {
|
|
689
1087
|
el.remove();
|
|
690
1088
|
const slot = el.getAttribute("slot");
|
|
691
1089
|
el.removeAttribute("slot");
|
|
692
|
-
return [slot, el];
|
|
1090
|
+
return [slot ?? 'unnamed', el];
|
|
693
1091
|
});
|
|
694
1092
|
const slots = {};
|
|
695
1093
|
slots.default = new DocumentFragment();
|
|
696
1094
|
slots.default.append(...el.childNodes);
|
|
697
|
-
for(const [name,el] of namedSlots){
|
|
698
|
-
if(!(name in slots)){
|
|
1095
|
+
for (const [name, el] of namedSlots) {
|
|
1096
|
+
if (!(name in slots)) {
|
|
699
1097
|
slots[name] = new DocumentFragment();
|
|
700
1098
|
}
|
|
701
1099
|
slots[name].append(el);
|
|
@@ -721,7 +1119,8 @@ var ful = (function (exports) {
|
|
|
721
1119
|
#ec;
|
|
722
1120
|
put(k, fragment) {
|
|
723
1121
|
if (this.#ec) {
|
|
724
|
-
|
|
1122
|
+
// @ts-ignore
|
|
1123
|
+
this.#idToTemplate[k] = ftl.Template.fromFragment(fragment, this.#ec);
|
|
725
1124
|
return;
|
|
726
1125
|
}
|
|
727
1126
|
this.#idToFragment[k] = fragment;
|
|
@@ -740,6 +1139,7 @@ var ful = (function (exports) {
|
|
|
740
1139
|
this.#ec = ec;
|
|
741
1140
|
for (const [k, fragment] of Object.entries(this.#idToFragment)) {
|
|
742
1141
|
delete this.#idToFragment[k];
|
|
1142
|
+
// @ts-ignore
|
|
743
1143
|
this.#idToTemplate[k] = ftl.Template.fromFragment(fragment, ec, ...data);
|
|
744
1144
|
}
|
|
745
1145
|
}
|
|
@@ -843,8 +1243,8 @@ var ful = (function (exports) {
|
|
|
843
1243
|
#initialized;
|
|
844
1244
|
#reflecting;
|
|
845
1245
|
#internals;
|
|
846
|
-
constructor(
|
|
847
|
-
super(
|
|
1246
|
+
constructor() {
|
|
1247
|
+
super();
|
|
848
1248
|
this.#internals = this.attachInternals();
|
|
849
1249
|
}
|
|
850
1250
|
get initialized() {
|
|
@@ -872,6 +1272,7 @@ var ful = (function (exports) {
|
|
|
872
1272
|
observer.disconnect();
|
|
873
1273
|
upgradeQueue.enqueue(this);
|
|
874
1274
|
});
|
|
1275
|
+
// @ts-ignore
|
|
875
1276
|
observer.observe(this.parentNode, { childList: true, subtree: true });
|
|
876
1277
|
}
|
|
877
1278
|
attributeChangedCallback(attr, oldValue, newValue) {
|
|
@@ -897,6 +1298,7 @@ var ful = (function (exports) {
|
|
|
897
1298
|
return;
|
|
898
1299
|
}
|
|
899
1300
|
this.#parsed = true;
|
|
1301
|
+
// @ts-ignore
|
|
900
1302
|
await this.render(elements.template(templateId), slots ? LightSlots.from(this) : undefined);
|
|
901
1303
|
|
|
902
1304
|
for (const [attr, mapper] of attrsAndMappers) {
|
|
@@ -925,8 +1327,6 @@ var ful = (function (exports) {
|
|
|
925
1327
|
return k;
|
|
926
1328
|
};
|
|
927
1329
|
|
|
928
|
-
/* global Infinity, CSS */
|
|
929
|
-
|
|
930
1330
|
function flatten(obj, prefix) {
|
|
931
1331
|
return Object.keys(obj).reduce((acc, k) => {
|
|
932
1332
|
const pre = prefix.length ? prefix + '.' : '';
|
|
@@ -1050,7 +1450,7 @@ var ful = (function (exports) {
|
|
|
1050
1450
|
}
|
|
1051
1451
|
get values() {
|
|
1052
1452
|
return Array.from(this.querySelectorAll('[name]'))
|
|
1053
|
-
.filter(
|
|
1453
|
+
.filter(el => {
|
|
1054
1454
|
if (el.dataset['fulBindInclude'] === 'never') {
|
|
1055
1455
|
return false;
|
|
1056
1456
|
}
|
|
@@ -1061,14 +1461,14 @@ var ful = (function (exports) {
|
|
|
1061
1461
|
}, {});
|
|
1062
1462
|
}
|
|
1063
1463
|
set errors(es) {
|
|
1064
|
-
const fieldErrors = es.filter(
|
|
1065
|
-
const globalErrors = es.filter(
|
|
1464
|
+
const fieldErrors = es.filter(e => e.type === 'FIELD_ERROR' || e.type === 'INVALID_FORMAT');
|
|
1465
|
+
const globalErrors = es.filter(e => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');
|
|
1066
1466
|
this.querySelectorAll(`.${Form.INVALID_CLASS}`).forEach(el => el.classList.remove(Form.INVALID_CLASS));
|
|
1067
1467
|
this.querySelectorAll("ful-errors").forEach(el => {
|
|
1068
1468
|
el.replaceChildren();
|
|
1069
1469
|
el.setAttribute('hidden', '');
|
|
1070
1470
|
});
|
|
1071
|
-
fieldErrors.forEach(
|
|
1471
|
+
fieldErrors.forEach(e => {
|
|
1072
1472
|
const name = e.context.replace("[", ".").replace("].", ".");
|
|
1073
1473
|
const validationTargetsSelector = `[name='${CSS.escape(name)}'] [ful-validation-target],[name='${CSS.escape(name)}']:not(:has([ful-validation-target]))`;
|
|
1074
1474
|
this.querySelectorAll(validationTargetsSelector).forEach(input => input.classList.add(Form.INVALID_CLASS));
|
|
@@ -1084,7 +1484,7 @@ var ful = (function (exports) {
|
|
|
1084
1484
|
if (!this.hasAttribute('scroll-on-error')) {
|
|
1085
1485
|
return;
|
|
1086
1486
|
}
|
|
1087
|
-
const ys = Array.from(this.querySelectorAll(`[ful-validated-field]:has(.${Form.INVALID_CLASS}) ful-field-error`))
|
|
1487
|
+
const ys = Array.from(this.querySelectorAll(`ful-errors:not([hidden]), [ful-validated-field]:has(.${Form.INVALID_CLASS}) ful-field-error`))
|
|
1088
1488
|
.map(el => el.parentElement ? el.parentElement : el)
|
|
1089
1489
|
.map(el => el.getBoundingClientRect().y + window.scrollY);
|
|
1090
1490
|
const miny = Math.min(...ys);
|
|
@@ -1139,6 +1539,7 @@ var ful = (function (exports) {
|
|
|
1139
1539
|
slots: true,
|
|
1140
1540
|
template: INPUT_TEMPLATE
|
|
1141
1541
|
}){
|
|
1542
|
+
input;
|
|
1142
1543
|
render(template, slots) {
|
|
1143
1544
|
const fragment = makeInputFragment(this, template, slots);
|
|
1144
1545
|
this.replaceChildren(fragment);
|
|
@@ -1309,27 +1710,40 @@ var ful = (function (exports) {
|
|
|
1309
1710
|
input.addEventListener('change', evt => {
|
|
1310
1711
|
evt.stopPropagation();
|
|
1311
1712
|
//change is not cancelable
|
|
1312
|
-
this.dispatchEvent(new CustomEvent('change', {
|
|
1313
|
-
bubbles: true,
|
|
1314
|
-
cancelable: false,
|
|
1713
|
+
this.dispatchEvent(new CustomEvent('change', {
|
|
1714
|
+
bubbles: true,
|
|
1715
|
+
cancelable: false,
|
|
1315
1716
|
detail: {
|
|
1316
1717
|
value: this.value
|
|
1317
1718
|
}
|
|
1318
|
-
}));
|
|
1319
|
-
});
|
|
1719
|
+
}));
|
|
1720
|
+
});
|
|
1320
1721
|
const label = Fragments.fromChildNodes(el);
|
|
1321
1722
|
return [input, label];
|
|
1322
1723
|
});
|
|
1323
1724
|
|
|
1324
1725
|
radioEls.forEach(el => el.remove());
|
|
1325
|
-
template.renderTo(this, {name, slots, inputsAndLabels});
|
|
1726
|
+
template.renderTo(this, { name, slots, inputsAndLabels });
|
|
1326
1727
|
}
|
|
1327
1728
|
get value() {
|
|
1729
|
+
/** @type {HTMLInputElement|null} */
|
|
1328
1730
|
const checked = this.querySelector('input[type=radio]:checked');
|
|
1329
1731
|
return checked ? checked.value : null;
|
|
1330
1732
|
}
|
|
1331
1733
|
set value(value) {
|
|
1332
|
-
|
|
1734
|
+
if (value === null) {
|
|
1735
|
+
/** @type {HTMLInputElement[]} */
|
|
1736
|
+
this.querySelectorAll(`input[type=radio]`).forEach(el => {
|
|
1737
|
+
// @ts-ignore
|
|
1738
|
+
el.checked = false;
|
|
1739
|
+
});
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
/** @type {HTMLInputElement|null} */
|
|
1743
|
+
const el = this.querySelector(`input[type=radio][value=${CSS.escape(value)}]`);
|
|
1744
|
+
if (el) {
|
|
1745
|
+
el.checked = true;
|
|
1746
|
+
}
|
|
1333
1747
|
}
|
|
1334
1748
|
}
|
|
1335
1749
|
|
|
@@ -1359,6 +1773,7 @@ var ful = (function (exports) {
|
|
|
1359
1773
|
exports.Fragments = Fragments;
|
|
1360
1774
|
exports.Hex = Hex;
|
|
1361
1775
|
exports.HttpClient = HttpClient;
|
|
1776
|
+
exports.HttpClientError = HttpClientError;
|
|
1362
1777
|
exports.INPUT_TEMPLATE = INPUT_TEMPLATE;
|
|
1363
1778
|
exports.Input = Input;
|
|
1364
1779
|
exports.LightSlots = LightSlots;
|
|
@@ -1372,15 +1787,9 @@ var ful = (function (exports) {
|
|
|
1372
1787
|
exports.TemplatesRegistry = TemplatesRegistry;
|
|
1373
1788
|
exports.VersionedStorage = VersionedStorage;
|
|
1374
1789
|
exports.elements = elements;
|
|
1375
|
-
exports.jsonPatch = jsonPatch;
|
|
1376
|
-
exports.jsonPost = jsonPost;
|
|
1377
|
-
exports.jsonPut = jsonPut;
|
|
1378
|
-
exports.jsonRequest = jsonRequest;
|
|
1379
1790
|
exports.makeInputFragment = makeInputFragment;
|
|
1380
1791
|
exports.timing = timing;
|
|
1381
1792
|
|
|
1382
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1383
|
-
|
|
1384
1793
|
return exports;
|
|
1385
1794
|
|
|
1386
1795
|
})({});
|