@muze-nl/jsfs-solid 0.1.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.
@@ -0,0 +1,3039 @@
1
+ (() => {
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+
8
+ // node_modules/@muze-nl/jsfs/src/Path.js
9
+ var Path = class _Path {
10
+ #value;
11
+ constructor(path) {
12
+ this.#value = _Path.collapse(path);
13
+ }
14
+ get value() {
15
+ return this.#value;
16
+ }
17
+ toString() {
18
+ return this.#value;
19
+ }
20
+ get length() {
21
+ return this.#value.length;
22
+ }
23
+ static collapse(path, cwd = "") {
24
+ if (path instanceof _Path) {
25
+ return path.value;
26
+ }
27
+ if (typeof path !== "string") {
28
+ throw new TypeError("path argument must be a string or an instance of Path");
29
+ }
30
+ if (cwd && !(cwd instanceof _Path)) {
31
+ cwd = new _Path(cwd);
32
+ }
33
+ path = path.trim();
34
+ if (path.length === 0) {
35
+ return cwd.value;
36
+ }
37
+ if (_Path.isRelative(path)) {
38
+ path = cwd + path;
39
+ }
40
+ let pathnames = _Path.reduce(path, (result3, entry) => {
41
+ if (entry == "..") {
42
+ result3.pop();
43
+ } else if (entry !== ".") {
44
+ result3.push(entry);
45
+ }
46
+ return result3;
47
+ }, []);
48
+ let result2 = "/";
49
+ if (pathnames.length) {
50
+ result2 += pathnames.join("/");
51
+ if (_Path.isFolder(path)) {
52
+ result2 += "/";
53
+ }
54
+ }
55
+ return result2;
56
+ }
57
+ static isAbsolute(path) {
58
+ if (path instanceof _Path) {
59
+ return true;
60
+ }
61
+ return path.length && path[0] === "/";
62
+ }
63
+ static isRelative(path) {
64
+ return !_Path.isAbsolute(path);
65
+ }
66
+ static isFolder(path) {
67
+ if (path instanceof _Path) {
68
+ path = path.value;
69
+ }
70
+ return path.length && path[path.length - 1] == "/";
71
+ }
72
+ static isPath(path) {
73
+ if (path instanceof _Path) {
74
+ return true;
75
+ }
76
+ if (typeof path !== "string") {
77
+ return false;
78
+ }
79
+ path = path.trim();
80
+ let u = new URL(path, document.location);
81
+ return u.pathname == path;
82
+ }
83
+ static reduce(path, reducer, initial) {
84
+ if (path instanceof _Path) {
85
+ path = path.value;
86
+ }
87
+ return path.split("/").filter(Boolean).reduce(reducer, initial);
88
+ }
89
+ static map(path, callback) {
90
+ if (path instanceof _Path) {
91
+ path = path.value;
92
+ }
93
+ return path.split("/").filter(Boolean).map(callback);
94
+ }
95
+ static parent(path) {
96
+ if (path instanceof _Path) {
97
+ path = path.value;
98
+ }
99
+ path = path.split("/").filter(Boolean);
100
+ path.pop();
101
+ let result2 = "/";
102
+ if (path.length) {
103
+ result2 += path.join("/") + "/";
104
+ }
105
+ return result2;
106
+ }
107
+ static filename(path) {
108
+ if (path instanceof _Path) {
109
+ path = path.value;
110
+ }
111
+ return path.split("/").filter(Boolean).pop();
112
+ }
113
+ static head(path) {
114
+ if (path instanceof _Path) {
115
+ path = path.value;
116
+ }
117
+ return path.split("/").filter(Boolean).shift();
118
+ }
119
+ static tail(path) {
120
+ if (path instanceof _Path) {
121
+ path = path.value;
122
+ }
123
+ path = path.split("/").filter(Boolean);
124
+ path.shift();
125
+ let result2 = "/";
126
+ if (path.length) {
127
+ result2 += path.join("/") + "/";
128
+ }
129
+ return result2;
130
+ }
131
+ };
132
+
133
+ // node_modules/@muze-nl/jsfs/src/Adapters/HttpAdapter.js
134
+ var HttpAdapter = class _HttpAdapter {
135
+ #baseUrl;
136
+ #path;
137
+ #exceptionHandler;
138
+ #fetchParams;
139
+ constructor(baseUrl, path = "/", exceptionHandler = null, fetchParams = {}) {
140
+ this.#baseUrl = new URL(baseUrl, window.location.href);
141
+ this.#path = new Path(path);
142
+ this.#exceptionHandler = exceptionHandler;
143
+ this.#fetchParams = fetchParams;
144
+ }
145
+ get name() {
146
+ return "HttpAdapter";
147
+ }
148
+ get path() {
149
+ return this.#path;
150
+ }
151
+ supportsWrite() {
152
+ return true;
153
+ }
154
+ supportsStreamingWrite() {
155
+ return supportsRequestStreams;
156
+ }
157
+ supportsStreamingRead() {
158
+ return true;
159
+ }
160
+ cd(path) {
161
+ if (!Path.isPath(path)) {
162
+ throw new TypeError(path + " is not a valid path");
163
+ }
164
+ return new _HttpAdapter(this.#baseUrl.href, path);
165
+ }
166
+ //FIXME: return a jsfs result object instead of http response
167
+ async write(path, contents, metadata = null) {
168
+ let params2 = Object.assign({}, this.#fetchParams, {
169
+ method: "PUT",
170
+ body: contents
171
+ });
172
+ return this.#fetch(path, params2);
173
+ }
174
+ writeStream(path, writer, metadata = null) {
175
+ throw new Error("Not yet implemented");
176
+ }
177
+ async read(path) {
178
+ let params2 = Object.assign({}, this.#fetchParams, {
179
+ method: "GET"
180
+ });
181
+ let response2 = await this.#fetch(path, params2);
182
+ let result2 = {
183
+ type: this.#getMimetype(response2),
184
+ name: Path.filename(path),
185
+ http: {
186
+ headers: response2.headers,
187
+ status: response2.status,
188
+ url: response2.url
189
+ }
190
+ };
191
+ if (result2.type.match(/text\/.*/)) {
192
+ result2.contents = await response2.text();
193
+ } else if (result2.type.match(/application\/json.*/)) {
194
+ result2.contents = await response2.json();
195
+ } else {
196
+ result2.contents = await response2.blob();
197
+ }
198
+ return result2;
199
+ }
200
+ readStream(path, reader) {
201
+ throw new Error("Not yet implemented");
202
+ }
203
+ async exists(path) {
204
+ let params2 = Object.assign({}, this.#fetchParams, {
205
+ method: "HEAD"
206
+ });
207
+ return this.#fetch(path, params2);
208
+ }
209
+ async delete(path) {
210
+ let params2 = Object.assign({}, this.#fetchParams, {
211
+ method: "DELETE"
212
+ });
213
+ return this.#fetch(path, params2);
214
+ }
215
+ async list(path) {
216
+ let supportedContentTypes = [
217
+ "text/html",
218
+ "text/xhtml",
219
+ "text/xhtml+xml",
220
+ "text/xml"
221
+ ];
222
+ let result2 = await this.read(path);
223
+ if (supportedContentTypes.includes(result2.type.split(";")[0])) {
224
+ var html = result2.contents;
225
+ } else {
226
+ let url3 = this.#getUrl(path);
227
+ throw new TypeError("URL " + url3 + " is not of a supported content type", {
228
+ cause: result2
229
+ });
230
+ }
231
+ let basePath = Path.collapse(this.#baseUrl.pathname);
232
+ let parentUrl = this.#getUrl(path);
233
+ let dom = document.createElement("template");
234
+ dom.innerHTML = html;
235
+ let links = dom.content.querySelectorAll("a[href]");
236
+ return Array.from(links).map((link) => {
237
+ let url3 = new URL(link.getAttribute("href"), parentUrl.href);
238
+ link.href = url3.href;
239
+ return {
240
+ filename: Path.filename(link.pathname),
241
+ path: link.pathname,
242
+ name: link.innerText,
243
+ href: link.href
244
+ };
245
+ }).filter((link) => {
246
+ let testURL = new URL(link.href);
247
+ testURL.pathname = Path.parent(testURL.pathname);
248
+ return testURL.href === parentUrl.href;
249
+ }).map((link) => {
250
+ return {
251
+ filename: link.filename,
252
+ path: link.path.substring(basePath.length - 1),
253
+ //TODO: Path.collapse() now always adds a trailing '/', so this works, but the added trailing / is probably not correct
254
+ name: link.name
255
+ };
256
+ });
257
+ }
258
+ #getUrl(path) {
259
+ path = Path.collapse(this.#baseUrl.pathname + Path.collapse(path));
260
+ return new URL(path, this.#baseUrl);
261
+ }
262
+ async #fetch(path, options) {
263
+ return fetch(this.#getUrl(path), options).catch((e) => {
264
+ if (!this.#exceptionHandler || !this.#exceptionHandler(url, options, e)) {
265
+ throw e;
266
+ }
267
+ });
268
+ }
269
+ #getMimetype(response2) {
270
+ if (response2.headers.has("Content-Type")) {
271
+ return response2.headers.get("Content-Type");
272
+ } else {
273
+ return null;
274
+ }
275
+ }
276
+ };
277
+ var supportsRequestStreams = (async () => {
278
+ const supportsStreamsInRequestObjects = !new Request(
279
+ "",
280
+ {
281
+ body: new ReadableStream(),
282
+ method: "POST",
283
+ duplex: "half"
284
+ // required in chrome
285
+ }
286
+ ).headers.has("Content-Type");
287
+ if (!supportsStreamsInRequestObjects) {
288
+ return false;
289
+ }
290
+ return fetch(
291
+ "data:a/a;charset=utf-8,",
292
+ {
293
+ method: "POST",
294
+ body: new ReadableStream(),
295
+ duplex: "half"
296
+ }
297
+ ).then(() => true, () => false);
298
+ })();
299
+
300
+ // node_modules/@muze-nl/metro/src/metro.mjs
301
+ var metro_exports = {};
302
+ __export(metro_exports, {
303
+ Client: () => Client,
304
+ client: () => client,
305
+ deepClone: () => deepClone,
306
+ formdata: () => formdata,
307
+ metroError: () => metroError,
308
+ request: () => request,
309
+ response: () => response,
310
+ trace: () => trace,
311
+ url: () => url2
312
+ });
313
+ var metroURL = "https://metro.muze.nl/details/";
314
+ if (!Symbol.metroProxy) {
315
+ Symbol.metroProxy = Symbol("isProxy");
316
+ }
317
+ if (!Symbol.metroSource) {
318
+ Symbol.metroSource = Symbol("source");
319
+ }
320
+ var Client = class _Client {
321
+ clientOptions = {
322
+ url: typeof window != "undefined" ? url2(window.location) : url2("https://localhost"),
323
+ verbs: ["get", "post", "put", "delete", "patch", "head", "options", "query"]
324
+ };
325
+ static tracers = {};
326
+ /**
327
+ * @typedef {Object} ClientOptions
328
+ * @property {Array} middlewares - list of middleware functions
329
+ * @property {string|URL} url - default url of the client
330
+ * @property {[string]} verbs - a list of verb methods to expose, e.g. ['get','post']
331
+ *
332
+ * Constructs a new metro client. Can have any number of params.
333
+ * @params {ClientOptions|URL|Function|Client}
334
+ * @returns {Client} - A metro client object with given or default verb methods
335
+ */
336
+ constructor(...options) {
337
+ for (let option of options) {
338
+ if (typeof option == "string" || option instanceof String) {
339
+ this.clientOptions.url = url2(this.clientOptions.url.href, option);
340
+ } else if (option instanceof Function) {
341
+ this.#addMiddlewares([option]);
342
+ } else if (option && typeof option == "object") {
343
+ for (let param in option) {
344
+ if (param == "middlewares") {
345
+ this.#addMiddlewares(option[param]);
346
+ } else if (param == "url") {
347
+ this.clientOptions.url = url2(this.clientOptions.url.href, option[param]);
348
+ } else if (typeof option[param] == "function") {
349
+ this.clientOptions[param] = option[param](this.clientOptions[param], this.clientOptions);
350
+ } else {
351
+ this.clientOptions[param] = option[param];
352
+ }
353
+ }
354
+ }
355
+ }
356
+ for (const verb of this.clientOptions.verbs) {
357
+ this[verb] = async function(...options2) {
358
+ return this.fetch(request(
359
+ this.clientOptions,
360
+ ...options2,
361
+ { method: verb.toUpperCase() }
362
+ ));
363
+ };
364
+ }
365
+ }
366
+ #addMiddlewares(middlewares) {
367
+ if (typeof middlewares == "function") {
368
+ middlewares = [middlewares];
369
+ }
370
+ let index = middlewares.findIndex((m) => typeof m != "function");
371
+ if (index >= 0) {
372
+ throw metroError("metro.client: middlewares must be a function or an array of functions " + metroURL + "client/invalid-middlewares/", middlewares[index]);
373
+ }
374
+ if (!Array.isArray(this.clientOptions.middlewares)) {
375
+ this.clientOptions.middlewares = [];
376
+ }
377
+ this.clientOptions.middlewares = this.clientOptions.middlewares.concat(middlewares);
378
+ }
379
+ /**
380
+ * Mimics the standard browser fetch method, but uses any middleware installed through
381
+ * the constructor.
382
+ * @param {Request|string|Object} - Required. The URL or Request object, accepts all types that are accepted by metro.request
383
+ * @param {Object} - Optional. Any object that is accepted by metro.request
384
+ * @return {Promise<Response|*>} - The metro.response to this request, or any other result as changed by any included middleware.
385
+ */
386
+ fetch(req, options) {
387
+ req = request(req, options);
388
+ if (!req.url) {
389
+ throw metroError("metro.client." + req.method.toLowerCase() + ": Missing url parameter " + metroURL + "client/fetch-missing-url/", req);
390
+ }
391
+ if (!options) {
392
+ options = {};
393
+ }
394
+ if (!(typeof options === "object") || options instanceof String) {
395
+ throw metroError("metro.client.fetch: Invalid options parameter " + metroURL + "client/fetch-invalid-options/", options);
396
+ }
397
+ const metrofetch = async function browserFetch(req2) {
398
+ if (req2[Symbol.metroProxy]) {
399
+ req2 = req2[Symbol.metroSource];
400
+ }
401
+ const res = await fetch(req2);
402
+ return response(res);
403
+ };
404
+ let middlewares = [metrofetch].concat(this.clientOptions?.middlewares?.slice() || []);
405
+ options = Object.assign({}, this.clientOptions, options);
406
+ let next;
407
+ for (let middleware of middlewares) {
408
+ next = /* @__PURE__ */ (function(next2, middleware2) {
409
+ return async function(req2) {
410
+ let res;
411
+ let tracers = Object.values(_Client.tracers);
412
+ for (let tracer of tracers) {
413
+ if (tracer.request) {
414
+ tracer.request.call(tracer, req2, middleware2);
415
+ }
416
+ }
417
+ res = await middleware2(req2, next2);
418
+ for (let tracer of tracers) {
419
+ if (tracer.response) {
420
+ tracer.response.call(tracer, res, middleware2);
421
+ }
422
+ }
423
+ return res;
424
+ };
425
+ })(next, middleware);
426
+ }
427
+ return next(req);
428
+ }
429
+ with(...options) {
430
+ return new _Client(deepClone(this.clientOptions), ...options);
431
+ }
432
+ get location() {
433
+ return this.clientOptions.url;
434
+ }
435
+ };
436
+ function client(...options) {
437
+ return new Client(...deepClone(options));
438
+ }
439
+ function getRequestParams(req, current) {
440
+ let params2 = current || {};
441
+ if (!params2.url && current.url) {
442
+ params2.url = current.url;
443
+ }
444
+ for (let prop of [
445
+ "method",
446
+ "headers",
447
+ "body",
448
+ "mode",
449
+ "credentials",
450
+ "cache",
451
+ "redirect",
452
+ "referrer",
453
+ "referrerPolicy",
454
+ "integrity",
455
+ "keepalive",
456
+ "signal",
457
+ "priority",
458
+ "url"
459
+ ]) {
460
+ let value = req[prop];
461
+ if (typeof value == "undefined" || value == null) {
462
+ continue;
463
+ }
464
+ if (value?.[Symbol.metroProxy]) {
465
+ value = value[Symbol.metroSource];
466
+ }
467
+ if (typeof value == "function") {
468
+ params2[prop] = value(params2[prop], params2);
469
+ } else {
470
+ if (prop == "url") {
471
+ params2.url = url2(params2.url, value);
472
+ } else if (prop == "headers") {
473
+ params2.headers = new Headers(current.headers);
474
+ if (!(value instanceof Headers)) {
475
+ value = new Headers(req.headers);
476
+ }
477
+ for (let [key, val] of value.entries()) {
478
+ params2.headers.set(key, val);
479
+ }
480
+ } else {
481
+ params2[prop] = value;
482
+ }
483
+ }
484
+ }
485
+ if (req instanceof Request && req.data) {
486
+ params2.body = req.data;
487
+ }
488
+ return params2;
489
+ }
490
+ function request(...options) {
491
+ let requestParams = {
492
+ url: typeof window != "undefined" ? url2(window.location) : url2("https://localhost/"),
493
+ duplex: "half"
494
+ // required when setting body to ReadableStream, just set it here by default already
495
+ };
496
+ for (let option of options) {
497
+ if (typeof option == "string" || option instanceof URL || option instanceof URLSearchParams) {
498
+ requestParams.url = url2(requestParams.url, option);
499
+ } else if (option && (option instanceof FormData || option instanceof ReadableStream || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView)) {
500
+ requestParams.body = option;
501
+ } else if (option && typeof option == "object") {
502
+ Object.assign(requestParams, getRequestParams(option, requestParams));
503
+ }
504
+ }
505
+ let r = new Request(requestParams.url, requestParams);
506
+ let data = requestParams.body;
507
+ if (data) {
508
+ if (typeof data == "object" && !(data instanceof String) && !(data instanceof ReadableStream) && !(data instanceof Blob) && !(data instanceof ArrayBuffer) && !(data instanceof DataView) && !(data instanceof FormData) && !(data instanceof URLSearchParams) && (typeof globalThis.TypedArray == "undefined" || !(data instanceof globalThis.TypedArray))) {
509
+ if (typeof data.toString == "function") {
510
+ requestParams.body = data.toString({ headers: r.headers });
511
+ r = new Request(requestParams.url, requestParams);
512
+ }
513
+ }
514
+ }
515
+ Object.freeze(r);
516
+ return new Proxy(r, {
517
+ get(target, prop) {
518
+ let result2;
519
+ switch (prop) {
520
+ case Symbol.metroSource:
521
+ result2 = target;
522
+ break;
523
+ case Symbol.metroProxy:
524
+ result2 = true;
525
+ break;
526
+ case "with":
527
+ result2 = function(...options2) {
528
+ if (data) {
529
+ options2.unshift({ body: data });
530
+ }
531
+ return request(target, ...options2);
532
+ };
533
+ break;
534
+ case "data":
535
+ result2 = data;
536
+ break;
537
+ default:
538
+ if (target[prop] instanceof Function) {
539
+ if (prop === "clone") {
540
+ }
541
+ result2 = target[prop].bind(target);
542
+ } else {
543
+ result2 = target[prop];
544
+ }
545
+ break;
546
+ }
547
+ return result2;
548
+ }
549
+ });
550
+ }
551
+ function getResponseParams(res, current) {
552
+ let params2 = current || {};
553
+ if (!params2.url && current.url) {
554
+ params2.url = current.url;
555
+ }
556
+ for (let prop of ["status", "statusText", "headers", "body", "url", "type", "redirected"]) {
557
+ let value = res[prop];
558
+ if (typeof value == "undefined" || value == null) {
559
+ continue;
560
+ }
561
+ if (value?.[Symbol.metroProxy]) {
562
+ value = value[Symbol.metroSource];
563
+ }
564
+ if (typeof value == "function") {
565
+ params2[prop] = value(params2[prop], params2);
566
+ } else {
567
+ if (prop == "url") {
568
+ params2.url = new URL(value, params2.url || "https://localhost/");
569
+ } else {
570
+ params2[prop] = value;
571
+ }
572
+ }
573
+ }
574
+ if (res instanceof Response && res.data) {
575
+ params2.body = res.data;
576
+ }
577
+ return params2;
578
+ }
579
+ function response(...options) {
580
+ let responseParams = {};
581
+ for (let option of options) {
582
+ if (typeof option == "string") {
583
+ responseParams.body = option;
584
+ } else if (option instanceof Response) {
585
+ Object.assign(responseParams, getResponseParams(option, responseParams));
586
+ } else if (option && typeof option == "object") {
587
+ if (option instanceof FormData || option instanceof Blob || option instanceof ArrayBuffer || option instanceof DataView || option instanceof ReadableStream || option instanceof URLSearchParams || option instanceof String || typeof globalThis.TypedArray != "undefined" && option instanceof globalThis.TypedArray) {
588
+ responseParams.body = option;
589
+ } else {
590
+ Object.assign(responseParams, getResponseParams(option, responseParams));
591
+ }
592
+ }
593
+ }
594
+ let data = void 0;
595
+ if (responseParams.body) {
596
+ data = responseParams.body;
597
+ }
598
+ if ([101, 204, 205, 304].includes(responseParams.status)) {
599
+ responseParams.body = null;
600
+ }
601
+ let r = new Response(responseParams.body, responseParams);
602
+ Object.freeze(r);
603
+ return new Proxy(r, {
604
+ get(target, prop) {
605
+ let result2;
606
+ switch (prop) {
607
+ case Symbol.metroProxy:
608
+ result2 = true;
609
+ break;
610
+ case Symbol.metroSource:
611
+ result2 = target;
612
+ break;
613
+ case "with":
614
+ result2 = function(...options2) {
615
+ return response(target, ...options2);
616
+ };
617
+ break;
618
+ case "data":
619
+ result2 = data;
620
+ break;
621
+ case "ok":
622
+ result2 = target.status >= 200 && target.status < 400;
623
+ break;
624
+ default:
625
+ if (typeof target[prop] == "function") {
626
+ result2 = target[prop].bind(target);
627
+ } else {
628
+ result2 = target[prop];
629
+ }
630
+ break;
631
+ }
632
+ return result2;
633
+ }
634
+ });
635
+ }
636
+ function appendSearchParams(url3, params2) {
637
+ if (typeof params2 == "function") {
638
+ params2(url3.searchParams, url3);
639
+ } else {
640
+ params2 = new URLSearchParams(params2);
641
+ params2.forEach((value, key) => {
642
+ url3.searchParams.append(key, value);
643
+ });
644
+ }
645
+ }
646
+ function url2(...options) {
647
+ let validParams = [
648
+ "hash",
649
+ "host",
650
+ "hostname",
651
+ "href",
652
+ "password",
653
+ "pathname",
654
+ "port",
655
+ "protocol",
656
+ "username",
657
+ "search",
658
+ "searchParams"
659
+ ];
660
+ let u = new URL("https://localhost/");
661
+ for (let option of options) {
662
+ if (typeof option == "string" || option instanceof String) {
663
+ u = new URL(option, u);
664
+ } else if (option instanceof URL || typeof Location != "undefined" && option instanceof Location) {
665
+ u = new URL(option);
666
+ } else if (option instanceof URLSearchParams) {
667
+ appendSearchParams(u, option);
668
+ } else if (option && typeof option == "object") {
669
+ for (let param in option) {
670
+ switch (param) {
671
+ case "search":
672
+ if (typeof option.search == "function") {
673
+ option.search(u.search, u);
674
+ } else {
675
+ u.search = new URLSearchParams(option.search);
676
+ }
677
+ break;
678
+ case "searchParams":
679
+ appendSearchParams(u, option.searchParams);
680
+ break;
681
+ default:
682
+ if (!validParams.includes(param)) {
683
+ throw metroError("metro.url: unknown url parameter " + metroURL + "url/unknown-param-name/", param);
684
+ }
685
+ if (typeof option[param] == "function") {
686
+ option[param](u[param], u);
687
+ } else if (typeof option[param] == "string" || option[param] instanceof String || typeof option[param] == "number" || option[param] instanceof Number || typeof option[param] == "boolean" || option[param] instanceof Boolean) {
688
+ u[param] = "" + option[param];
689
+ } else if (typeof option[param] == "object" && option[param].toString) {
690
+ u[param] = option[param].toString();
691
+ } else {
692
+ throw metroError("metro.url: unsupported value for " + param + " " + metroURL + "url/unsupported-param-value/", options[param]);
693
+ }
694
+ break;
695
+ }
696
+ }
697
+ } else {
698
+ throw metroError("metro.url: unsupported option value " + metroURL + "url/unsupported-option-value/", option);
699
+ }
700
+ }
701
+ Object.freeze(u);
702
+ return new Proxy(u, {
703
+ get(target, prop) {
704
+ let result2;
705
+ switch (prop) {
706
+ case Symbol.metroProxy:
707
+ result2 = true;
708
+ break;
709
+ case Symbol.metroSource:
710
+ result2 = target;
711
+ break;
712
+ case "with":
713
+ result2 = function(...options2) {
714
+ return url2(target, ...options2);
715
+ };
716
+ break;
717
+ case "filename":
718
+ result2 = target.pathname.split("/").pop();
719
+ break;
720
+ case "folderpath":
721
+ result2 = target.pathname.substring(0, target.pathname.lastIndexOf("\\") + 1);
722
+ break;
723
+ case "authority":
724
+ result2 = target.username ?? "";
725
+ result2 += target.password ? ":" + target.password : "";
726
+ result2 += result2 ? "@" : "";
727
+ result2 += target.hostname;
728
+ result2 += target.port ? ":" + target.port : "";
729
+ result2 += "/";
730
+ result2 = target.protocol + "//" + result2;
731
+ break;
732
+ case "origin":
733
+ result2 = target.protocol + "//" + target.hostname;
734
+ result2 += target.port ? ":" + target.port : "";
735
+ result2 += "/";
736
+ break;
737
+ case "fragment":
738
+ result2 = target.hash.substring(1);
739
+ break;
740
+ case "scheme":
741
+ if (target.protocol) {
742
+ result2 = target.protocol.substring(0, target.protocol.length - 1);
743
+ } else {
744
+ result2 = "";
745
+ }
746
+ break;
747
+ default:
748
+ if (target[prop] instanceof Function) {
749
+ result2 = target[prop].bind(target);
750
+ } else {
751
+ result2 = target[prop];
752
+ }
753
+ break;
754
+ }
755
+ return result2;
756
+ }
757
+ });
758
+ }
759
+ function formdata(...options) {
760
+ var params2 = new FormData();
761
+ for (let option of options) {
762
+ if (option instanceof HTMLFormElement) {
763
+ option = new FormData(option);
764
+ }
765
+ if (option instanceof FormData) {
766
+ for (let entry of option.entries()) {
767
+ params2.append(entry[0], entry[1]);
768
+ }
769
+ } else if (option && typeof option == "object") {
770
+ for (let entry of Object.entries(option)) {
771
+ if (Array.isArray(entry[1])) {
772
+ for (let value of entry[1]) {
773
+ params2.append(entry[0], value);
774
+ }
775
+ } else {
776
+ params2.append(entry[0], entry[1]);
777
+ }
778
+ }
779
+ } else {
780
+ throw new metroError("metro.formdata: unknown option type " + metroURL + "formdata/unknown-option-value/", option);
781
+ }
782
+ }
783
+ Object.freeze(params2);
784
+ return new Proxy(params2, {
785
+ get(target, prop) {
786
+ let result2;
787
+ switch (prop) {
788
+ case Symbol.metroProxy:
789
+ result2 = true;
790
+ break;
791
+ case Symbol.metroSource:
792
+ result2 = target;
793
+ break;
794
+ //TODO: add toString() that can check
795
+ //headers param: toString({headers:request.headers})
796
+ //for the content-type
797
+ case "with":
798
+ result2 = function(...options2) {
799
+ return formdata(target, ...options2);
800
+ };
801
+ break;
802
+ default:
803
+ if (target[prop] instanceof Function) {
804
+ result2 = target[prop].bind(target);
805
+ } else {
806
+ result2 = target[prop];
807
+ }
808
+ break;
809
+ }
810
+ return result2;
811
+ }
812
+ });
813
+ }
814
+ var metroConsole = {
815
+ error: (message, ...details) => {
816
+ console.error("\u24C2\uFE0F ", message, ...details);
817
+ },
818
+ info: (message, ...details) => {
819
+ console.info("\u24C2\uFE0F ", message, ...details);
820
+ },
821
+ group: (name) => {
822
+ console.group("\u24C2\uFE0F " + name);
823
+ },
824
+ groupEnd: (name) => {
825
+ console.groupEnd("\u24C2\uFE0F " + name);
826
+ }
827
+ };
828
+ function metroError(message, ...details) {
829
+ metroConsole.error(message, ...details);
830
+ return new Error(message, ...details);
831
+ }
832
+ var trace = {
833
+ /**
834
+ * Adds a named tracer function
835
+ * @param {string} name - the name of the tracer
836
+ * @param {Function} tracer - the tracer function to call
837
+ */
838
+ add(name, tracer) {
839
+ Client.tracers[name] = tracer;
840
+ },
841
+ /**
842
+ * Removes a named tracer function
843
+ * @param {string} name
844
+ */
845
+ delete(name) {
846
+ delete Client.tracers[name];
847
+ },
848
+ /**
849
+ * Removes all tracer functions
850
+ */
851
+ clear() {
852
+ Client.tracers = {};
853
+ },
854
+ /**
855
+ * Returns a set of request and response tracer functions that use the
856
+ * console.group feature to shows nested request/response pairs, with
857
+ * most commonly needed information for debugging
858
+ */
859
+ group() {
860
+ let group = 0;
861
+ return {
862
+ request: (req, middleware) => {
863
+ group++;
864
+ metroConsole.group(group);
865
+ metroConsole.info(req?.url, req, middleware);
866
+ },
867
+ response: (res, middleware) => {
868
+ metroConsole.info(res?.body ? res.body[Symbol.metroSource] : null, res, middleware);
869
+ metroConsole.groupEnd(group);
870
+ group--;
871
+ }
872
+ };
873
+ }
874
+ };
875
+ function deepClone(object) {
876
+ if (Array.isArray(object)) {
877
+ return object.slice().map(deepClone);
878
+ }
879
+ if (object && typeof object === "object") {
880
+ if (object.__proto__.constructor == Object || !object.__proto__) {
881
+ let result2 = Object.assign({}, object);
882
+ Object.keys(result2).forEach((key) => {
883
+ result2[key] = deepClone(object[key]);
884
+ });
885
+ return result2;
886
+ } else {
887
+ return object;
888
+ }
889
+ }
890
+ return object;
891
+ }
892
+
893
+ // node_modules/@muze-nl/metro/src/mw/getdata.mjs
894
+ function getdatamw() {
895
+ return async function getdata(req, next) {
896
+ let res = await next(req);
897
+ if (res.ok && res.data) {
898
+ return res.data;
899
+ }
900
+ return res;
901
+ };
902
+ }
903
+
904
+ // node_modules/@muze-nl/metro/src/mw/json.mjs
905
+ function jsonmw(options) {
906
+ options = Object.assign({
907
+ contentType: "application/json",
908
+ reviver: null,
909
+ replacer: null,
910
+ space: ""
911
+ }, options);
912
+ return async function json(req, next) {
913
+ if (!req.headers.get("Accept")) {
914
+ req = req.with({
915
+ headers: {
916
+ "Accept": options.accept ?? options.contentType
917
+ }
918
+ });
919
+ }
920
+ if (req.method !== "GET" && req.method !== "HEAD") {
921
+ if (req.data && typeof req.data == "object" && !(req.data instanceof ReadableStream)) {
922
+ const contentType = req.headers.get("Content-Type");
923
+ if (!contentType || isPlainText2(contentType)) {
924
+ req = req.with({
925
+ headers: {
926
+ "Content-Type": options.contentType
927
+ }
928
+ });
929
+ }
930
+ if (isJSON(req.headers.get("Content-Type"))) {
931
+ req = req.with({
932
+ body: JSON.stringify(req.data, options.replacer, options.space)
933
+ });
934
+ }
935
+ }
936
+ }
937
+ let res = await next(req);
938
+ if (isJSON(res.headers.get("Content-Type"))) {
939
+ let tempRes = res.clone();
940
+ let body = await tempRes.text();
941
+ try {
942
+ let json2 = JSON.parse(body, options.reviver);
943
+ return res.with({
944
+ body: json2
945
+ });
946
+ } catch (e) {
947
+ }
948
+ }
949
+ return res;
950
+ };
951
+ }
952
+ var jsonRE = /^application\/([a-zA-Z0-9\-_]+\+)?json\b/;
953
+ function isJSON(contentType) {
954
+ return jsonRE.exec(contentType);
955
+ }
956
+ function isPlainText2(contentType) {
957
+ return /^text\/plain\b/.exec(contentType);
958
+ }
959
+
960
+ // node_modules/@muze-nl/metro/src/mw/thrower.mjs
961
+ function throwermw(options) {
962
+ return async function thrower(req, next) {
963
+ let res = await next(req);
964
+ if (!res.ok) {
965
+ if (options && typeof options[res.status] == "function") {
966
+ res = options[res.status].apply(res, req);
967
+ } else {
968
+ throw new Error(res.status + ": " + res.statusText, {
969
+ cause: res
970
+ });
971
+ }
972
+ }
973
+ return res;
974
+ };
975
+ }
976
+
977
+ // node_modules/@muze-nl/metro/src/api.mjs
978
+ var API = class extends Client {
979
+ constructor(base, methods, bind = null) {
980
+ if (base instanceof Client) {
981
+ super(base.clientOptions, throwermw(), getdatamw());
982
+ } else {
983
+ super(base, throwermw(), getdatamw());
984
+ }
985
+ if (!bind) {
986
+ bind = this;
987
+ }
988
+ for (const methodName in methods) {
989
+ if (typeof methods[methodName] == "function") {
990
+ this[methodName] = methods[methodName].bind(bind);
991
+ } else if (methods[methodName] && typeof methods[methodName] == "object") {
992
+ this[methodName] = new this.constructor(base, methods[methodName], bind);
993
+ } else {
994
+ this[methodName] = methods[methodName];
995
+ }
996
+ }
997
+ }
998
+ };
999
+ var JsonAPI = class extends API {
1000
+ constructor(base, methods, bind = null) {
1001
+ if (base instanceof Client) {
1002
+ super(base.with(jsonmw()), methods, bind);
1003
+ } else {
1004
+ super(client(base, jsonmw()), methods, bind);
1005
+ }
1006
+ }
1007
+ };
1008
+ function api(...options) {
1009
+ return new API(...deepClone(options));
1010
+ }
1011
+ function jsonApi(...options) {
1012
+ return new JsonAPI(...deepClone(options));
1013
+ }
1014
+
1015
+ // node_modules/@muze-nl/metro/src/everything.mjs
1016
+ var metro2 = Object.assign({}, metro_exports, {
1017
+ mw: {
1018
+ jsonmw,
1019
+ thrower: throwermw
1020
+ },
1021
+ api,
1022
+ jsonApi
1023
+ });
1024
+ if (!globalThis.metro) {
1025
+ globalThis.metro = metro2;
1026
+ }
1027
+ var everything_default = metro2;
1028
+
1029
+ // node_modules/@muze-nl/assert/src/assert.mjs
1030
+ globalThis.assertEnabled = false;
1031
+ function assert(source, test) {
1032
+ if (globalThis.assertEnabled) {
1033
+ let problems = fails(source, test);
1034
+ if (problems) {
1035
+ console.error("\u{1F170}\uFE0F Assertions failed because of:", problems, "in this source:", source);
1036
+ throw new Error("Assertions failed", {
1037
+ cause: { problems, source }
1038
+ });
1039
+ }
1040
+ }
1041
+ }
1042
+ function Optional(pattern) {
1043
+ return function _Optional(data, root, path) {
1044
+ if (typeof data != "undefined" && data != null && typeof pattern != "undefined") {
1045
+ return fails(data, pattern, root, path);
1046
+ }
1047
+ };
1048
+ }
1049
+ function Required(pattern) {
1050
+ return function _Required(data, root, path) {
1051
+ if (data == null || typeof data == "undefined") {
1052
+ return error("data is required", data, pattern || "any value", path);
1053
+ } else if (typeof pattern != "undefined") {
1054
+ return fails(data, pattern, root, path);
1055
+ } else {
1056
+ return false;
1057
+ }
1058
+ };
1059
+ }
1060
+ function Recommended(pattern) {
1061
+ return function _Recommended(data, root, path) {
1062
+ if (data == null || typeof data == "undefined") {
1063
+ warn("data does not contain recommended value", data, pattern, path);
1064
+ return false;
1065
+ } else {
1066
+ return fails(data, pattern, root, path);
1067
+ }
1068
+ };
1069
+ }
1070
+ function oneOf(...patterns) {
1071
+ return function _oneOf(data, root, path) {
1072
+ for (let pattern of patterns) {
1073
+ if (!fails(data, pattern, root, path)) {
1074
+ return false;
1075
+ }
1076
+ }
1077
+ return error("data does not match oneOf patterns", data, patterns, path);
1078
+ };
1079
+ }
1080
+ function anyOf(...patterns) {
1081
+ return function _anyOf(data, root, path) {
1082
+ if (!Array.isArray(data)) {
1083
+ return error("data is not an array", data, "anyOf", path);
1084
+ }
1085
+ for (let value of data) {
1086
+ if (oneOf(...patterns)(value)) {
1087
+ return error("data does not match anyOf patterns", value, patterns, path);
1088
+ }
1089
+ }
1090
+ return false;
1091
+ };
1092
+ }
1093
+ function allOf(...patterns) {
1094
+ return function _allOf(data, root, path) {
1095
+ let problems = [];
1096
+ for (let pattern of patterns) {
1097
+ problems = problems.concat(fails(data, pattern, root, path));
1098
+ }
1099
+ problems = problems.filter(Boolean);
1100
+ if (problems.length) {
1101
+ return error("data does not match all given patterns", data, patterns, path, problems);
1102
+ }
1103
+ };
1104
+ }
1105
+ function validURL(data, root, path) {
1106
+ try {
1107
+ if (data instanceof URL) {
1108
+ data = data.href;
1109
+ }
1110
+ let url3 = new URL(data);
1111
+ if (url3.href != data) {
1112
+ if (!(url3.href + "/" == data || url3.href == data + "/")) {
1113
+ return error("data is not a valid url", data, "validURL", path);
1114
+ }
1115
+ }
1116
+ } catch (e) {
1117
+ return error("data is not a valid url", data, "validURL", path);
1118
+ }
1119
+ }
1120
+ function validEmail(data, root, path) {
1121
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
1122
+ return error("data is not a valid email", data, "validEmail", path);
1123
+ }
1124
+ }
1125
+ function instanceOf(constructor) {
1126
+ return function _instanceOf(data, root, path) {
1127
+ if (!(data instanceof constructor)) {
1128
+ return error("data is not an instanceof pattern", data, constructor, path);
1129
+ }
1130
+ };
1131
+ }
1132
+ function not(pattern) {
1133
+ return function _not(data, root, path) {
1134
+ if (!fails(data, pattern, root, path)) {
1135
+ return error("data matches pattern, when required not to", data, pattern, path);
1136
+ }
1137
+ };
1138
+ }
1139
+ function fails(data, pattern, root, path = "") {
1140
+ if (!root) {
1141
+ root = data;
1142
+ }
1143
+ let problems = [];
1144
+ if (pattern === Boolean) {
1145
+ if (typeof data != "boolean" && !(data instanceof Boolean)) {
1146
+ problems.push(error("data is not a boolean", data, pattern, path));
1147
+ }
1148
+ } else if (pattern === Number) {
1149
+ if (typeof data != "number" && !(data instanceof Number)) {
1150
+ problems.push(error("data is not a number", data, pattern, path));
1151
+ }
1152
+ } else if (pattern === String) {
1153
+ if (typeof data != "string" && !(data instanceof String)) {
1154
+ problems.push(error("data is not a string", data, pattern, path));
1155
+ }
1156
+ if (data == "") {
1157
+ problems.push(error("data is an empty string, which is not allowed", data, pattern, path));
1158
+ }
1159
+ } else if (pattern instanceof RegExp) {
1160
+ if (Array.isArray(data)) {
1161
+ let index = data.findIndex((element, index2) => fails(element, pattern, root, path + "[" + index2 + "]"));
1162
+ if (index > -1) {
1163
+ problems.push(error("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
1164
+ }
1165
+ } else if (typeof data == "undefined") {
1166
+ problems.push(error("data is undefined, should match pattern", data, pattern, path));
1167
+ } else if (!pattern.test(data)) {
1168
+ problems.push(error("data does not match pattern", data, pattern, path));
1169
+ }
1170
+ } else if (pattern instanceof Function) {
1171
+ let problem = pattern(data, root, path);
1172
+ if (problem) {
1173
+ if (Array.isArray(problem)) {
1174
+ problems = problems.concat(problem);
1175
+ } else {
1176
+ problems.push(problem);
1177
+ }
1178
+ }
1179
+ } else if (Array.isArray(pattern)) {
1180
+ if (!Array.isArray(data)) {
1181
+ problems.push(error("data is not an array", data, [], path));
1182
+ }
1183
+ for (let p of pattern) {
1184
+ for (let index of data.keys()) {
1185
+ let problem = fails(data[index], p, root, path + "[" + index + "]");
1186
+ if (Array.isArray(problem)) {
1187
+ problems = problems.concat(problem);
1188
+ } else if (problem) {
1189
+ problems.push(problem);
1190
+ }
1191
+ }
1192
+ }
1193
+ } else if (pattern && typeof pattern == "object") {
1194
+ if (Array.isArray(data)) {
1195
+ let index = data.findIndex((element, index2) => fails(element, pattern, root, path + "[" + index2 + "]"));
1196
+ if (index > -1) {
1197
+ problems.push(error("data[" + index + "] does not match pattern", data[index], pattern, path + "[" + index + "]"));
1198
+ }
1199
+ } else if (!data || typeof data != "object") {
1200
+ problems.push(error("data is not an object, pattern is", data, pattern, path));
1201
+ } else {
1202
+ if (data instanceof URLSearchParams) {
1203
+ data = Object.fromEntries(data);
1204
+ }
1205
+ if (pattern instanceof Function) {
1206
+ let result2 = fails(data, pattern, root, path);
1207
+ if (result2) {
1208
+ problems = problems.concat(result2);
1209
+ }
1210
+ } else {
1211
+ for (const [patternKey, subpattern] of Object.entries(pattern)) {
1212
+ let result2 = fails(data[patternKey], subpattern, root, path + "." + patternKey);
1213
+ if (result2) {
1214
+ problems = problems.concat(result2);
1215
+ }
1216
+ }
1217
+ }
1218
+ }
1219
+ } else {
1220
+ if (pattern != data) {
1221
+ problems.push(error("data and pattern are not equal", data, pattern, path));
1222
+ }
1223
+ }
1224
+ if (problems.length) {
1225
+ return problems;
1226
+ }
1227
+ return false;
1228
+ }
1229
+ function error(message, found, expected, path, problems) {
1230
+ let result2 = {
1231
+ path,
1232
+ message,
1233
+ found,
1234
+ expected
1235
+ };
1236
+ if (problems) {
1237
+ result2.problems = problems;
1238
+ }
1239
+ return result2;
1240
+ }
1241
+ function warn(message, data, pattern, path) {
1242
+ console.warn("\u{1F170}\uFE0F Assert: " + path, message, pattern, data);
1243
+ }
1244
+
1245
+ // node_modules/@muze-nl/metro-oauth2/src/tokenstore.mjs
1246
+ function tokenStore(site) {
1247
+ let localState, localTokens;
1248
+ if (typeof localStorage !== "undefined") {
1249
+ localState = {
1250
+ get: () => localStorage.getItem("metro/state:" + site),
1251
+ set: (value) => localStorage.setItem("metro/state:" + site, value),
1252
+ has: () => localStorage.getItem("metro/state:" + site) !== null,
1253
+ delete: () => localStorage.remoteItem("metro/state:" + site)
1254
+ };
1255
+ localTokens = {
1256
+ get: (name) => JSON.parse(localStorage.getItem(site + ":" + name)),
1257
+ set: (name, value) => localStorage.setItem(site + ":" + name, JSON.stringify(value)),
1258
+ has: (name) => localStorage.getItem(site + ":" + name) !== null,
1259
+ delete: (name) => localStorage.removeItem(site + ":" + name)
1260
+ };
1261
+ } else {
1262
+ let stateMap = /* @__PURE__ */ new Map();
1263
+ localState = {
1264
+ get: () => stateMap.get("metro/state:" + site),
1265
+ set: (value) => stateMap.set("metro/state:" + site, value),
1266
+ has: () => stateMap.has("metro/state:" + site),
1267
+ delete: () => stateMap.delete("metro/state:" + site)
1268
+ };
1269
+ localTokens = /* @__PURE__ */ new Map();
1270
+ }
1271
+ return {
1272
+ state: localState,
1273
+ tokens: localTokens
1274
+ };
1275
+ }
1276
+
1277
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.mjs
1278
+ function oauth2mw(options) {
1279
+ const defaultOptions = {
1280
+ client: client(),
1281
+ force_authorization: false,
1282
+ site: "default",
1283
+ oauth2_configuration: {
1284
+ authorization_endpoint: "/authorize",
1285
+ token_endpoint: "/token",
1286
+ redirect_uri: globalThis.document?.location.href,
1287
+ grant_type: "authorization_code",
1288
+ code_verifier: generateCodeVerifier(64)
1289
+ },
1290
+ authorize_callback: async (url3) => {
1291
+ if (window.location.href != url3.href) {
1292
+ window.location.replace(url3.href);
1293
+ }
1294
+ return false;
1295
+ }
1296
+ };
1297
+ assert(options, {});
1298
+ const oauth2 = Object.assign({}, defaultOptions.oauth2_configuration, options?.oauth2_configuration);
1299
+ options = Object.assign({}, defaultOptions, options);
1300
+ options.oauth2_configuration = oauth2;
1301
+ const store = tokenStore(options.site);
1302
+ if (!options.tokens) {
1303
+ options.tokens = store.tokens;
1304
+ }
1305
+ if (!options.state) {
1306
+ options.state = store.state;
1307
+ }
1308
+ assert(options, {
1309
+ oauth2_configuration: {
1310
+ client_id: Required(/.+/),
1311
+ grant_type: "authorization_code",
1312
+ authorization_endpoint: Required(validURL),
1313
+ token_endpoint: Required(validURL),
1314
+ redirect_uri: Required(validURL)
1315
+ }
1316
+ });
1317
+ for (let option in oauth2) {
1318
+ switch (option) {
1319
+ case "access_token":
1320
+ case "authorization_code":
1321
+ case "refresh_token":
1322
+ options.tokens.set(option, oauth2[option]);
1323
+ break;
1324
+ }
1325
+ }
1326
+ return async function(req, next) {
1327
+ if (options.force_authorization) {
1328
+ return oauth2authorized(req, next);
1329
+ }
1330
+ let res;
1331
+ try {
1332
+ res = await next(req);
1333
+ if (res.ok) {
1334
+ return res;
1335
+ }
1336
+ } catch (err) {
1337
+ switch (res?.status) {
1338
+ case 400:
1339
+ // Oauth2.1 RFC 3.2.4
1340
+ case 401:
1341
+ return oauth2authorized(req, next);
1342
+ break;
1343
+ }
1344
+ throw err;
1345
+ }
1346
+ if (!res.ok) {
1347
+ switch (res.status) {
1348
+ case 400:
1349
+ // Oauth2.1 RFC 3.2.4
1350
+ case 401:
1351
+ return oauth2authorized(req, next);
1352
+ break;
1353
+ }
1354
+ }
1355
+ return res;
1356
+ };
1357
+ async function oauth2authorized(req, next) {
1358
+ getTokensFromLocation();
1359
+ const accessToken = options.tokens.get("access_token");
1360
+ const refreshToken = options.tokens.get("refresh_token");
1361
+ const tokenIsExpired = isExpired(accessToken);
1362
+ if (!accessToken || tokenIsExpired && !refreshToken) {
1363
+ try {
1364
+ let token = await fetchAccessToken();
1365
+ if (!token) {
1366
+ return response("false");
1367
+ }
1368
+ } catch (e) {
1369
+ throw e;
1370
+ }
1371
+ return oauth2authorized(req, next);
1372
+ } else if (tokenIsExpired && refreshToken) {
1373
+ try {
1374
+ let token = await refreshAccessToken();
1375
+ if (!token) {
1376
+ return response("false");
1377
+ }
1378
+ } catch (e) {
1379
+ throw e;
1380
+ }
1381
+ return oauth2authorized(req, next);
1382
+ } else {
1383
+ req = request(req, {
1384
+ headers: {
1385
+ Authorization: accessToken.type + " " + accessToken.value
1386
+ }
1387
+ });
1388
+ return next(req);
1389
+ }
1390
+ }
1391
+ function getTokensFromLocation() {
1392
+ if (typeof window !== "undefined" && window?.location) {
1393
+ let url3 = url2(window.location);
1394
+ let code, state, params2;
1395
+ if (url3.searchParams.has("code")) {
1396
+ params2 = url3.searchParams;
1397
+ url3 = url3.with({ search: "" });
1398
+ history.pushState({}, "", url3.href);
1399
+ } else if (url3.hash) {
1400
+ let query = url3.hash.substr(1);
1401
+ params2 = new URLSearchParams("?" + query);
1402
+ url3 = url3.with({ hash: "" });
1403
+ history.pushState({}, "", url3.href);
1404
+ }
1405
+ if (params2) {
1406
+ code = params2.get("code");
1407
+ state = params2.get("state");
1408
+ let storedState = options.state.get("metro/state");
1409
+ if (!state || state !== storedState) {
1410
+ return;
1411
+ }
1412
+ if (code) {
1413
+ options.tokens.set("authorization_code", code);
1414
+ }
1415
+ }
1416
+ }
1417
+ }
1418
+ async function fetchAccessToken() {
1419
+ if (oauth2.grant_type === "authorization_code" && !options.tokens.has("authorization_code")) {
1420
+ let authReqURL = await getAuthorizationCodeURL();
1421
+ if (!options.authorize_callback || typeof options.authorize_callback !== "function") {
1422
+ throw metroError("oauth2mw: oauth2 with grant_type:authorization_code requires a callback function in client options.authorize_callback");
1423
+ }
1424
+ let token = await options.authorize_callback(authReqURL);
1425
+ if (token) {
1426
+ options.tokens.set("authorization_code", token);
1427
+ } else {
1428
+ return false;
1429
+ }
1430
+ }
1431
+ let tokenReq = getAccessTokenRequest();
1432
+ let response2 = await options.client.post(tokenReq);
1433
+ if (!response2.ok) {
1434
+ let msg = await response2.text();
1435
+ throw metroError("OAuth2mw: fetch access_token: " + response2.status + ": " + response2.statusText, { cause: tokenReq });
1436
+ }
1437
+ let data = await response2.json();
1438
+ options.tokens.set("access_token", {
1439
+ value: data.access_token,
1440
+ expires: getExpires(data.expires_in),
1441
+ type: data.token_type,
1442
+ scope: data.scope
1443
+ });
1444
+ if (data.refresh_token) {
1445
+ let token = {
1446
+ value: data.refresh_token
1447
+ };
1448
+ options.tokens.set("refresh_token", token);
1449
+ }
1450
+ options.tokens.delete("authorization_code");
1451
+ return data;
1452
+ }
1453
+ async function refreshAccessToken() {
1454
+ let refreshTokenReq = getAccessTokenRequest("refresh_token");
1455
+ let response2 = await options.client.post(refreshTokenReq);
1456
+ if (!response2.ok) {
1457
+ throw metroError("OAuth2mw: refresh access_token: " + response2.status + ": " + response2.statusText, { cause: refreshTokenReq });
1458
+ }
1459
+ let data = await response2.json();
1460
+ options.tokens.set("access_token", {
1461
+ value: data.access_token,
1462
+ expires: getExpires(data.expires_in),
1463
+ type: data.token_type,
1464
+ scope: data.scope
1465
+ });
1466
+ if (data.refresh_token) {
1467
+ let token = {
1468
+ value: data.refresh_token
1469
+ };
1470
+ options.tokens.set("refresh_token", token);
1471
+ } else {
1472
+ return false;
1473
+ }
1474
+ return data;
1475
+ }
1476
+ async function getAuthorizationCodeURL() {
1477
+ if (!oauth2.authorization_endpoint) {
1478
+ throw metroError("oauth2mw: Missing options.oauth2_configuration.authorization_endpoint");
1479
+ }
1480
+ let url3 = url2(oauth2.authorization_endpoint, { hash: "" });
1481
+ assert(oauth2, {
1482
+ client_id: /.+/,
1483
+ redirect_uri: /.+/,
1484
+ scope: /.*/
1485
+ });
1486
+ let search = {
1487
+ response_type: "code",
1488
+ // implicit flow uses 'token' here, but is not considered safe, so not supported
1489
+ client_id: oauth2.client_id,
1490
+ redirect_uri: oauth2.redirect_uri,
1491
+ state: oauth2.state || createState(40)
1492
+ // OAuth2.1 RFC says optional, but its a good idea to always add/check it
1493
+ };
1494
+ if (oauth2.response_type) {
1495
+ search.response_type = oauth2.response_type;
1496
+ }
1497
+ if (oauth2.response_mode) {
1498
+ search.response_mode = oauth2.response_mode;
1499
+ }
1500
+ options.state.set(search.state);
1501
+ if (oauth2.client_secret) {
1502
+ search.client_secret = oauth2.client_secret;
1503
+ }
1504
+ if (oauth2.code_verifier) {
1505
+ options.tokens.set("code_verifier", oauth2.code_verifier);
1506
+ search.code_challenge = await generateCodeChallenge(oauth2.code_verifier);
1507
+ search.code_challenge_method = "S256";
1508
+ }
1509
+ if (oauth2.scope) {
1510
+ search.scope = oauth2.scope;
1511
+ }
1512
+ if (oauth2.prompt) {
1513
+ search.prompt = oauth2.prompt;
1514
+ }
1515
+ return url2(url3, { search });
1516
+ }
1517
+ function getAccessTokenRequest(grant_type = null) {
1518
+ assert(oauth2, {
1519
+ client_id: /.+/,
1520
+ redirect_uri: /.+/
1521
+ });
1522
+ if (!oauth2.token_endpoint) {
1523
+ throw metroError("oauth2mw: Missing options.endpoints.token url");
1524
+ }
1525
+ let url3 = url2(oauth2.token_endpoint, { hash: "" });
1526
+ let params2 = {
1527
+ grant_type: grant_type || oauth2.grant_type,
1528
+ client_id: oauth2.client_id
1529
+ };
1530
+ if (oauth2.client_secret) {
1531
+ params2.client_secret = oauth2.client_secret;
1532
+ }
1533
+ if (oauth2.scope) {
1534
+ params2.scope = oauth2.scope;
1535
+ }
1536
+ switch (params2.grant_type) {
1537
+ case "authorization_code":
1538
+ params2.redirect_uri = oauth2.redirect_uri;
1539
+ params2.code = options.tokens.get("authorization_code");
1540
+ const code_verifier = options.tokens.get("code_verifier");
1541
+ if (code_verifier) {
1542
+ params2.code_verifier = code_verifier;
1543
+ }
1544
+ break;
1545
+ case "client_credentials":
1546
+ break;
1547
+ case "refresh_token":
1548
+ const refreshToken = options.tokens.get("refresh_token");
1549
+ params2.refresh_token = refreshToken.value;
1550
+ break;
1551
+ default:
1552
+ throw new Error("Unknown grant_type: ".oauth2.grant_type);
1553
+ break;
1554
+ }
1555
+ return request(url3, { method: "POST", body: new URLSearchParams(params2) });
1556
+ }
1557
+ }
1558
+ function isExpired(token) {
1559
+ if (!token) {
1560
+ return true;
1561
+ }
1562
+ let expires = new Date(token.expires);
1563
+ let now = /* @__PURE__ */ new Date();
1564
+ return now.getTime() > expires.getTime();
1565
+ }
1566
+ function getExpires(duration) {
1567
+ if (duration instanceof Date) {
1568
+ return new Date(duration.getTime());
1569
+ }
1570
+ if (typeof duration === "number") {
1571
+ let date = /* @__PURE__ */ new Date();
1572
+ date.setSeconds(date.getSeconds() + duration);
1573
+ return date;
1574
+ }
1575
+ throw new TypeError("Unknown expires type " + duration);
1576
+ }
1577
+ function generateCodeVerifier(size = 64) {
1578
+ const code_verifier = new Uint8Array(size);
1579
+ globalThis.crypto.getRandomValues(code_verifier);
1580
+ return base64url_encode(code_verifier);
1581
+ }
1582
+ async function generateCodeChallenge(code_verifier) {
1583
+ const encoder2 = new TextEncoder();
1584
+ const data = encoder2.encode(code_verifier);
1585
+ const challenge = await globalThis.crypto.subtle.digest("SHA-256", data);
1586
+ return base64url_encode(challenge);
1587
+ }
1588
+ function base64url_encode(buffer) {
1589
+ const byteString = Array.from(new Uint8Array(buffer), (b) => String.fromCharCode(b)).join("");
1590
+ return btoa(byteString).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
1591
+ }
1592
+ function createState(length) {
1593
+ const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1594
+ let randomState = "";
1595
+ let counter = 0;
1596
+ while (counter < length) {
1597
+ randomState += validChars.charAt(Math.floor(Math.random() * validChars.length));
1598
+ counter++;
1599
+ }
1600
+ return randomState;
1601
+ }
1602
+ function isRedirected() {
1603
+ let url3 = new URL(document.location.href);
1604
+ if (!url3.searchParams.has("code")) {
1605
+ if (url3.hash) {
1606
+ let query = url3.hash.substr(1);
1607
+ params = new URLSearchParams("?" + query);
1608
+ if (params.has("code")) {
1609
+ return true;
1610
+ }
1611
+ }
1612
+ return false;
1613
+ }
1614
+ return true;
1615
+ }
1616
+
1617
+ // node_modules/@muze-nl/metro-oauth2/src/keysstore.mjs
1618
+ function keysStore() {
1619
+ return new Promise((resolve, reject) => {
1620
+ const request2 = globalThis.indexedDB.open("metro", 1);
1621
+ request2.onupgradeneeded = () => request2.result.createObjectStore("keyPairs", { keyPath: "domain" });
1622
+ request2.onerror = (event) => {
1623
+ reject(event);
1624
+ };
1625
+ request2.onsuccess = (event) => {
1626
+ const db = event.target.result;
1627
+ resolve({
1628
+ set: function(value, key) {
1629
+ return new Promise((resolve2, reject2) => {
1630
+ const tx = db.transaction("keyPairs", "readwrite", { durability: "strict" });
1631
+ const objectStore = tx.objectStore("keyPairs");
1632
+ tx.oncomplete = () => {
1633
+ resolve2();
1634
+ };
1635
+ tx.onerror = reject2;
1636
+ objectStore.put(value, key);
1637
+ });
1638
+ },
1639
+ get: function(key) {
1640
+ return new Promise((resolve2, reject2) => {
1641
+ const tx = db.transaction("keyPairs", "readonly");
1642
+ const objectStore = tx.objectStore("keyPairs");
1643
+ const request3 = objectStore.get(key);
1644
+ request3.onsuccess = () => {
1645
+ resolve2(request3.result);
1646
+ };
1647
+ request3.onerror = reject2;
1648
+ tx.onerror = reject2;
1649
+ });
1650
+ },
1651
+ clear: function() {
1652
+ return new Promise((resolve2, reject2) => {
1653
+ const tx = db.transaction("keyPairs", "readwrite");
1654
+ const objectStore = tx.objectStore("keyPairs");
1655
+ const request3 = objectStore.clear();
1656
+ request3.onsuccess = () => {
1657
+ resolve2();
1658
+ };
1659
+ request3.onerror = reject2;
1660
+ tx.onerror = reject2;
1661
+ });
1662
+ }
1663
+ });
1664
+ };
1665
+ });
1666
+ }
1667
+
1668
+ // node_modules/dpop/build/index.js
1669
+ var encoder = new TextEncoder();
1670
+ var decoder = new TextDecoder();
1671
+ function buf(input) {
1672
+ if (typeof input === "string") {
1673
+ return encoder.encode(input);
1674
+ }
1675
+ return decoder.decode(input);
1676
+ }
1677
+ function checkRsaKeyAlgorithm(algorithm) {
1678
+ if (typeof algorithm.modulusLength !== "number" || algorithm.modulusLength < 2048) {
1679
+ throw new OperationProcessingError(`${algorithm.name} modulusLength must be at least 2048 bits`);
1680
+ }
1681
+ }
1682
+ function subtleAlgorithm(key) {
1683
+ switch (key.algorithm.name) {
1684
+ case "ECDSA":
1685
+ return { name: key.algorithm.name, hash: "SHA-256" };
1686
+ case "RSA-PSS":
1687
+ checkRsaKeyAlgorithm(key.algorithm);
1688
+ return {
1689
+ name: key.algorithm.name,
1690
+ saltLength: 256 >> 3
1691
+ };
1692
+ case "RSASSA-PKCS1-v1_5":
1693
+ checkRsaKeyAlgorithm(key.algorithm);
1694
+ return { name: key.algorithm.name };
1695
+ case "Ed25519":
1696
+ return { name: key.algorithm.name };
1697
+ }
1698
+ throw new UnsupportedOperationError();
1699
+ }
1700
+ async function jwt(header, claimsSet, key) {
1701
+ if (key.usages.includes("sign") === false) {
1702
+ throw new TypeError('private CryptoKey instances used for signing assertions must include "sign" in their "usages"');
1703
+ }
1704
+ const input = `${b64u(buf(JSON.stringify(header)))}.${b64u(buf(JSON.stringify(claimsSet)))}`;
1705
+ const signature = b64u(await crypto.subtle.sign(subtleAlgorithm(key), key, buf(input)));
1706
+ return `${input}.${signature}`;
1707
+ }
1708
+ var CHUNK_SIZE = 32768;
1709
+ function encodeBase64Url(input) {
1710
+ if (input instanceof ArrayBuffer) {
1711
+ input = new Uint8Array(input);
1712
+ }
1713
+ const arr = [];
1714
+ for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {
1715
+ arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
1716
+ }
1717
+ return btoa(arr.join("")).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1718
+ }
1719
+ function b64u(input) {
1720
+ return encodeBase64Url(input);
1721
+ }
1722
+ function randomBytes() {
1723
+ return b64u(crypto.getRandomValues(new Uint8Array(32)));
1724
+ }
1725
+ var UnsupportedOperationError = class extends Error {
1726
+ constructor(message) {
1727
+ super(message ?? "operation not supported");
1728
+ this.name = this.constructor.name;
1729
+ Error.captureStackTrace?.(this, this.constructor);
1730
+ }
1731
+ };
1732
+ var OperationProcessingError = class extends Error {
1733
+ constructor(message) {
1734
+ super(message);
1735
+ this.name = this.constructor.name;
1736
+ Error.captureStackTrace?.(this, this.constructor);
1737
+ }
1738
+ };
1739
+ function psAlg(key) {
1740
+ switch (key.algorithm.hash.name) {
1741
+ case "SHA-256":
1742
+ return "PS256";
1743
+ default:
1744
+ throw new UnsupportedOperationError("unsupported RsaHashedKeyAlgorithm hash name");
1745
+ }
1746
+ }
1747
+ function rsAlg(key) {
1748
+ switch (key.algorithm.hash.name) {
1749
+ case "SHA-256":
1750
+ return "RS256";
1751
+ default:
1752
+ throw new UnsupportedOperationError("unsupported RsaHashedKeyAlgorithm hash name");
1753
+ }
1754
+ }
1755
+ function esAlg(key) {
1756
+ switch (key.algorithm.namedCurve) {
1757
+ case "P-256":
1758
+ return "ES256";
1759
+ default:
1760
+ throw new UnsupportedOperationError("unsupported EcKeyAlgorithm namedCurve");
1761
+ }
1762
+ }
1763
+ function determineJWSAlgorithm(key) {
1764
+ switch (key.algorithm.name) {
1765
+ case "RSA-PSS":
1766
+ return psAlg(key);
1767
+ case "RSASSA-PKCS1-v1_5":
1768
+ return rsAlg(key);
1769
+ case "ECDSA":
1770
+ return esAlg(key);
1771
+ case "Ed25519":
1772
+ return "EdDSA";
1773
+ default:
1774
+ throw new UnsupportedOperationError("unsupported CryptoKey algorithm name");
1775
+ }
1776
+ }
1777
+ function isCryptoKey(key) {
1778
+ return key instanceof CryptoKey;
1779
+ }
1780
+ function isPrivateKey(key) {
1781
+ return isCryptoKey(key) && key.type === "private";
1782
+ }
1783
+ function isPublicKey(key) {
1784
+ return isCryptoKey(key) && key.type === "public";
1785
+ }
1786
+ function epochTime() {
1787
+ return Math.floor(Date.now() / 1e3);
1788
+ }
1789
+ async function DPoP(keypair, htu, htm, nonce, accessToken, additional) {
1790
+ const privateKey = keypair?.privateKey;
1791
+ const publicKey = keypair?.publicKey;
1792
+ if (!isPrivateKey(privateKey)) {
1793
+ throw new TypeError('"keypair.privateKey" must be a private CryptoKey');
1794
+ }
1795
+ if (!isPublicKey(publicKey)) {
1796
+ throw new TypeError('"keypair.publicKey" must be a public CryptoKey');
1797
+ }
1798
+ if (publicKey.extractable !== true) {
1799
+ throw new TypeError('"keypair.publicKey.extractable" must be true');
1800
+ }
1801
+ if (typeof htu !== "string") {
1802
+ throw new TypeError('"htu" must be a string');
1803
+ }
1804
+ if (typeof htm !== "string") {
1805
+ throw new TypeError('"htm" must be a string');
1806
+ }
1807
+ if (nonce !== void 0 && typeof nonce !== "string") {
1808
+ throw new TypeError('"nonce" must be a string or undefined');
1809
+ }
1810
+ if (accessToken !== void 0 && typeof accessToken !== "string") {
1811
+ throw new TypeError('"accessToken" must be a string or undefined');
1812
+ }
1813
+ if (additional !== void 0 && (typeof additional !== "object" || additional === null || Array.isArray(additional))) {
1814
+ throw new TypeError('"additional" must be an object');
1815
+ }
1816
+ return jwt({
1817
+ alg: determineJWSAlgorithm(privateKey),
1818
+ typ: "dpop+jwt",
1819
+ jwk: await publicJwk(publicKey)
1820
+ }, {
1821
+ ...additional,
1822
+ iat: epochTime(),
1823
+ jti: randomBytes(),
1824
+ htm,
1825
+ nonce,
1826
+ htu,
1827
+ ath: accessToken ? b64u(await crypto.subtle.digest("SHA-256", buf(accessToken))) : void 0
1828
+ }, privateKey);
1829
+ }
1830
+ async function publicJwk(key) {
1831
+ const { kty, e, n, x, y, crv } = await crypto.subtle.exportKey("jwk", key);
1832
+ return { kty, crv, e, n, x, y };
1833
+ }
1834
+ async function generateKeyPair(alg, options) {
1835
+ let algorithm;
1836
+ if (typeof alg !== "string" || alg.length === 0) {
1837
+ throw new TypeError('"alg" must be a non-empty string');
1838
+ }
1839
+ switch (alg) {
1840
+ case "PS256":
1841
+ algorithm = {
1842
+ name: "RSA-PSS",
1843
+ hash: "SHA-256",
1844
+ modulusLength: options?.modulusLength ?? 2048,
1845
+ publicExponent: new Uint8Array([1, 0, 1])
1846
+ };
1847
+ break;
1848
+ case "RS256":
1849
+ algorithm = {
1850
+ name: "RSASSA-PKCS1-v1_5",
1851
+ hash: "SHA-256",
1852
+ modulusLength: options?.modulusLength ?? 2048,
1853
+ publicExponent: new Uint8Array([1, 0, 1])
1854
+ };
1855
+ break;
1856
+ case "ES256":
1857
+ algorithm = { name: "ECDSA", namedCurve: "P-256" };
1858
+ break;
1859
+ case "EdDSA":
1860
+ algorithm = { name: "Ed25519" };
1861
+ break;
1862
+ default:
1863
+ throw new UnsupportedOperationError();
1864
+ }
1865
+ return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ["sign", "verify"]);
1866
+ }
1867
+
1868
+ // node_modules/@muze-nl/metro-oauth2/src/oauth2.dpop.mjs
1869
+ function dpopmw(options) {
1870
+ assert(options, {
1871
+ site: Required(validURL),
1872
+ authorization_endpoint: Required(validURL),
1873
+ token_endpoint: Required(validURL),
1874
+ dpop_signing_alg_values_supported: Optional([])
1875
+ // this property is unfortunately rarely supported
1876
+ });
1877
+ return async (req, next) => {
1878
+ const keys = await keysStore();
1879
+ let keyInfo = await keys.get(options.site);
1880
+ if (!keyInfo) {
1881
+ let keyPair = await generateKeyPair("ES256");
1882
+ keyInfo = { domain: options.site, keyPair };
1883
+ await keys.set(keyInfo);
1884
+ }
1885
+ const url3 = everything_default.url(req.url);
1886
+ if (req.url.startsWith(options.authorization_endpoint)) {
1887
+ let params2 = req.body;
1888
+ if (params2 instanceof URLSearchParams || params2 instanceof FormData) {
1889
+ params2.set("dpop_jkt", keyInfo.keyPair.publicKey);
1890
+ } else {
1891
+ params2.dpop_jkt = keyInfo.keyPair.publicKey;
1892
+ }
1893
+ } else if (req.url.startsWith(options.token_endpoint)) {
1894
+ const dpopHeader = await DPoP(keyInfo.keyPair, req.url, req.method);
1895
+ req = req.with({
1896
+ headers: {
1897
+ "DPoP": dpopHeader
1898
+ }
1899
+ });
1900
+ } else if (req.headers.has("Authorization")) {
1901
+ const nonce = localStorage.getItem(url3.host + ":nonce") || void 0;
1902
+ const accessToken = req.headers.get("Authorization").split(" ")[1];
1903
+ const dpopHeader = await DPoP(keyInfo.keyPair, req.url, req.method, nonce, accessToken);
1904
+ req = req.with({
1905
+ headers: {
1906
+ "Authorization": "DPoP " + accessToken,
1907
+ "DPoP": dpopHeader
1908
+ }
1909
+ });
1910
+ }
1911
+ let response2 = await next(req);
1912
+ if (response2.headers.get("DPoP-Nonce")) {
1913
+ localStorage.setItem(url3.host + ":nonce", response2.headers.get("DPoP-Nonce"));
1914
+ }
1915
+ return response2;
1916
+ };
1917
+ }
1918
+
1919
+ // node_modules/@muze-nl/metro-oidc/src/oidc.util.mjs
1920
+ var MustHave = (...options) => (value, root) => {
1921
+ if (options.filter((o) => root.hasOwnKey(o)).length > 0) {
1922
+ return false;
1923
+ }
1924
+ return error("root data must have all of", root, options);
1925
+ };
1926
+ var MustInclude = (...options) => (value) => {
1927
+ if (Array.isArray(value) && options.filter((o) => !value.includes(o)).length == 0) {
1928
+ return false;
1929
+ } else {
1930
+ return error("data must be an array which includes", value, options);
1931
+ }
1932
+ };
1933
+ var validJWA = [
1934
+ "HS256",
1935
+ "HS384",
1936
+ "HS512",
1937
+ "RS256",
1938
+ "RS384",
1939
+ "RS512",
1940
+ "ES256",
1941
+ "ES384",
1942
+ "ES512"
1943
+ ];
1944
+ var validAuthMethods = [
1945
+ "client_secret_post",
1946
+ "client_secret_basic",
1947
+ "client_secret_jwt",
1948
+ "private_key_jwt"
1949
+ ];
1950
+
1951
+ // node_modules/@muze-nl/metro-oidc/src/oidc.discovery.mjs
1952
+ async function oidcDiscovery(options = {}) {
1953
+ assert(options, {
1954
+ client: Optional(instanceOf(everything_default.client().constructor)),
1955
+ issuer: Required(validURL)
1956
+ });
1957
+ const defaultOptions = {
1958
+ client: everything_default.client().with(throwermw()).with(jsonmw()),
1959
+ requireDynamicRegistration: false
1960
+ };
1961
+ options = Object.assign({}, defaultOptions, options);
1962
+ const TestSucceeded = false;
1963
+ function MustUseHTTPS(url3) {
1964
+ return TestSucceeded;
1965
+ }
1966
+ const openid_provider_metadata = {
1967
+ issuer: Required(allOf(options.issuer, MustUseHTTPS)),
1968
+ authorization_endpoint: Required(validURL),
1969
+ token_endpoint: Required(validURL),
1970
+ userinfo_endpoint: Recommended(validURL),
1971
+ // todo: test for https protocol
1972
+ jwks_uri: Required(validURL),
1973
+ registration_endpoint: options.requireDynamicRegistration ? Required(validURL) : Recommended(validURL),
1974
+ scopes_supported: Recommended(MustInclude("openid")),
1975
+ response_types_supported: options.requireDynamicRegistration ? Required(MustInclude("code", "id_token", "id_token token")) : Required([]),
1976
+ response_modes_supported: Optional([]),
1977
+ grant_types_supported: options.requireDynamicRegistration ? Optional(MustInclude("authorization_code")) : Optional([]),
1978
+ acr_values_supported: Optional([]),
1979
+ subject_types_supported: Required([]),
1980
+ id_token_signing_alg_values_supported: Required(MustInclude("RS256")),
1981
+ id_token_encryption_alg_values_supported: Optional([]),
1982
+ id_token_encryption_enc_values_supported: Optional([]),
1983
+ userinfo_signing_alg_values_supported: Optional([]),
1984
+ userinfo_encryption_alg_values_supported: Optional([]),
1985
+ userinfo_encryption_enc_values_supported: Optional([]),
1986
+ request_object_signing_alg_values_supported: Optional(MustInclude("RS256")),
1987
+ // not testing for 'none'
1988
+ request_object_encryption_alg_values_supported: Optional([]),
1989
+ request_object_encryption_enc_values_supported: Optional([]),
1990
+ token_endpoint_auth_methods_supported: Optional(anyOf(...validAuthMethods)),
1991
+ token_endpoint_auth_signing_alg_values_supported: Optional(MustInclude("RS256"), not(MustInclude("none"))),
1992
+ display_values_supported: Optional(anyOf("page", "popup", "touch", "wap")),
1993
+ claim_types_supported: Optional(anyOf("normal", "aggregated", "distributed")),
1994
+ claims_supported: Recommended([]),
1995
+ service_documentation: Optional(validURL),
1996
+ claims_locales_supported: Optional([]),
1997
+ ui_locales_supported: Optional([]),
1998
+ claims_parameter_supported: Optional(Boolean),
1999
+ request_parameter_supported: Optional(Boolean),
2000
+ request_uri_parameter_supported: Optional(Boolean),
2001
+ op_policy_uri: Optional(validURL),
2002
+ op_tos_uri: Optional(validURL)
2003
+ };
2004
+ const configURL = everything_default.url(options.issuer, ".well-known/openid-configuration");
2005
+ const response2 = await options.client.get(
2006
+ // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest
2007
+ // note: this allows path components in the options.issuer url
2008
+ configURL
2009
+ );
2010
+ const openid_config = response2.data;
2011
+ assert(openid_config, openid_provider_metadata);
2012
+ assert(openid_config.issuer, options.issuer);
2013
+ return openid_config;
2014
+ }
2015
+
2016
+ // node_modules/@muze-nl/metro-oidc/src/oidc.register.mjs
2017
+ async function register(options) {
2018
+ const openid_client_metadata = {
2019
+ redirect_uris: Required([validURL]),
2020
+ response_types: Optional([]),
2021
+ grant_types: Optional(anyOf("authorization_code", "refresh_token")),
2022
+ //TODO: match response_types with grant_types
2023
+ application_type: Optional(oneOf("native", "web")),
2024
+ contacts: Optional([validEmail]),
2025
+ client_name: Optional(String),
2026
+ logo_uri: Optional(validURL),
2027
+ client_uri: Optional(validURL),
2028
+ policy_uri: Optional(validURL),
2029
+ tos_uri: Optional(validURL),
2030
+ jwks_uri: Optional(validURL, not(MustHave("jwks"))),
2031
+ jwks: Optional(validURL, not(MustHave("jwks_uri"))),
2032
+ sector_identifier_uri: Optional(validURL),
2033
+ subject_type: Optional(String),
2034
+ id_token_signed_response_alg: Optional(oneOf(...validJWA)),
2035
+ id_token_encrypted_response_alg: Optional(oneOf(...validJWA)),
2036
+ id_token_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave("id_token_encrypted_response_alg")),
2037
+ userinfo_signed_response_alg: Optional(oneOf(...validJWA)),
2038
+ userinfo_encrypted_response_alg: Optional(oneOf(...validJWA)),
2039
+ userinfo_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave("userinfo_encrypted_response_alg")),
2040
+ request_object_signing_alg: Optional(oneOf(...validJWA)),
2041
+ request_object_encryption_alg: Optional(oneOf(...validJWA)),
2042
+ request_object_encryption_enc: Optional(oneOf(...validJWA)),
2043
+ token_endpoint_auth_method: Optional(oneOf(...validAuthMethods)),
2044
+ token_endpoint_auth_signing_alg: Optional(oneOf(...validJWA)),
2045
+ default_max_age: Optional(Number),
2046
+ require_auth_time: Optional(Boolean),
2047
+ default_acr_values: Optional([String]),
2048
+ initiate_login_uri: Optional([validURL]),
2049
+ request_uris: Optional([validURL])
2050
+ };
2051
+ assert(options, {
2052
+ client: Optional(instanceOf(everything_default.client().constructor)),
2053
+ registration_endpoint: validURL,
2054
+ client_info: openid_client_metadata
2055
+ });
2056
+ const defaultOptions = {
2057
+ client: everything_default.client().with(throwermw()).with(jsonmw()),
2058
+ client_info: {
2059
+ redirect_uris: [globalThis.document?.location.href]
2060
+ }
2061
+ };
2062
+ options = Object.assign({}, defaultOptions, options);
2063
+ if (!options.client_info) {
2064
+ options.client_info = {};
2065
+ }
2066
+ if (!options.client_info.redirect_uris) {
2067
+ options.client_info.redirect_uris = [globalThis.document?.location.href];
2068
+ }
2069
+ let response2 = await options.client.post(options.registration_endpoint, {
2070
+ body: options.client_info
2071
+ });
2072
+ let info = response2.data;
2073
+ if (!info.client_id || !info.client_secret) {
2074
+ throw everything_default.metroError("metro.oidc: Error: dynamic registration of client failed, no client_id or client_secret returned", response2);
2075
+ }
2076
+ options.client_info = Object.assign(options.client_info, info);
2077
+ return options.client_info;
2078
+ }
2079
+
2080
+ // node_modules/@muze-nl/metro-oidc/src/oidc.store.mjs
2081
+ function oidcStore(site) {
2082
+ let store;
2083
+ if (typeof localStorage !== "undefined") {
2084
+ store = {
2085
+ get: (name) => JSON.parse(localStorage.getItem("metro/oidc:" + site + ":" + name)),
2086
+ set: (name, value) => localStorage.setItem("metro/oidc:" + site + ":" + name, JSON.stringify(value)),
2087
+ has: (name) => localStorage.getItem("metro/oidc:" + site + ":" + name) !== null
2088
+ };
2089
+ } else {
2090
+ let storeMap = /* @__PURE__ */ new Map();
2091
+ store = {
2092
+ get: (name) => JSON.parse(storeMap.get("metro/oidc:" + site + ":" + name) || null),
2093
+ set: (name, value) => storeMap.set("metro/oidc:" + site + ":" + name, JSON.stringify(value)),
2094
+ has: (name) => storeMap.has("metro/oidc:" + site + ":" + name)
2095
+ };
2096
+ }
2097
+ return store;
2098
+ }
2099
+
2100
+ // node_modules/@muze-nl/metro-oidc/src/oidcmw.mjs
2101
+ function oidcmw(options = {}) {
2102
+ const defaultOptions = {
2103
+ client: client(),
2104
+ force_authorization: false,
2105
+ use_dpop: true,
2106
+ authorize_callback: async (url3) => {
2107
+ if (window.location.href != url3.href) {
2108
+ window.location.replace(url3.href);
2109
+ }
2110
+ return false;
2111
+ }
2112
+ };
2113
+ options = Object.assign({}, defaultOptions, options);
2114
+ assert(options, {
2115
+ client: Required(instanceOf(client().constructor)),
2116
+ // required because it is set in defaultOptions
2117
+ client_info: Required(),
2118
+ issuer: Required(validURL),
2119
+ oauth2: Optional({}),
2120
+ openid_configuration: Optional()
2121
+ });
2122
+ if (!options.store) {
2123
+ options.store = oidcStore(options.issuer);
2124
+ }
2125
+ if (!options.openid_configuration && options.store.has("openid_configuration")) {
2126
+ options.openid_configuration = options.store.get("openid_configuration");
2127
+ }
2128
+ if (!options.client_info?.client_id && options.store.has("client_info")) {
2129
+ options.client_info = options.store.get("client_info");
2130
+ }
2131
+ return async (req, next) => {
2132
+ let res;
2133
+ if (!options.force_authorization) {
2134
+ try {
2135
+ res = await next(req);
2136
+ } catch (err) {
2137
+ if (res.status != 401 && res.status != 403) {
2138
+ throw err;
2139
+ }
2140
+ }
2141
+ if (res.ok || res.status != 401 && res.status != 403) {
2142
+ return res;
2143
+ }
2144
+ }
2145
+ if (!options.openid_configuration) {
2146
+ options.openid_configuration = await oidcDiscovery({
2147
+ issuer: options.issuer
2148
+ });
2149
+ options.store.set("openid_configuration", options.openid_configuration);
2150
+ }
2151
+ if (!options.client_info?.client_id) {
2152
+ if (!options.openid_configuration.registration_endpoint) {
2153
+ throw metroError("metro.oidcmw: Error: issuer " + options.issuer + " does not support dynamic client registration, but you haven't specified a client_id");
2154
+ }
2155
+ options.client_info = await register({
2156
+ registration_endpoint: options.openid_configuration.registration_endpoint,
2157
+ client_info: options.client_info
2158
+ });
2159
+ options.store.set("client_info", options.client_info);
2160
+ }
2161
+ const scope = options.scope || "openid";
2162
+ const oauth2Options = Object.assign(
2163
+ {
2164
+ site: options.issuer,
2165
+ client: options.client,
2166
+ force_authorization: true,
2167
+ authorize_callback: options.authorize_callback,
2168
+ oauth2_configuration: {
2169
+ client_id: options.client_info?.client_id,
2170
+ client_secret: options.client_info?.client_secret,
2171
+ grant_type: "authorization_code",
2172
+ response_type: "code",
2173
+ response_mode: "query",
2174
+ authorization_endpoint: options.openid_configuration.authorization_endpoint,
2175
+ token_endpoint: options.openid_configuration.token_endpoint,
2176
+ scope,
2177
+ //FIXME: should only use scopes supported by server
2178
+ redirect_uri: options.client_info.redirect_uris[0]
2179
+ }
2180
+ }
2181
+ //...
2182
+ );
2183
+ const storeIdToken = async (req2, next2) => {
2184
+ const res2 = await next2(req2);
2185
+ const contentType = res2.headers.get("content-type");
2186
+ if (contentType?.startsWith("application/json")) {
2187
+ let id_token = res2.data?.id_token;
2188
+ if (!id_token) {
2189
+ const res22 = res2.clone();
2190
+ try {
2191
+ let data = await res22.json();
2192
+ if (data && data.id_token) {
2193
+ id_token = data.id_token;
2194
+ }
2195
+ } catch (e) {
2196
+ }
2197
+ }
2198
+ if (id_token) {
2199
+ options.store.set("id_token", id_token);
2200
+ }
2201
+ }
2202
+ return res2;
2203
+ };
2204
+ let oauth2client = options.client.with(options.issuer).with(storeIdToken);
2205
+ if (options.use_dpop) {
2206
+ const dpopOptions = {
2207
+ site: options.issuer,
2208
+ authorization_endpoint: options.openid_configuration.authorization_endpoint,
2209
+ token_endpoint: options.openid_configuration.token_endpoint,
2210
+ dpop_signing_alg_values_supported: options.openid_configuration.dpop_signing_alg_values_supported
2211
+ };
2212
+ oauth2client = oauth2client.with(dpopmw(dpopOptions));
2213
+ oauth2Options.client = oauth2client;
2214
+ }
2215
+ oauth2client = oauth2client.with(oauth2mw(oauth2Options));
2216
+ res = await oauth2client.fetch(req);
2217
+ return res;
2218
+ };
2219
+ }
2220
+ function isRedirected2() {
2221
+ return isRedirected();
2222
+ }
2223
+ function idToken(options) {
2224
+ if (!options.store) {
2225
+ if (!options.issuer) {
2226
+ throw metroError("Must supply options.issuer or options.store to get the id_token");
2227
+ }
2228
+ options.store = oidcStore(options.issuer);
2229
+ }
2230
+ return options.store.get("id_token");
2231
+ }
2232
+
2233
+ // node_modules/@muze-nl/metro-oidc/src/browser.mjs
2234
+ var oidc = {
2235
+ oidcmw,
2236
+ discover: oidcDiscovery,
2237
+ register,
2238
+ isRedirected: isRedirected2,
2239
+ idToken
2240
+ };
2241
+ if (!globalThis.metro.oidc) {
2242
+ globalThis.metro.oidc = oidc;
2243
+ }
2244
+ var browser_default = oidc;
2245
+
2246
+ // node_modules/@muze-nl/oldm/src/oldm.mjs
2247
+ function oldm(options) {
2248
+ return new Context(options);
2249
+ }
2250
+ var rdfType = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
2251
+ var prefixes = {
2252
+ rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
2253
+ solid: "http://www.w3.org/ns/solid/terms#",
2254
+ schema: "http://schema.org/",
2255
+ vcard: "http://www.w3.org/2006/vcard/ns#"
2256
+ };
2257
+ var Context = class {
2258
+ constructor(options) {
2259
+ this.prefixes = { ...prefixes, ...options?.prefixes };
2260
+ if (!this.prefixes["xsd"]) {
2261
+ this.prefixes["xsd"] = "http://www.w3.org/2001/XMLSchema#";
2262
+ }
2263
+ this.parser = options?.parser;
2264
+ this.writer = options?.writer;
2265
+ this.sources = /* @__PURE__ */ Object.create(null);
2266
+ this.separator = options?.separator ?? "$";
2267
+ }
2268
+ parse(input, url3, type) {
2269
+ const { quads, prefixes: prefixes2 } = this.parser(input, url3, type);
2270
+ if (prefixes2) {
2271
+ for (let prefix in prefixes2) {
2272
+ let prefixURL = prefixes2[prefix];
2273
+ if (prefixURL.match(/^http(s?):\/\/$/i)) {
2274
+ prefixURL += url3.substring(prefixURL.length);
2275
+ } else try {
2276
+ prefixURL = new URL(prefixes2[prefix], url3).href;
2277
+ } catch (err) {
2278
+ console.error("Could not parse prefix", prefixes2[prefix], err.message);
2279
+ }
2280
+ if (!this.prefixes[prefix]) {
2281
+ this.prefixes[prefix] = prefixURL;
2282
+ }
2283
+ }
2284
+ }
2285
+ this.sources[url3] = new Graph(quads, url3, type, prefixes2, this);
2286
+ return this.sources[url3];
2287
+ }
2288
+ setType(literal, shortType) {
2289
+ if (!shortType) {
2290
+ return literal;
2291
+ }
2292
+ if (typeof literal == "string") {
2293
+ literal = new String(literal);
2294
+ } else if (typeof result == "number") {
2295
+ literal = new Number(literal);
2296
+ }
2297
+ if (typeof literal !== "object") {
2298
+ throw new Error("cannot set type on ", literal, shortType);
2299
+ }
2300
+ literal.type = shortType;
2301
+ return literal;
2302
+ }
2303
+ getType(literal) {
2304
+ if (literal && typeof literal == "object") {
2305
+ return literal.type;
2306
+ }
2307
+ return null;
2308
+ }
2309
+ };
2310
+ var Graph = class {
2311
+ #blankNodes = /* @__PURE__ */ Object.create(null);
2312
+ constructor(quads, url3, mimetype, prefixes2, context) {
2313
+ this.mimetype = mimetype;
2314
+ this.url = url3;
2315
+ this.prefixes = prefixes2;
2316
+ this.context = context;
2317
+ this.subjects = /* @__PURE__ */ Object.create(null);
2318
+ for (let quad of quads) {
2319
+ let subject;
2320
+ if (quad.subject.termType == "BlankNode") {
2321
+ let shortPred = this.shortURI(quad.predicate.id, ":");
2322
+ let shortObj;
2323
+ switch (shortPred) {
2324
+ case "rdf:first":
2325
+ subject = this.addCollection(quad.subject.id);
2326
+ shortObj = this.shortURI(quad.object.id, ":");
2327
+ if (shortObj != "rdf:nil") {
2328
+ const value = this.getValue(quad.object);
2329
+ if (value) {
2330
+ subject.push(value);
2331
+ }
2332
+ }
2333
+ continue;
2334
+ case "rdf:rest":
2335
+ this.#blankNodes[quad.object.id] = this.#blankNodes[quad.subject.id];
2336
+ continue;
2337
+ default:
2338
+ subject = this.addBlankNode(quad.subject.id);
2339
+ break;
2340
+ }
2341
+ } else {
2342
+ subject = this.addNamedNode(quad.subject.id);
2343
+ }
2344
+ subject.addPredicate(quad.predicate.id, quad.object);
2345
+ }
2346
+ if (this.subjects[url3]) {
2347
+ this.primary = this.subjects[url3];
2348
+ } else {
2349
+ this.primary = null;
2350
+ }
2351
+ Object.defineProperty(this, "data", {
2352
+ get() {
2353
+ return Object.values(this.subjects);
2354
+ }
2355
+ });
2356
+ }
2357
+ addNamedNode(uri) {
2358
+ let absURI = new URL(uri, this.url).href;
2359
+ if (!this.subjects[absURI]) {
2360
+ this.subjects[absURI] = new NamedNode(absURI, this);
2361
+ }
2362
+ return this.subjects[absURI];
2363
+ }
2364
+ addBlankNode(id) {
2365
+ if (!this.#blankNodes[id]) {
2366
+ this.#blankNodes[id] = new BlankNode(this);
2367
+ }
2368
+ return this.#blankNodes[id];
2369
+ }
2370
+ addCollection(id) {
2371
+ if (!this.#blankNodes[id]) {
2372
+ this.#blankNodes[id] = new Collection(this);
2373
+ }
2374
+ return this.#blankNodes[id];
2375
+ }
2376
+ write() {
2377
+ return this.context.writer(this);
2378
+ }
2379
+ get(shortID) {
2380
+ return this.subjects[this.fullURI(shortID)];
2381
+ }
2382
+ fullURI(shortURI, separator = null) {
2383
+ if (!separator) {
2384
+ separator = this.context.separator;
2385
+ }
2386
+ const [prefix, path] = shortURI.split(separator);
2387
+ if (path) {
2388
+ return this.prefixes[prefix] + path;
2389
+ }
2390
+ return shortURI;
2391
+ }
2392
+ shortURI(fullURI, separator = null) {
2393
+ if (!separator) {
2394
+ separator = this.context.separator;
2395
+ }
2396
+ for (let prefix in this.context.prefixes) {
2397
+ if (fullURI.startsWith(this.context.prefixes[prefix])) {
2398
+ return prefix + separator + fullURI.substring(this.context.prefixes[prefix].length);
2399
+ }
2400
+ }
2401
+ if (this.url && fullURI.startsWith(this.url)) {
2402
+ return fullURI.substring(this.url.length);
2403
+ }
2404
+ return fullURI;
2405
+ }
2406
+ /**
2407
+ * This sets the type of a literal, usually one of the xsd types
2408
+ */
2409
+ setType(literal, type) {
2410
+ const shortType = this.shortURI(type);
2411
+ return this.context.setType(literal, shortType);
2412
+ }
2413
+ /**
2414
+ * This returns the type of a literal, or null
2415
+ */
2416
+ getType(literal) {
2417
+ return this.context.getType(literal);
2418
+ }
2419
+ setLanguage(literal, language) {
2420
+ if (typeof literal == "string") {
2421
+ literal = new String(literal);
2422
+ } else if (typeof result == "number") {
2423
+ literal = new Number(literal);
2424
+ }
2425
+ if (typeof literal !== "object") {
2426
+ throw new Error("cannot set language on ", literal);
2427
+ }
2428
+ literal.language = language;
2429
+ return literal;
2430
+ }
2431
+ getValue(object) {
2432
+ let result2;
2433
+ if (object.termType == "Literal") {
2434
+ result2 = object.value;
2435
+ let datatype = object.datatype?.id;
2436
+ if (datatype) {
2437
+ result2 = this.setType(result2, datatype);
2438
+ }
2439
+ let language = object.language;
2440
+ if (language) {
2441
+ result2 = this.setLanguage(result2, language);
2442
+ }
2443
+ } else if (object.termType == "BlankNode") {
2444
+ result2 = this.addBlankNode(object.id);
2445
+ } else {
2446
+ result2 = this.addNamedNode(object.id);
2447
+ }
2448
+ return result2;
2449
+ }
2450
+ };
2451
+ var BlankNode = class {
2452
+ constructor(graph) {
2453
+ Object.defineProperty(this, "graph", {
2454
+ value: graph,
2455
+ writable: false,
2456
+ enumerable: false
2457
+ });
2458
+ }
2459
+ addPredicate(predicate, object) {
2460
+ if (predicate.id) {
2461
+ predicate = predicate.id;
2462
+ }
2463
+ if (predicate == rdfType) {
2464
+ let type = this.graph.shortURI(object.id);
2465
+ this.addType(type);
2466
+ } else {
2467
+ const value = this.graph.getValue(object);
2468
+ predicate = this.graph.shortURI(predicate);
2469
+ if (!this[predicate]) {
2470
+ this[predicate] = value;
2471
+ } else if (Array.isArray(this[predicate])) {
2472
+ this[predicate].push(value);
2473
+ } else {
2474
+ this[predicate] = [this[predicate], value];
2475
+ }
2476
+ }
2477
+ }
2478
+ /**
2479
+ * Adds a rdfType value, stored in this.a
2480
+ * Subjects can have more than one type (or class), unlike literals
2481
+ * The type value can be any URI, xsdTypes are unexpected here
2482
+ */
2483
+ addType(type) {
2484
+ if (!this.a) {
2485
+ this.a = type;
2486
+ } else {
2487
+ if (!Array.isArray(this.a)) {
2488
+ this.a = [this.a];
2489
+ }
2490
+ this.a.push(type);
2491
+ }
2492
+ }
2493
+ };
2494
+ var NamedNode = class extends BlankNode {
2495
+ constructor(id, graph) {
2496
+ super(graph);
2497
+ Object.defineProperty(this, "id", {
2498
+ value: id,
2499
+ writable: false,
2500
+ enumerable: true
2501
+ });
2502
+ }
2503
+ };
2504
+ var Collection = class extends Array {
2505
+ constructor(id, graph) {
2506
+ super();
2507
+ Object.defineProperty(this, "graph", {
2508
+ value: graph,
2509
+ writable: false,
2510
+ enumerable: false
2511
+ });
2512
+ }
2513
+ };
2514
+
2515
+ // node_modules/@muze-nl/metro-oldm/src/oldmmw.mjs
2516
+ function oldmmw(options) {
2517
+ options = Object.assign({
2518
+ contentType: "text/turtle",
2519
+ prefixes: {
2520
+ "ldp": "http://www.w3.org/ns/ldp#",
2521
+ "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
2522
+ "dct": "http://purl.org/dc/terms/",
2523
+ "stat": "http://www.w3.org/ns/posix/stat#",
2524
+ "turtle": "http://www.w3.org/ns/iana/media-types/text/turtle#",
2525
+ "schem": "https://schema.org/",
2526
+ "solid": "http://www.w3.org/ns/solid/terms#",
2527
+ "acl": "http://www.w3.org/ns/auth/acl#",
2528
+ "pims": "http://www.w3.org/ns/pim/space#",
2529
+ "vcard": "http://www.w3.org/2006/vcard/ns#",
2530
+ "foaf": "http://xmlns.com/foaf/0.1/"
2531
+ },
2532
+ parser: oldm.n3Parser,
2533
+ writer: oldm.n3Writer
2534
+ }, options);
2535
+ if (!options.prefixes["ldp"]) {
2536
+ options.prefixes["ldp"] = "http://www.w3.org/ns/ldp#";
2537
+ }
2538
+ const context = oldm(options);
2539
+ return async function oldmmw2(req, next) {
2540
+ if (!req.headers.get("Accept")) {
2541
+ req = req.with({
2542
+ headers: {
2543
+ "Accept": options.accept ?? options.contentType
2544
+ }
2545
+ });
2546
+ }
2547
+ if (req.method !== "GET" && req.method !== "HEAD") {
2548
+ if (req.data && typeof req.data == "object" && !(req.data instanceof ReadableStream)) {
2549
+ const contentType = req.headers.get("Content-Type");
2550
+ if (!contentType || isPlainText(contentType)) {
2551
+ req = req.with({
2552
+ headers: {
2553
+ "Content-Type": options.contentType
2554
+ }
2555
+ });
2556
+ }
2557
+ if (isLinkedData(req.headers.get("Content-Type"))) {
2558
+ req = req.with({
2559
+ body: await context.writer(req.data)
2560
+ });
2561
+ }
2562
+ }
2563
+ }
2564
+ let res = await next(req);
2565
+ };
2566
+ }
2567
+
2568
+ // node_modules/@muze-nl/metro-oldm/src/index.mjs
2569
+ globalThis.oldmmw = oldmmw;
2570
+ var src_default = oldmmw;
2571
+
2572
+ // node_modules/@muze-nl/jaqt/src/jaqt.mjs
2573
+ function isPrimitiveWrapper(data) {
2574
+ return [String, Boolean, Number, BigInt].includes(data?.constructor);
2575
+ }
2576
+ function getSelectFn(filter) {
2577
+ let fns = [];
2578
+ if (filter instanceof Function) {
2579
+ fns.push(filter);
2580
+ } else for (const [filterKey, filterValue] of Object.entries(filter)) {
2581
+ if (filterValue instanceof Function) {
2582
+ fns.push((data) => {
2583
+ const result2 = {
2584
+ [filterKey]: filterValue(data, filterKey, "select")
2585
+ };
2586
+ return result2;
2587
+ });
2588
+ } else if (!isPrimitiveWrapper(filterValue)) {
2589
+ fns.push((data) => {
2590
+ const result2 = {
2591
+ [filterKey]: from(data[filterKey]).select(filterValue)
2592
+ };
2593
+ return result2;
2594
+ });
2595
+ } else {
2596
+ fns.push(() => {
2597
+ return {
2598
+ [filterKey]: filterValue
2599
+ };
2600
+ });
2601
+ }
2602
+ }
2603
+ if (fns.length == 1) {
2604
+ return fns[0];
2605
+ }
2606
+ return (data) => {
2607
+ let result2 = {};
2608
+ for (let fn of fns) {
2609
+ Object.assign(result2, fn(data));
2610
+ }
2611
+ return result2;
2612
+ };
2613
+ }
2614
+ function getMatchFn(pattern) {
2615
+ let fns = [];
2616
+ if (Array.isArray(pattern)) {
2617
+ fns.push(anyOf2(...pattern));
2618
+ } else if (pattern instanceof RegExp) {
2619
+ fns.push((data) => pattern.test(data));
2620
+ } else if (pattern instanceof Function) {
2621
+ fns.push((data) => pattern(data));
2622
+ } else if (!isPrimitiveWrapper(pattern)) {
2623
+ let patternMatches = {};
2624
+ for (const [wKey, wVal] of Object.entries(pattern)) {
2625
+ patternMatches[wKey] = getMatchFn(wVal);
2626
+ }
2627
+ let matchFn = (data) => {
2628
+ if (Array.isArray(data)) {
2629
+ return data.filter((element) => matchFn(element)).length > 0;
2630
+ }
2631
+ if (isPrimitiveWrapper(data)) {
2632
+ return false;
2633
+ }
2634
+ for (let wKey in patternMatches) {
2635
+ let patternMatchFn = patternMatches[wKey];
2636
+ if (!patternMatchFn(data?.[wKey])) {
2637
+ return false;
2638
+ }
2639
+ }
2640
+ return true;
2641
+ };
2642
+ fns.push(matchFn);
2643
+ } else {
2644
+ fns.push((data) => {
2645
+ if (Array.isArray(data)) {
2646
+ return data.filter((element) => pattern == element).length > 0;
2647
+ } else {
2648
+ return pattern == data;
2649
+ }
2650
+ });
2651
+ }
2652
+ if (fns.length == 1) {
2653
+ return fns[0];
2654
+ }
2655
+ return (data) => {
2656
+ for (let fn of fns) {
2657
+ if (!fn(data)) {
2658
+ return false;
2659
+ }
2660
+ }
2661
+ return true;
2662
+ };
2663
+ }
2664
+ var asc = Symbol("asc");
2665
+ var desc = Symbol("desc");
2666
+ function getSortFn(pattern) {
2667
+ let comparisons = Object.entries(pattern);
2668
+ let fns = [];
2669
+ for (let [key, compare] of comparisons) {
2670
+ if (compare instanceof Function) {
2671
+ fns.push(compare);
2672
+ } else if (compare === asc) {
2673
+ fns.push((a, b) => a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0);
2674
+ } else if (compare === desc) {
2675
+ fns.push((a, b) => a[key] < b[key] ? 1 : a[key] > b[key] ? -1 : 0);
2676
+ } else if (!isPrimitiveWrapper(compare)) {
2677
+ let subFn = getSortFn(compare);
2678
+ fns.push((a, b) => subFn(a[key], b[key]));
2679
+ } else {
2680
+ throw new Error("Unknown sort order", compare);
2681
+ }
2682
+ }
2683
+ if (fns.length == 1) {
2684
+ return fns[0];
2685
+ }
2686
+ return (a, b) => {
2687
+ for (let fn of fns) {
2688
+ let result2 = fn(a, b);
2689
+ if (result2 !== 0) {
2690
+ return result2;
2691
+ }
2692
+ }
2693
+ return 0;
2694
+ };
2695
+ }
2696
+ function getAggregateFn(filter) {
2697
+ let fns = [];
2698
+ if (filter instanceof Function) {
2699
+ fns.push(filter);
2700
+ } else for (const [filterKey, filterValue] of Object.entries(filter)) {
2701
+ if (filterValue instanceof Function) {
2702
+ fns.push((a, o, i, l) => {
2703
+ if (isPrimitiveWrapper(a)) {
2704
+ a = {};
2705
+ }
2706
+ if (o.reduce) {
2707
+ a[filterKey] = o.reduce(filterValue, a[filterKey] || []);
2708
+ } else {
2709
+ a[filterKey] = filterValue(a[filterKey] || [], o, i, l);
2710
+ }
2711
+ return a;
2712
+ });
2713
+ } else if (!isPrimitiveWrapper(filterValue)) {
2714
+ fns.push((a, o) => {
2715
+ if (isPrimitiveWrapper(a)) {
2716
+ a = {};
2717
+ }
2718
+ a[filterKey] = from(o[filterKey]).reduce(filterValue, []);
2719
+ return a;
2720
+ });
2721
+ } else {
2722
+ fns.push((a) => {
2723
+ if (isPrimitiveWrapper(a)) {
2724
+ a = {};
2725
+ }
2726
+ a[filterKey] = filterValue;
2727
+ return a;
2728
+ });
2729
+ }
2730
+ }
2731
+ if (fns.length == 1) {
2732
+ return fns[0];
2733
+ }
2734
+ return (a, o, i, l) => {
2735
+ let result2 = {};
2736
+ for (let fn of fns) {
2737
+ Object.assign(result2, fn(a, o, i, l));
2738
+ }
2739
+ return result2;
2740
+ };
2741
+ }
2742
+ function getMatchingGroups(data, pointerFn) {
2743
+ let result2 = {};
2744
+ for (let entity of data) {
2745
+ let groups = pointerFn(entity);
2746
+ if (!Array.isArray(groups)) {
2747
+ groups = [groups];
2748
+ }
2749
+ for (let group of groups) {
2750
+ if (typeof group != "string" && !(group instanceof String)) {
2751
+ console.warn("JAQT: groupBy(selector) can only handle string values, got:", group);
2752
+ continue;
2753
+ }
2754
+ if (!result2[group]) {
2755
+ result2[group] = [];
2756
+ }
2757
+ result2[group].push(entity);
2758
+ }
2759
+ }
2760
+ return result2;
2761
+ }
2762
+ function groupBy(data, pointerFunctions) {
2763
+ let pointerFn = pointerFunctions.shift();
2764
+ let groups = getMatchingGroups(data, pointerFn);
2765
+ if (pointerFunctions.length) {
2766
+ for (let group in groups) {
2767
+ groups[group] = groupBy(groups[group], pointerFunctions);
2768
+ }
2769
+ }
2770
+ return groups;
2771
+ }
2772
+ function anyOf2(...patterns) {
2773
+ let matchFns = patterns.map((pattern) => getMatchFn(pattern));
2774
+ return (data) => matchFns.some((fn) => fn(data));
2775
+ }
2776
+ var FunctionProxyHandler = {
2777
+ apply(target, thisArg, argumentsList) {
2778
+ let result2 = target.apply(thisArg, argumentsList);
2779
+ if (typeof result2 === "object") {
2780
+ return new Proxy(result2, DataProxyHandler);
2781
+ }
2782
+ return result2;
2783
+ }
2784
+ };
2785
+ var DataProxyHandler = {
2786
+ get(target, property) {
2787
+ let result2 = null;
2788
+ if (typeof property === "symbol") {
2789
+ result2 = target[property];
2790
+ }
2791
+ if (Array.isArray(target)) {
2792
+ switch (property) {
2793
+ case "where":
2794
+ result2 = function(shape) {
2795
+ let matchFn = getMatchFn(shape);
2796
+ return new Proxy(
2797
+ target.filter((element) => matchFn(element)),
2798
+ DataProxyHandler
2799
+ );
2800
+ };
2801
+ break;
2802
+ case "select":
2803
+ result2 = function(filter) {
2804
+ let selectFn = getSelectFn(filter);
2805
+ return new Proxy(
2806
+ target.map(selectFn),
2807
+ DataProxyHandler
2808
+ );
2809
+ };
2810
+ break;
2811
+ case "reduce":
2812
+ result2 = function(pattern, initial = []) {
2813
+ let aggregateFn = getAggregateFn(pattern);
2814
+ let temp = target.reduce(aggregateFn, initial);
2815
+ if (Array.isArray(temp)) {
2816
+ return new Proxy(temp, DataProxyHandler);
2817
+ } else if (!isPrimitiveWrapper(temp)) {
2818
+ return new Proxy(temp, GroupByProxyHandler);
2819
+ } else {
2820
+ return temp;
2821
+ }
2822
+ };
2823
+ break;
2824
+ case "orderBy":
2825
+ result2 = function(pattern) {
2826
+ let sortFn = getSortFn(pattern);
2827
+ return new Proxy(
2828
+ target.toSorted(sortFn),
2829
+ DataProxyHandler
2830
+ );
2831
+ };
2832
+ break;
2833
+ case "groupBy":
2834
+ result2 = function(...groups) {
2835
+ let temp = groupBy(target, groups);
2836
+ return new Proxy(
2837
+ temp,
2838
+ GroupByProxyHandler
2839
+ );
2840
+ };
2841
+ break;
2842
+ }
2843
+ }
2844
+ if (!result2 && target && typeof target === "object") {
2845
+ if (property === "select") {
2846
+ result2 = function(filter) {
2847
+ let selector = getSelectFn(filter);
2848
+ return new Proxy(selector(target), DataProxyHandler);
2849
+ };
2850
+ }
2851
+ }
2852
+ if (!result2 && target && typeof target[property] === "function") {
2853
+ result2 = new Proxy(target[property], FunctionProxyHandler);
2854
+ }
2855
+ if (!result2) {
2856
+ result2 = target[property];
2857
+ }
2858
+ return result2;
2859
+ }
2860
+ };
2861
+ var GroupByProxyHandler = {
2862
+ get(target, property) {
2863
+ let result2 = null;
2864
+ switch (property) {
2865
+ case "select":
2866
+ result2 = function(filter) {
2867
+ let selectFn = getSelectFn(filter);
2868
+ let result3 = {};
2869
+ for (let group in target) {
2870
+ if (Array.isArray(target[group])) {
2871
+ result3[group] = new Proxy(target[group].map(selectFn), DataProxyHandler);
2872
+ } else {
2873
+ result3[group] = new Proxy(target[group], GroupByProxyHandler);
2874
+ }
2875
+ }
2876
+ return result3;
2877
+ };
2878
+ break;
2879
+ case "reduce":
2880
+ result2 = function(pattern, initial = []) {
2881
+ let aggregateFn = getAggregateFn(pattern);
2882
+ let result3 = {};
2883
+ for (let group in target) {
2884
+ if (Array.isArray(target[group])) {
2885
+ let temp = target[group].reduce(aggregateFn, initial);
2886
+ if (Array.isArray(temp)) {
2887
+ result3[group] = new Proxy(temp, DataProxyHandler);
2888
+ } else if (!isPrimitiveWrapper(temp)) {
2889
+ result3[group] = new Proxy(temp, GroupByProxyHandler);
2890
+ } else {
2891
+ result3[group] = temp;
2892
+ }
2893
+ } else {
2894
+ result3[group] = new Proxy(target[group], GroupByProxyHandler);
2895
+ }
2896
+ }
2897
+ return result3;
2898
+ };
2899
+ break;
2900
+ default:
2901
+ if (Array.isArray(target[property])) {
2902
+ result2 = from(target[property]);
2903
+ } else {
2904
+ result2 = target[property];
2905
+ }
2906
+ break;
2907
+ }
2908
+ return result2;
2909
+ }
2910
+ };
2911
+ var EmptyHandler = {
2912
+ get(target, property) {
2913
+ let result2 = null;
2914
+ switch (property) {
2915
+ case "where":
2916
+ result2 = function() {
2917
+ return new Proxy(new Null(), EmptyHandler);
2918
+ };
2919
+ break;
2920
+ case "reduce":
2921
+ case "select":
2922
+ result2 = function() {
2923
+ return null;
2924
+ };
2925
+ break;
2926
+ case "orderBy":
2927
+ result2 = function() {
2928
+ return new Proxy(new Null(), EmptyHandler);
2929
+ };
2930
+ break;
2931
+ case "groupBy":
2932
+ result2 = function() {
2933
+ return new Proxy(new Null(), EmptyHandler);
2934
+ };
2935
+ break;
2936
+ }
2937
+ if (!result2 && typeof target?.[property] == "function") {
2938
+ result2 = target[property];
2939
+ }
2940
+ return result2;
2941
+ }
2942
+ };
2943
+ var Null = class {
2944
+ toJSON() {
2945
+ return null;
2946
+ }
2947
+ };
2948
+ function from(data) {
2949
+ if (!data || typeof data !== "object") {
2950
+ return new Proxy(new Null(), EmptyHandler);
2951
+ }
2952
+ return new Proxy(data, DataProxyHandler);
2953
+ }
2954
+ function getPointerFn(path) {
2955
+ return (data, key) => {
2956
+ if (path?.length > 0) {
2957
+ let localPath = path.slice();
2958
+ let prop = localPath.shift();
2959
+ while (prop) {
2960
+ if (Array.isArray(data) && parseInt(prop) != prop) {
2961
+ localPath.unshift(prop);
2962
+ return data.map(getPointerFn(localPath));
2963
+ } else if (typeof data?.[prop] != "undefined") {
2964
+ data = data[prop];
2965
+ } else {
2966
+ data = null;
2967
+ }
2968
+ prop = localPath.shift();
2969
+ }
2970
+ return data;
2971
+ } else if (key) {
2972
+ if (typeof data?.[key] != "undefined") {
2973
+ return data[key];
2974
+ } else {
2975
+ return null;
2976
+ }
2977
+ } else {
2978
+ return data;
2979
+ }
2980
+ };
2981
+ }
2982
+ var pointerHandler = (path) => {
2983
+ if (!path) {
2984
+ path = [];
2985
+ }
2986
+ return {
2987
+ get(target, property) {
2988
+ if (property == "constructor" || typeof property == "symbol") {
2989
+ return target[property];
2990
+ }
2991
+ let newpath = path.concat([property]);
2992
+ return new Proxy(getPointerFn(newpath), pointerHandler(newpath));
2993
+ },
2994
+ apply(target, thisArg, argumentsList) {
2995
+ let result2 = target(...argumentsList);
2996
+ if (Array.isArray(result2)) {
2997
+ result2 = result2.flat(Infinity);
2998
+ }
2999
+ return result2;
3000
+ }
3001
+ };
3002
+ };
3003
+ var _ = new Proxy(getPointerFn(), pointerHandler());
3004
+
3005
+ // src/SolidAdapter.js
3006
+ var SolidAdapter = class extends HttpAdapter {
3007
+ #client;
3008
+ #path;
3009
+ constructor(metroClient, path = "/", solidConfiguration = {}) {
3010
+ this.#client = client(metroClient).with(browser_default.oidcmw(solidConfiguration)).with(src_default(solidConfiguration));
3011
+ this.#path = new Path(path);
3012
+ }
3013
+ get name() {
3014
+ return "SolidAdapter";
3015
+ }
3016
+ async list(path) {
3017
+ let supportedContentTypes = [
3018
+ "text/turtle"
3019
+ ];
3020
+ let result2 = await this.read(path);
3021
+ if (result2.data) {
3022
+ from(result2.data).where({
3023
+ a: "ldp$Resource"
3024
+ }).select({
3025
+ filename: (o) => jsfs.path.filename(metro.url(o.id).pathname),
3026
+ path: (o) => metro.url(o.id).pathname,
3027
+ type: (o) => o.a.includes("ldp$Container") ? "folder" : "file"
3028
+ });
3029
+ } else {
3030
+ throw new Error(path + " could not be parsed", { cause: result2 });
3031
+ }
3032
+ }
3033
+ };
3034
+
3035
+ // src/browser.js
3036
+ var browser_default2 = SolidAdapter;
3037
+ globalThis.SolidAdapter = SolidAdapter;
3038
+ })();
3039
+ //# sourceMappingURL=browser.js.map