k99 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +127 -119
- package/index.d.ts +75 -48
- package/index.js +127 -119
- package/index.min.js +3 -3
- package/index.min.mjs +3 -3
- package/index.mjs +127 -119
- package/package.json +1 -1
- package/services.cjs +2 -2
- package/services.d.ts +2 -2
- package/services.js +2 -2
- package/services.min.js +2 -2
- package/services.min.mjs +2 -2
- package/services.mjs +2 -2
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* k99 v0.
|
|
3
|
-
* (c) 2019-
|
|
2
|
+
* k99 v0.8.0
|
|
3
|
+
* (c) 2019-2026 猛火Fierflame
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
/**
|
|
13
13
|
*
|
|
14
14
|
* @param {string} str
|
|
15
|
-
* @returns {Uint8Array}
|
|
15
|
+
* @returns {Uint8Array<ArrayBuffer>}
|
|
16
16
|
*/
|
|
17
17
|
function str2utf8bin(str) {
|
|
18
|
+
// @ts-ignore
|
|
18
19
|
return new TextEncoder().encode(str);
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
@@ -53,26 +54,15 @@
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
/**
|
|
57
|
-
*
|
|
58
|
-
* @param {any} k
|
|
59
|
-
* @param {any} v
|
|
60
|
-
* @returns {any}
|
|
61
|
-
*/
|
|
62
|
-
function replacer(k, v) {
|
|
63
|
-
if (typeof v === 'bigint') {
|
|
64
|
-
return String(v);
|
|
65
|
-
}
|
|
66
|
-
return v;
|
|
67
|
-
}
|
|
68
57
|
|
|
69
58
|
/**
|
|
70
59
|
*
|
|
71
60
|
* @param {any} result
|
|
61
|
+
* @param {(this: any, key: string, value: any) => any} replacer
|
|
72
62
|
* @param {Promise<never>} [aborted]
|
|
73
63
|
* @returns {[BodyInit, number, string] | null}
|
|
74
64
|
*/
|
|
75
|
-
function toBodyData(result, aborted) {
|
|
65
|
+
function toBodyData(result, replacer, aborted) {
|
|
76
66
|
if (result instanceof ReadableStream) {
|
|
77
67
|
return [result, 0, ''];
|
|
78
68
|
}
|
|
@@ -86,11 +76,16 @@
|
|
|
86
76
|
return [result, 0, ''];
|
|
87
77
|
}
|
|
88
78
|
if (ArrayBuffer.isView(result) || result instanceof ArrayBuffer) {
|
|
79
|
+
// @ts-ignore
|
|
89
80
|
return [result, result.byteLength, ''];
|
|
90
81
|
}
|
|
91
82
|
if (typeof result === 'string') {
|
|
92
83
|
const body = str2utf8bin(result);
|
|
93
|
-
return [body, body.byteLength, ''];
|
|
84
|
+
return [body, body.byteLength, 'text/plain'];
|
|
85
|
+
}
|
|
86
|
+
if (['bigint', 'boolean', 'number'].includes(typeof result)) {
|
|
87
|
+
const body = str2utf8bin(JSON.stringify(result, replacer));
|
|
88
|
+
return [body, body.byteLength, 'application/json'];
|
|
94
89
|
}
|
|
95
90
|
if (typeof result !== 'object') {
|
|
96
91
|
return null;
|
|
@@ -117,11 +112,12 @@
|
|
|
117
112
|
*
|
|
118
113
|
* @param {any} result
|
|
119
114
|
* @param {Headers} headers
|
|
115
|
+
* @param {(this: any, key: string, value: any) => any} replacer
|
|
120
116
|
* @param {Promise<never>} [aborted]
|
|
121
117
|
* @returns
|
|
122
118
|
*/
|
|
123
|
-
function toBody(result, headers, aborted) {
|
|
124
|
-
const bodyData = toBodyData(result, aborted);
|
|
119
|
+
function toBody(result, headers, replacer, aborted) {
|
|
120
|
+
const bodyData = toBodyData(result, replacer, aborted);
|
|
125
121
|
if (!bodyData) { return null; }
|
|
126
122
|
const [body, size, type] = bodyData;
|
|
127
123
|
if (type && !headers.get('Content-Type')) {
|
|
@@ -215,7 +211,7 @@
|
|
|
215
211
|
}
|
|
216
212
|
}
|
|
217
213
|
|
|
218
|
-
/** @import { Context, Cookie, CookieOption, FindHandler, Method, Options, Params, Service } from './types' */
|
|
214
|
+
/** @import { Context, Cookie, CookieOption, FindHandler, HandlerResult, Method, Options, Params, Service } from './types' */
|
|
219
215
|
|
|
220
216
|
|
|
221
217
|
const noBodyMethods = new Set(['GET', 'OPTIONS']);
|
|
@@ -268,6 +264,18 @@
|
|
|
268
264
|
}
|
|
269
265
|
return /** @type {Method} */(methodStr.toUpperCase());
|
|
270
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
*
|
|
269
|
+
* @param {any} k
|
|
270
|
+
* @param {any} v
|
|
271
|
+
* @returns {any}
|
|
272
|
+
*/
|
|
273
|
+
function defaultReplacer(k, v) {
|
|
274
|
+
if (typeof v === 'bigint') {
|
|
275
|
+
return String(v);
|
|
276
|
+
}
|
|
277
|
+
return v;
|
|
278
|
+
}
|
|
271
279
|
/**
|
|
272
280
|
*
|
|
273
281
|
* @param {Request} request
|
|
@@ -275,10 +283,15 @@
|
|
|
275
283
|
* @param {Options} [options]
|
|
276
284
|
* @returns {Promise<Response | null>}
|
|
277
285
|
*/
|
|
278
|
-
function main(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
286
|
+
function main(request, getHandler, {
|
|
287
|
+
runner,
|
|
288
|
+
error: echoError,
|
|
289
|
+
catch: catchError,
|
|
290
|
+
method: toMethod,
|
|
291
|
+
environment,
|
|
292
|
+
replacer: JSONReplacer,
|
|
293
|
+
} = {}) {
|
|
294
|
+
const replacer = typeof JSONReplacer === 'function' ? JSONReplacer : defaultReplacer;
|
|
282
295
|
/**
|
|
283
296
|
*
|
|
284
297
|
* @param {Request} request
|
|
@@ -302,12 +315,12 @@
|
|
|
302
315
|
/** @type {any} */
|
|
303
316
|
let error = null;
|
|
304
317
|
|
|
305
|
-
let resolve = () => {};
|
|
318
|
+
let resolve = () => { };
|
|
306
319
|
/** @type {(error: unknown) => void} */
|
|
307
|
-
let reject = () => {};
|
|
320
|
+
let reject = () => { };
|
|
308
321
|
/** @type {Promise<void>} */
|
|
309
322
|
const donePromise = new Promise((a, b) => { resolve = a; reject = b; });
|
|
310
|
-
donePromise.catch(() => {});
|
|
323
|
+
donePromise.catch(() => { });
|
|
311
324
|
|
|
312
325
|
/** @type {Params} */
|
|
313
326
|
let params = {};
|
|
@@ -325,7 +338,7 @@
|
|
|
325
338
|
if (!data || noBodyMethods.has(method.toUpperCase())) {
|
|
326
339
|
return exec(new Request(fetchUrl, { method, headers, signal }), context);
|
|
327
340
|
}
|
|
328
|
-
const body = toBody(data, headers);
|
|
341
|
+
const body = toBody(data, headers, replacer);
|
|
329
342
|
return exec(new Request(fetchUrl, { method, headers, signal, body }), context);
|
|
330
343
|
},
|
|
331
344
|
done(onfulfilled, onrejected) {
|
|
@@ -370,7 +383,7 @@
|
|
|
370
383
|
set responseType(type) { setHeader(responseHeaders, 'content-type', type); },
|
|
371
384
|
getCookie(name) { return getCookie(sentCookies, name); },
|
|
372
385
|
setCookie(name, value, { expire, domain, path, secure, httpOnly } = {}) {
|
|
373
|
-
sentCookies.push({name, value, expire, domain, path, secure, httpOnly});
|
|
386
|
+
sentCookies.push({ name, value, expire, domain, path, secure, httpOnly });
|
|
374
387
|
setCookiesHeader(responseHeaders, sentCookies);
|
|
375
388
|
},
|
|
376
389
|
/**
|
|
@@ -388,16 +401,22 @@
|
|
|
388
401
|
return Promise.race([
|
|
389
402
|
aborted,
|
|
390
403
|
Promise.resolve().then(() => getHandler(context, v => { params = v; })),
|
|
391
|
-
]).then(
|
|
392
|
-
|
|
393
|
-
|
|
404
|
+
]).then(async handlers => {
|
|
405
|
+
const allHandlers = [handlers].flat().filter(h => typeof h === 'function');
|
|
406
|
+
if (!allHandlers.length) { return null; }
|
|
407
|
+
/** @type {HandlerResult?} */
|
|
408
|
+
let result;
|
|
409
|
+
for (const handle of allHandlers) {
|
|
410
|
+
result = await Promise.race([aborted, handle(context)]);
|
|
411
|
+
if (result !== undefined) { break; }
|
|
394
412
|
}
|
|
413
|
+
if (result instanceof Response) { return result; }
|
|
395
414
|
const headers = new Headers(context.responseHeaders);
|
|
396
415
|
const { status } = context;
|
|
397
416
|
if (!result) { return new Response(null, { status, headers }); }
|
|
398
|
-
const body = toBody(result, headers, aborted);
|
|
417
|
+
const body = toBody(result, headers, replacer, aborted);
|
|
399
418
|
return new Response(body, { status, headers });
|
|
400
|
-
})
|
|
419
|
+
}).then(response => {
|
|
401
420
|
destroyed = true;
|
|
402
421
|
resolve();
|
|
403
422
|
return response;
|
|
@@ -425,12 +444,12 @@
|
|
|
425
444
|
return r => main(r, getHandler, options);
|
|
426
445
|
}
|
|
427
446
|
|
|
428
|
-
/** @import { Context, Handler } from './main/types' */
|
|
447
|
+
/** @import { Context, Handler, HandlerResult } from './main/types' */
|
|
429
448
|
/**
|
|
430
449
|
*
|
|
431
450
|
* @param {Context} context
|
|
432
451
|
* @param {Handler[]} handlers
|
|
433
|
-
* @returns {Promise<
|
|
452
|
+
* @returns {Promise<HandlerResult>}
|
|
434
453
|
*/
|
|
435
454
|
async function runHandles(context, handlers) {
|
|
436
455
|
for (const handle of handlers) {
|
|
@@ -632,9 +651,11 @@
|
|
|
632
651
|
/** @import { Onionskin } from './onionskin.mjs' */
|
|
633
652
|
/**
|
|
634
653
|
* @callback Packer
|
|
635
|
-
* @param {Handler} handler
|
|
636
|
-
* @returns {Handler}
|
|
654
|
+
* @param {Handler | Handler[]} handler
|
|
655
|
+
* @returns {Handler | Handler[]}
|
|
637
656
|
*/
|
|
657
|
+
|
|
658
|
+
|
|
638
659
|
/** @type {Packer} */
|
|
639
660
|
const noop$1 = h => h;
|
|
640
661
|
/**
|
|
@@ -646,7 +667,7 @@
|
|
|
646
667
|
function packer(onionskin, packer = noop$1) {
|
|
647
668
|
return h => {
|
|
648
669
|
const handler = packer(h);
|
|
649
|
-
return async (ctx) => onionskin(ctx, async () => handler(
|
|
670
|
+
return async (ctx) => onionskin(ctx, async () => runHandles(ctx, [handler].flat()));
|
|
650
671
|
};
|
|
651
672
|
}
|
|
652
673
|
|
|
@@ -659,7 +680,7 @@
|
|
|
659
680
|
* @returns {PromiseLike<boolean | Handler | void> | boolean | Handler | void}
|
|
660
681
|
*/
|
|
661
682
|
/**
|
|
662
|
-
* @typedef {[Handler | Router, Record<string | symbol, any>, string[]]} FindItem
|
|
683
|
+
* @typedef {[Handler | Handler[] | Router, Record<string | symbol, any>, string[]]} FindItem
|
|
663
684
|
*/
|
|
664
685
|
/**
|
|
665
686
|
* @callback Finder
|
|
@@ -670,55 +691,6 @@
|
|
|
670
691
|
* @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
|
|
671
692
|
*/
|
|
672
693
|
|
|
673
|
-
/**
|
|
674
|
-
*
|
|
675
|
-
* @param {Set<Guard>} guards
|
|
676
|
-
* @param {Context} ctx
|
|
677
|
-
* @param {(v: any) => void} setParams
|
|
678
|
-
* @param {object} params
|
|
679
|
-
* @returns {Promise<boolean | Handler>}
|
|
680
|
-
*/
|
|
681
|
-
async function execGuard(guards, ctx, setParams, params) {
|
|
682
|
-
if (!guards.size) { return true; }
|
|
683
|
-
setParams(params);
|
|
684
|
-
for (const guard of guards) {
|
|
685
|
-
if (ctx.destroyed) { return false; }
|
|
686
|
-
const ret = await guard(Object.create(ctx, {
|
|
687
|
-
params: { value: { ...params } },
|
|
688
|
-
}));
|
|
689
|
-
if (ret === false) { return false; }
|
|
690
|
-
// @ts-ignore
|
|
691
|
-
if (typeof ret === 'function') { return ret; }
|
|
692
|
-
}
|
|
693
|
-
return true;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
/**
|
|
697
|
-
*
|
|
698
|
-
* @param {Router | Handler} route
|
|
699
|
-
* @param {string[]} path
|
|
700
|
-
* @param {Context} ctx
|
|
701
|
-
* @param {(v: Params) => void} setParams
|
|
702
|
-
* @param {Params} params
|
|
703
|
-
* @returns {Promise<Handler | null>}
|
|
704
|
-
*/
|
|
705
|
-
async function find(route, path, ctx, setParams, params) {
|
|
706
|
-
if (!(route instanceof Router)) {
|
|
707
|
-
setParams(params);
|
|
708
|
-
return route;
|
|
709
|
-
}
|
|
710
|
-
if (route.disabled) { return null; }
|
|
711
|
-
const guardResult = await execGuard(route.guards, ctx, setParams, params);
|
|
712
|
-
if (!guardResult) { return null; }
|
|
713
|
-
if (typeof guardResult === 'function') { return guardResult; }
|
|
714
|
-
if (ctx.destroyed) { return null; }
|
|
715
|
-
for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
|
|
716
|
-
if (ctx.destroyed) { return null; }
|
|
717
|
-
const res = await find(r, p, ctx, setParams, { ...params, ...result });
|
|
718
|
-
if (res) { return route.__onionskin(res); }
|
|
719
|
-
}
|
|
720
|
-
return null;
|
|
721
|
-
}
|
|
722
694
|
|
|
723
695
|
/**
|
|
724
696
|
*
|
|
@@ -737,6 +709,29 @@
|
|
|
737
709
|
*/
|
|
738
710
|
class Router {
|
|
739
711
|
disabled = false;
|
|
712
|
+
/**
|
|
713
|
+
*
|
|
714
|
+
* @param {Router | Handler[] | Handler} route
|
|
715
|
+
* @param {string[]} path
|
|
716
|
+
* @param {Context} ctx
|
|
717
|
+
* @param {(v: Params) => void} setParams
|
|
718
|
+
* @param {Params} params
|
|
719
|
+
* @returns {Promise<Handler[] | null>}
|
|
720
|
+
*/
|
|
721
|
+
static async #find(route, path, ctx, setParams, params) {
|
|
722
|
+
if (!(route instanceof Router)) {
|
|
723
|
+
setParams(params);
|
|
724
|
+
return [route].flat();
|
|
725
|
+
}
|
|
726
|
+
if (route.disabled) { return null; }
|
|
727
|
+
if (ctx.destroyed) { return null; }
|
|
728
|
+
for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
|
|
729
|
+
if (ctx.destroyed) { return null; }
|
|
730
|
+
const res = await Router.#find(r, p, ctx, setParams, { ...params, ...result });
|
|
731
|
+
if (res) { return [route.#guards, route.#onionskin(res)].flat(); }
|
|
732
|
+
}
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
740
735
|
/**
|
|
741
736
|
* @abstract
|
|
742
737
|
* @param {Method} method
|
|
@@ -755,13 +750,28 @@
|
|
|
755
750
|
const list = routers.flat();
|
|
756
751
|
const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
|
|
757
752
|
for (const route of list) {
|
|
758
|
-
const res = await find(route, path, ctx, setParams, {});
|
|
753
|
+
const res = await Router.#find(route, path, ctx, setParams, {});
|
|
759
754
|
if (res) { return res; }
|
|
760
755
|
}
|
|
761
756
|
return null;
|
|
762
757
|
};
|
|
763
758
|
}
|
|
764
759
|
|
|
760
|
+
|
|
761
|
+
/** @type {Handler[]} */
|
|
762
|
+
#guards = [];
|
|
763
|
+
/**
|
|
764
|
+
*
|
|
765
|
+
* @param {...Handler | Handler[]} guards
|
|
766
|
+
*/
|
|
767
|
+
guard(...guards) {
|
|
768
|
+
const list =this.#guards;
|
|
769
|
+
for (const guard of guards.flat()) {
|
|
770
|
+
if (typeof guard !== 'function') { continue; }
|
|
771
|
+
list.push(guard);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
765
775
|
/**
|
|
766
776
|
*
|
|
767
777
|
* @param {Finder} find
|
|
@@ -772,16 +782,14 @@
|
|
|
772
782
|
'find': { configurable: true, value: find, writable: true },
|
|
773
783
|
});
|
|
774
784
|
}
|
|
775
|
-
/** @readonly @type {Set<Guard>} */
|
|
776
|
-
guards = new Set();
|
|
777
785
|
/**
|
|
778
786
|
*
|
|
779
|
-
* @param {Handler} h
|
|
780
|
-
* @returns {Handler}
|
|
787
|
+
* @param {Handler | Handler[]} h
|
|
788
|
+
* @returns {Handler | Handler[]}
|
|
781
789
|
*/
|
|
782
|
-
|
|
790
|
+
#onionskin = (h) => h;
|
|
783
791
|
/** @param {Onionskin} os */
|
|
784
|
-
onionskin(os) { this
|
|
792
|
+
onionskin(os) { this.#onionskin = packer(os, this.#onionskin); }
|
|
785
793
|
}
|
|
786
794
|
|
|
787
795
|
/** @import { Match } from './index.mjs' */
|
|
@@ -947,6 +955,7 @@
|
|
|
947
955
|
optional: modifier === '?' || modifier === '*',
|
|
948
956
|
many: modifier === '+' || modifier === '*',
|
|
949
957
|
});
|
|
958
|
+
continue;
|
|
950
959
|
}
|
|
951
960
|
}
|
|
952
961
|
}
|
|
@@ -978,7 +987,7 @@
|
|
|
978
987
|
*/
|
|
979
988
|
function bind(routes, methods, match, handlers) {
|
|
980
989
|
/** @type {Route} */
|
|
981
|
-
const route = { match, methods,
|
|
990
|
+
const route = { match, methods, handlers: handlers };
|
|
982
991
|
routes.push(route);
|
|
983
992
|
let removed = false;
|
|
984
993
|
return () => {
|
|
@@ -1060,8 +1069,7 @@
|
|
|
1060
1069
|
* @typedef {object} Route
|
|
1061
1070
|
* @property {Match} [match] 路径匹配
|
|
1062
1071
|
* @property {null} [router]
|
|
1063
|
-
* @property {
|
|
1064
|
-
* @property {Handler} handler 处理函数
|
|
1072
|
+
* @property {Handler[]} handlers 处理函数
|
|
1065
1073
|
* @property {Set<Method>} methods 方法列表
|
|
1066
1074
|
*/
|
|
1067
1075
|
|
|
@@ -1148,14 +1156,14 @@
|
|
|
1148
1156
|
const {match} = route;
|
|
1149
1157
|
if (!match) {
|
|
1150
1158
|
if (route.router || !path.length) {
|
|
1151
|
-
yield [route.router || route.
|
|
1159
|
+
yield [route.router || route.handlers, {}, path];
|
|
1152
1160
|
}
|
|
1153
1161
|
continue;
|
|
1154
1162
|
}
|
|
1155
1163
|
if (!path.length) { continue; }
|
|
1156
1164
|
const result = match(path);
|
|
1157
1165
|
if (!result) { continue; }
|
|
1158
|
-
yield [route.router || route.
|
|
1166
|
+
yield [route.router || route.handlers, ...result];
|
|
1159
1167
|
}
|
|
1160
1168
|
}
|
|
1161
1169
|
/**
|
|
@@ -1183,25 +1191,25 @@
|
|
|
1183
1191
|
/**
|
|
1184
1192
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} methods
|
|
1185
1193
|
* @param {string| Handler} [path]
|
|
1186
|
-
* @param {Handler}
|
|
1194
|
+
* @param {...Handler} handler
|
|
1187
1195
|
* @returns {Binder | (() => void)}
|
|
1188
1196
|
*/
|
|
1189
|
-
verb(methods, path, handler) {
|
|
1197
|
+
verb(methods, path, ...handler) {
|
|
1190
1198
|
const allMethods = getMethods(methods);
|
|
1191
1199
|
if (!allMethods.length) { return () => {}; }
|
|
1192
|
-
return verb(this.#routes, allMethods, [path, handler]);
|
|
1200
|
+
return verb(this.#routes, allMethods, [path, ...handler]);
|
|
1193
1201
|
}
|
|
1194
1202
|
/**
|
|
1195
1203
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1196
1204
|
* @overload
|
|
1197
|
-
* @param {Handler}
|
|
1205
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1198
1206
|
* @returns {() => void}
|
|
1199
1207
|
*/
|
|
1200
1208
|
/**
|
|
1201
1209
|
* 注册处理函数
|
|
1202
1210
|
* @overload
|
|
1203
1211
|
* @param {string} path 要注册的路径
|
|
1204
|
-
* @param {Handler}
|
|
1212
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1205
1213
|
* @returns {() => void}
|
|
1206
1214
|
*/
|
|
1207
1215
|
/**
|
|
@@ -1227,14 +1235,14 @@
|
|
|
1227
1235
|
/**
|
|
1228
1236
|
* 注册 HTTP GET 处理函数
|
|
1229
1237
|
* @overload
|
|
1230
|
-
* @param {Handler}
|
|
1238
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1231
1239
|
* @returns {() => void}
|
|
1232
1240
|
*/
|
|
1233
1241
|
/**
|
|
1234
1242
|
* 注册 HTTP GET 处理函数
|
|
1235
1243
|
* @overload
|
|
1236
1244
|
* @param {string} path 要注册的路径
|
|
1237
|
-
* @param {Handler}
|
|
1245
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1238
1246
|
* @returns {() => void}
|
|
1239
1247
|
*/
|
|
1240
1248
|
/**
|
|
@@ -1258,14 +1266,14 @@
|
|
|
1258
1266
|
/**
|
|
1259
1267
|
* 注册 HTTP POST 处理函数
|
|
1260
1268
|
* @overload
|
|
1261
|
-
* @param {Handler}
|
|
1269
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1262
1270
|
* @returns {() => void}
|
|
1263
1271
|
*/
|
|
1264
1272
|
/**
|
|
1265
1273
|
* 注册 HTTP POST 处理函数
|
|
1266
1274
|
* @overload
|
|
1267
1275
|
* @param {string} path 要注册的路径
|
|
1268
|
-
* @param {Handler}
|
|
1276
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1269
1277
|
* @returns {() => void}
|
|
1270
1278
|
*/
|
|
1271
1279
|
/**
|
|
@@ -1289,14 +1297,14 @@
|
|
|
1289
1297
|
/**
|
|
1290
1298
|
* 注册 HTTP PUT 处理函数
|
|
1291
1299
|
* @overload
|
|
1292
|
-
* @param {Handler}
|
|
1300
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1293
1301
|
* @returns {() => void}
|
|
1294
1302
|
*/
|
|
1295
1303
|
/**
|
|
1296
1304
|
* 注册 HTTP PUT 处理函数
|
|
1297
1305
|
* @overload
|
|
1298
1306
|
* @param {string} path 要注册的路径
|
|
1299
|
-
* @param {Handler}
|
|
1307
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1300
1308
|
* @returns {() => void}
|
|
1301
1309
|
*/
|
|
1302
1310
|
/**
|
|
@@ -1320,14 +1328,14 @@
|
|
|
1320
1328
|
/**
|
|
1321
1329
|
* 注册 HTTP DELETE 处理函数
|
|
1322
1330
|
* @overload
|
|
1323
|
-
* @param {Handler}
|
|
1331
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1324
1332
|
* @returns {() => void}
|
|
1325
1333
|
*/
|
|
1326
1334
|
/**
|
|
1327
1335
|
* 注册 HTTP DELETE 处理函数
|
|
1328
1336
|
* @overload
|
|
1329
1337
|
* @param {string} path 要注册的路径
|
|
1330
|
-
* @param {Handler}
|
|
1338
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1331
1339
|
* @returns {() => void}
|
|
1332
1340
|
*/
|
|
1333
1341
|
/**
|
|
@@ -1351,14 +1359,14 @@
|
|
|
1351
1359
|
/**
|
|
1352
1360
|
* 注册 HTTP HEAD 处理函数
|
|
1353
1361
|
* @overload
|
|
1354
|
-
* @param {Handler}
|
|
1362
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1355
1363
|
* @returns {() => void}
|
|
1356
1364
|
*/
|
|
1357
1365
|
/**
|
|
1358
1366
|
* 注册 HTTP HEAD 处理函数
|
|
1359
1367
|
* @overload
|
|
1360
1368
|
* @param {string} path 要注册的路径
|
|
1361
|
-
* @param {Handler}
|
|
1369
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1362
1370
|
* @returns {() => void}
|
|
1363
1371
|
*/
|
|
1364
1372
|
/**
|
|
@@ -1382,14 +1390,14 @@
|
|
|
1382
1390
|
/**
|
|
1383
1391
|
* 注册 HTTP OPTIONS 处理函数
|
|
1384
1392
|
* @overload
|
|
1385
|
-
* @param {Handler}
|
|
1393
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1386
1394
|
* @returns {() => void}
|
|
1387
1395
|
*/
|
|
1388
1396
|
/**
|
|
1389
1397
|
* 注册 HTTP OPTIONS 处理函数
|
|
1390
1398
|
* @overload
|
|
1391
1399
|
* @param {string} path 要注册的路径
|
|
1392
|
-
* @param {Handler}
|
|
1400
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1393
1401
|
* @returns {() => void}
|
|
1394
1402
|
*/
|
|
1395
1403
|
/**
|
|
@@ -1467,7 +1475,7 @@
|
|
|
1467
1475
|
get pattern() { return this.#pattern; }
|
|
1468
1476
|
/**
|
|
1469
1477
|
*
|
|
1470
|
-
* @param {RegExp} pattern
|
|
1478
|
+
* @param {RegExp?} [pattern]
|
|
1471
1479
|
*/
|
|
1472
1480
|
constructor(pattern) {
|
|
1473
1481
|
this.#pattern = pattern;
|
package/index.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* k99 v0.
|
|
3
|
-
* (c) 2019-
|
|
2
|
+
* k99 v0.8.0
|
|
3
|
+
* (c) 2019-2026 猛火Fierflame
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).k99={})}(this,(function(t){"use strict";function e(t){return(new TextEncoder).encode(t)}function n(t){return Symbol.asyncIterator in t||Symbol.iterator in t}async function r(t,o){if("string"==typeof o)return t.write(e(o));if("object"==typeof o){if(ArrayBuffer.isView(o))return t.write(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(o instanceof ArrayBuffer)return t.write(new Uint8Array(o));if(n(o))for await(const e of o)e&&await r(t,e)}}function o(t,e){return"bigint"==typeof e?String(e):e}function s(t,s,i){const c=function(t,s){if(t instanceof ReadableStream)return[t,0,""];if(t instanceof URLSearchParams)return[t,0,""];if(t instanceof Blob)return[t,t.size,t.type];if(t instanceof FormData)return[t,0,""];if(ArrayBuffer.isView(t)||t instanceof ArrayBuffer)return[t,t.byteLength,""];if("string"==typeof t){const n=e(t);return[n,n.byteLength,""]}if("object"!=typeof t)return null;if(Array.isArray(t)||!n(t)){const n=e(JSON.stringify(t,o));return[n,n.byteLength,"application/json"]}const{writable:i,readable:c}=new TransformStream,u=i.getWriter();return s?.catch((t=>{i.abort(t||new DOMException("The user aborted a request.")).catch((()=>{}))})),(async()=>{for await(const e of t)e&&await r(u,e)})().then((()=>i.close()),(t=>i.abort(t))).catch((()=>{})),[c,0,""]}(t,i);if(!c)return null;const[u,a,f]=c;return f&&!s.get("Content-Type")&&s.set("Content-Type",f),a>0&&!s.get("Content-Length")&&s.set("Content-Length",String(a)),u}function i(t,e){t.delete("set-cookie");for(const{name:n,value:r,expire:o,domain:s,path:i,secure:c,httpOnly:u}of e)n&&t.append("set-cookie",[`${encodeURI(n)}=${encodeURI(r||"")}`,o&&`Expires=${o}`,s&&`Domain=${encodeURI(s)}`,i&&`Path=${encodeURI(i)}`,c&&"Secure",u&&"HttpOnly"].filter(Boolean).join("; "))}const c=new Set(["GET","OPTIONS"]);function u(t,e,n){n?t.set(e,n):t.delete(e)}function a(t,e,{runner:n,error:r,catch:o,method:a,environment:f}={}){return function t(l,p){const h=function(t,e){let n="";return"string"==typeof e?n=e:"function"==typeof e&&(n=e(t)),n&&"string"==typeof n||(n=t.method||"GET"),n.toUpperCase()}(l,a),y=new URL(l.url),{signal:d,headers:g}=l,m=function(t){return new Promise(((e,n)=>{if(t.aborted)return n(t.reason);t.addEventListener("abort",(()=>n(t.reason)),{once:!0})}))}(d),b=new Map,w=function(t){let e={};for(const n of t.replace(/\s/g,"").split(";")){const t=n.split("=");e[decodeURIComponent(t.shift())]=decodeURIComponent(t.join("="))}return e}(g.get("cookie")||""),O=[],T=new Headers,E=p?.root;let j=200,R=!1,S=null,A=()=>{},P=()=>{};const U=new Promise(((t,e)=>{A=t,P=e}));U.catch((()=>{}));let v={};const k={environment:f,parent:p,get error(){return S},get root(){return E||this},signal:d,url:y,fetch(e,{method:n="get",signal:r,body:o,headers:i}={}){const u=new URL(e,y),a=new Headers(i||{});if(!o||c.has(n.toUpperCase()))return t(new Request(u,{method:n,headers:a,signal:r}),k);const f=s(o,a);return t(new Request(u,{method:n,headers:a,signal:r,body:f}),k)},done(t,e){if(R)return null;const n=U.then(t,e);return n.catch(r),n},service(t,...e){if(t.rootOnly&&E)return E.service(t,...e);let n=b.get(t);if(!n){if(n=t(k),"function"!=typeof n)return;b.set(t,n)}return n(...e)},method:h,get params(){return v},requestHeaders:g,requestType:g.get("content-type")||"",referer:g.get("referer")||"",userAgent:g.get("user-agent")||"",accept:(g.get("accept")||"").split(/,\s*/).filter(Boolean),acceptLanguage:(g.get("accept-language")||"").split(/,\s*/).filter(Boolean),cookies:w,request:l,get destroyed(){return R},get status(){return j},set status(t){j=t},responseHeaders:T,get location(){return T.get("location")||""},set location(t){u(T,"location",t)},get responseType(){return T.get("content-type")||""},set responseType(t){u(T,"content-type",t)},getCookie:t=>function*(t,e){const n=t;for(const t of n)e&&t.name!==e||(yield{...t})}(O,t),setCookie(t,e,{expire:n,domain:r,path:o,secure:s,httpOnly:c}={}){O.push({name:t,value:e,expire:n,domain:r,path:o,secure:s,httpOnly:c}),i(T,O)},clearCookie(t,e){!function(t,e,n,r){let o="Fri, 31 Dec 1999 16:00:00 GMT";if("string"==typeof n){if(!n)return;const{domain:e,path:s,secure:i,httpOnly:c}=!0!==r&&r||{};t.push({name:n,value:"delete",expire:o,domain:e,path:s,secure:i,httpOnly:c})}else{const{domain:s,path:i,secure:c,httpOnly:u}=n||{};if(t.length=0,r)for(let n in e)t.push({name:n,value:"delete",expire:o,domain:s,path:i,secure:c,httpOnly:u})}}(O,w,t,e),i(T,O)}};function x(){return Promise.race([m,Promise.resolve().then((()=>e(k,(t=>{v=t}))))]).then((t=>t?Promise.race([m,t(k)]).then((t=>{if(t instanceof Response)return t;const e=new Headers(k.responseHeaders),{status:n}=k;if(!t)return new Response(null,{status:n,headers:e});const r=s(t,e,m);return new Response(r,{status:n,headers:e})})):null)).then((t=>(R=!0,A(),t)),(t=>(R=!0,S=t||!0,P(S),Promise.reject(t)))).catch(o)}return n?n(k,x):x()}(t)}async function f(t,e){for(const n of e){const e=await n(t);if(void 0!==e)return e}}const l=t=>t;function p(t,e=l){return n=>{const r=e(n);return async e=>t(e,(async()=>r(e)))}}async function h(t,e,n,r,o){if(!(t instanceof d))return r(o),t;if(t.disabled)return null;const s=await async function(t,e,n,r){if(!t.size)return!0;n(r);for(const n of t){if(e.destroyed)return!1;const t=await n(Object.create(e,{params:{value:{...r}}}));if(!1===t)return!1;if("function"==typeof t)return t}return!0}(t.guards,n,r,o);if(!s)return null;if("function"==typeof s)return s;if(n.destroyed)return null;for await(const[s,i,c]of t.find(n.method,e,n)){if(n.destroyed)return null;const e=await h(s,c,n,r,{...o,...i});if(e)return t.__onionskin(e)}return null}function y(t){try{return decodeURIComponent(t)}catch{return t}}class d{disabled=!1;find(t,e,n){return[]}static make(t){return async(e,n)=>{const r=t.flat(),o=e.url.pathname.split("/").filter(Boolean).map(y);for(const t of r){const r=await h(t,o,e,n,{});if(r)return r}return null}}static create(t){return Object.defineProperties(new d,{find:{configurable:!0,value:t,writable:!0}})}guards=new Set;__onionskin=t=>t;onionskin(t){this.__onionskin=p(t,this.__onionskin)}}const g=/^:([a-zA-Z][a-zA-Z0-9]*)(?:\((.+)\))?([ius]+)?([?+*]?)$/;function m(t){const e=g.exec(t);if(!e)return t;const[,n,r=".*",o,s]=e;if(!r)return{name:n,pattern:new RegExp("^.*$",o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s};let i=0,c=0;const u=["^(?:"];for(;i<r.length;){const e=r[i++];if(u.push(e),"\\"!==e)if(")"!==e)if("["!==e){if("("===e&&(c++,"?"===r[i]&&(i+=2,":"!==r[i-1])))return t}else for(;i<r.length;){const t=r[i++];if(u.push(t),"]"===t)break;"\\"===t&&u.push(r[i++])}else{if(0===c)return t;c--}else u.push(r[i++])}return c?t:(u.push(")$"),{name:n,pattern:new RegExp(u.join(""),o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s})}function b(t,e){const n=[];if("string"==typeof t)for(const e of t.split("/"))e&&!/^\.+$/.test(e)&&n.push(m(e));else for(const[e,r]of function*([...t],[...e]){let n=(t.shift()||"").split("/"),r=[n.pop()||""];for(const t of n)yield[[t],[]];for(const n of t){const t=n.split("/");if(t.length<=1){r.push(n);continue}const o=e.splice(0,r.length);r.push(t.shift()||""),yield[r,o],r=[t.pop()||""];for(const e of t)yield[[e],[]]}yield[r,e]}(...t)){if(2===e.length&&!e[0]){const t=e[1];if(["","?","+","*"].includes(t)){const e=r[0];if("symbol"==typeof e){n.push({name:e,pattern:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}if(e&&"object"==typeof e){const{name:r,pattern:o}=e;"symbol"==typeof r&&n.push({name:r,pattern:o instanceof RegExp?o:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t})}}}const t=e.pop()||"",o=e.map(((t,e)=>[t,r[e]])).flat();o.push(t);const s=o.join("");s&&!/^\.+$/.test(s)&&n.push(m(s))}if(n.length)return t=>function(t,e,n){const r={};for(let n=0;n<t.length;n++){const o=t[n],s=e[n];if(o!==s){if("string"==typeof o)return;if(!s)return o.optional?[r,[]]:void 0;if(!o.pattern.test(s))return;r[o.name]=s}}if(!n)return[r,e.slice(t.length)];if(e.length<=t.length)return[r,[]];const o=t[t.length-1];if("string"!=typeof o&&(o.many||!(e.length>t.length))){for(let n=t.length;n<e.length;n++)if(!o.pattern.test(e[n]))return;return r[o.name]=e.slice(t.length-1),[r,[]]}}(n,t,e)}function w(t,e,n,r){const o={match:n,methods:e,handler:t=>f(t,r)};t.push(o);let s=!1;return()=>{if(s)return;s=!0;const e=t.indexOf(o);e<0||t.splice(e,1)}}const O=t=>"function"==typeof t;function T(t,e,n){const r=new Set(e);if(!n.length){const e=void 0;return(...n)=>w(t,r,e,n)}const[o]=n;if(o&&"object"==typeof o){const e=b([o,n.slice(1)],!0);return(...n)=>w(t,r,e,n)}const s=b("string"==typeof o?o:"",!0),i=n.filter(O);return i.length?w(t,r,s,i):(...e)=>w(t,r,s,e)}const E=new Set(["GET","POST","PUT","DELETE","HEAD","OPTIONS"]);function j(t){return E.has(t)}function R(t,e,n){const r=n instanceof d?n:"function"==typeof n?d.create(n):new S;return t.push({match:b(e,!1),router:r}),r}class S extends d{#t=[];route(...t){const[e]=t;if(e&&"object"==typeof e&&!(e instanceof d))return n=>R(this.#t,[e,t.slice(1)],n);const n="string"==typeof e?e:"",r="string"==typeof e?t[1]:e;return R(this.#t,n,r)}*find(t,e,n){for(const n of Array.from(this.#t)){if(!n.router&&!n.methods.has(t))continue;const{match:r}=n;if(!r){!n.router&&e.length||(yield[n.router||n.handler,{},e]);continue}if(!e.length)continue;const o=r(e);o&&(yield[n.router||n.handler,...o])}}verb(t,e,n){const r=function(t){return t?"string"==typeof t?[t.toUpperCase()].filter(j):Array.from(t).map((t=>"string"==typeof t&&t.toUpperCase())).filter(j):["GET","POST","PUT","DELETE"]}(t);return r.length?T(this.#t,r,[e,n]):()=>{}}match(...t){return T(this.#t,["GET","POST","PUT","DELETE"],t)}get(...t){return T(this.#t,["GET"],t)}post(...t){return T(this.#t,["POST"],t)}put(...t){return T(this.#t,["PUT"],t)}delete(...t){return T(this.#t,["DELETE"],t)}head(...t){return T(this.#t,["HEAD"],t)}options(...t){return T(this.#t,["OPTIONS"],t)}}const A=()=>{};t.ApiRouter=S,t.Param=class{#e=Symbol();get name(){return this.#e}#n;get pattern(){return this.#n}constructor(t){this.#n=t}param(t){const e=t.params[this.#e];return Array.isArray(e)?e[0]??null:e??null}params(t){const e=t.params[this.#e];return"string"==typeof e?[e]:Array.isArray(e)?e:null}},t.Router=d,t.createFetch=function(t,e){return async function(n,r){const o=new Request(n,r),{signal:s}=o;s.throwIfAborted();const i=await t(o);return i||("function"==typeof e?e(o):new Response(null,{status:404}))}},t.main=a,t.make=function(t,e){return n=>a(n,t,e)},t.merge=function(...t){return e=>f(e,t.flat())},t.onionskin=function(...t){let e=A;for(const n of t.flat()){const t=e;e=async e=>n(e,(async()=>t(e)))}return e},t.packer=p,t.service=function(t,e,n){const r=function(n){return"function"==typeof e&&n.done((()=>e(n)),(t=>e(n,t))),(...e)=>t(n,...e)},{rootOnly:o}="object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r},t.stateService=function(t,e,n,r){const o=function(r){const o=t(r)||{};return"function"==typeof e&&r.done((()=>e(o,r)),(t=>e(o,r,t))),"function"!=typeof n?()=>o:()=>(n(o,r),o)},{rootOnly:s}="object"==typeof e&&e||"object"==typeof n&&n||"object"==typeof r&&r||{};return Object.assign(o,{rootOnly:Boolean(s)}),o},t.storeService=function(t,e,n){const r=function(n){let r;return"function"==typeof t&&n.done((()=>t(r,n)),(e=>t(r,n,e))),"function"!=typeof e?(...t)=>(t.length&&([r]=t),r):(...t)=>(t.length&&([r]=t,e(r,n)),r)},{rootOnly:o}="object"==typeof t&&t||"object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}}));
|
|
6
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).k99={})}(this,(function(t){"use strict";function e(t){return(new TextEncoder).encode(t)}function n(t){return Symbol.asyncIterator in t||Symbol.iterator in t}async function r(t,o){if("string"==typeof o)return t.write(e(o));if("object"==typeof o){if(ArrayBuffer.isView(o))return t.write(new Uint8Array(o.buffer,o.byteOffset,o.byteLength));if(o instanceof ArrayBuffer)return t.write(new Uint8Array(o));if(n(o))for await(const e of o)e&&await r(t,e)}}function o(t,o,s,i){const c=function(t,o,s){if(t instanceof ReadableStream)return[t,0,""];if(t instanceof URLSearchParams)return[t,0,""];if(t instanceof Blob)return[t,t.size,t.type];if(t instanceof FormData)return[t,0,""];if(ArrayBuffer.isView(t)||t instanceof ArrayBuffer)return[t,t.byteLength,""];if("string"==typeof t){const n=e(t);return[n,n.byteLength,"text/plain"]}if(["bigint","boolean","number"].includes(typeof t)){const n=e(JSON.stringify(t,o));return[n,n.byteLength,"application/json"]}if("object"!=typeof t)return null;if(Array.isArray(t)||!n(t)){const n=e(JSON.stringify(t,o));return[n,n.byteLength,"application/json"]}const{writable:i,readable:c}=new TransformStream,f=i.getWriter();return s?.catch((t=>{i.abort(t||new DOMException("The user aborted a request.")).catch((()=>{}))})),(async()=>{for await(const e of t)e&&await r(f,e)})().then((()=>i.close()),(t=>i.abort(t))).catch((()=>{})),[c,0,""]}(t,s,i);if(!c)return null;const[f,a,u]=c;return u&&!o.get("Content-Type")&&o.set("Content-Type",u),a>0&&!o.get("Content-Length")&&o.set("Content-Length",String(a)),f}function s(t,e){t.delete("set-cookie");for(const{name:n,value:r,expire:o,domain:s,path:i,secure:c,httpOnly:f}of e)n&&t.append("set-cookie",[`${encodeURI(n)}=${encodeURI(r||"")}`,o&&`Expires=${o}`,s&&`Domain=${encodeURI(s)}`,i&&`Path=${encodeURI(i)}`,c&&"Secure",f&&"HttpOnly"].filter(Boolean).join("; "))}const i=new Set(["GET","OPTIONS"]);function c(t,e,n){n?t.set(e,n):t.delete(e)}function f(t,e){return"bigint"==typeof e?String(e):e}function a(t,e,{runner:n,error:r,catch:a,method:u,environment:l,replacer:p}={}){const h="function"==typeof p?p:f;return function t(f,p){const y=function(t,e){let n="";return"string"==typeof e?n=e:"function"==typeof e&&(n=e(t)),n&&"string"==typeof n||(n=t.method||"GET"),n.toUpperCase()}(f,u),d=new URL(f.url),{signal:g,headers:m}=f,b=function(t){return new Promise(((e,n)=>{if(t.aborted)return n(t.reason);t.addEventListener("abort",(()=>n(t.reason)),{once:!0})}))}(g),w=new Map,O=function(t){let e={};for(const n of t.replace(/\s/g,"").split(";")){const t=n.split("=");e[decodeURIComponent(t.shift())]=decodeURIComponent(t.join("="))}return e}(m.get("cookie")||""),T=[],E=new Headers,j=p?.root;let R=200,S=!1,A=null,P=()=>{},U=()=>{};const k=new Promise(((t,e)=>{P=t,U=e}));k.catch((()=>{}));let v={};const x={environment:l,parent:p,get error(){return A},get root(){return j||this},signal:g,url:d,fetch(e,{method:n="get",signal:r,body:s,headers:c}={}){const f=new URL(e,d),a=new Headers(c||{});if(!s||i.has(n.toUpperCase()))return t(new Request(f,{method:n,headers:a,signal:r}),x);const u=o(s,a,h);return t(new Request(f,{method:n,headers:a,signal:r,body:u}),x)},done(t,e){if(S)return null;const n=k.then(t,e);return n.catch(r),n},service(t,...e){if(t.rootOnly&&j)return j.service(t,...e);let n=w.get(t);if(!n){if(n=t(x),"function"!=typeof n)return;w.set(t,n)}return n(...e)},method:y,get params(){return v},requestHeaders:m,requestType:m.get("content-type")||"",referer:m.get("referer")||"",userAgent:m.get("user-agent")||"",accept:(m.get("accept")||"").split(/,\s*/).filter(Boolean),acceptLanguage:(m.get("accept-language")||"").split(/,\s*/).filter(Boolean),cookies:O,request:f,get destroyed(){return S},get status(){return R},set status(t){R=t},responseHeaders:E,get location(){return E.get("location")||""},set location(t){c(E,"location",t)},get responseType(){return E.get("content-type")||""},set responseType(t){c(E,"content-type",t)},getCookie:t=>function*(t,e){const n=t;for(const t of n)e&&t.name!==e||(yield{...t})}(T,t),setCookie(t,e,{expire:n,domain:r,path:o,secure:i,httpOnly:c}={}){T.push({name:t,value:e,expire:n,domain:r,path:o,secure:i,httpOnly:c}),s(E,T)},clearCookie(t,e){!function(t,e,n,r){let o="Fri, 31 Dec 1999 16:00:00 GMT";if("string"==typeof n){if(!n)return;const{domain:e,path:s,secure:i,httpOnly:c}=!0!==r&&r||{};t.push({name:n,value:"delete",expire:o,domain:e,path:s,secure:i,httpOnly:c})}else{const{domain:s,path:i,secure:c,httpOnly:f}=n||{};if(t.length=0,r)for(let n in e)t.push({name:n,value:"delete",expire:o,domain:s,path:i,secure:c,httpOnly:f})}}(T,O,t,e),s(E,T)}};function L(){return Promise.race([b,Promise.resolve().then((()=>e(x,(t=>{v=t}))))]).then((async t=>{const e=[t].flat().filter((t=>"function"==typeof t));if(!e.length)return null;let n;for(const t of e)if(n=await Promise.race([b,t(x)]),void 0!==n)break;if(n instanceof Response)return n;const r=new Headers(x.responseHeaders),{status:s}=x;if(!n)return new Response(null,{status:s,headers:r});const i=o(n,r,h,b);return new Response(i,{status:s,headers:r})})).then((t=>(S=!0,P(),t)),(t=>(S=!0,A=t||!0,U(A),Promise.reject(t)))).catch(a)}return n?n(x,L):L()}(t)}async function u(t,e){for(const n of e){const e=await n(t);if(void 0!==e)return e}}const l=t=>t;function p(t,e=l){return n=>{const r=e(n);return async e=>t(e,(async()=>u(e,[r].flat())))}}function h(t){try{return decodeURIComponent(t)}catch{return t}}class y{disabled=!1;static async#t(t,e,n,r,o){if(!(t instanceof y))return r(o),[t].flat();if(t.disabled)return null;if(n.destroyed)return null;for await(const[s,i,c]of t.find(n.method,e,n)){if(n.destroyed)return null;const e=await y.#t(s,c,n,r,{...o,...i});if(e)return[t.#e,t.#n(e)].flat()}return null}find(t,e,n){return[]}static make(t){return async(e,n)=>{const r=t.flat(),o=e.url.pathname.split("/").filter(Boolean).map(h);for(const t of r){const r=await y.#t(t,o,e,n,{});if(r)return r}return null}}#e=[];guard(...t){const e=this.#e;for(const n of t.flat())"function"==typeof n&&e.push(n)}static create(t){return Object.defineProperties(new y,{find:{configurable:!0,value:t,writable:!0}})}#n=t=>t;onionskin(t){this.#n=p(t,this.#n)}}const d=/^:([a-zA-Z][a-zA-Z0-9]*)(?:\((.+)\))?([ius]+)?([?+*]?)$/;function g(t){const e=d.exec(t);if(!e)return t;const[,n,r=".*",o,s]=e;if(!r)return{name:n,pattern:new RegExp("^.*$",o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s};let i=0,c=0;const f=["^(?:"];for(;i<r.length;){const e=r[i++];if(f.push(e),"\\"!==e)if(")"!==e)if("["!==e){if("("===e&&(c++,"?"===r[i]&&(i+=2,":"!==r[i-1])))return t}else for(;i<r.length;){const t=r[i++];if(f.push(t),"]"===t)break;"\\"===t&&f.push(r[i++])}else{if(0===c)return t;c--}else f.push(r[i++])}return c?t:(f.push(")$"),{name:n,pattern:new RegExp(f.join(""),o),optional:"?"===s||"*"===s,many:"+"===s||"*"===s})}function m(t,e){const n=[];if("string"==typeof t)for(const e of t.split("/"))e&&!/^\.+$/.test(e)&&n.push(g(e));else for(const[e,r]of function*([...t],[...e]){let n=(t.shift()||"").split("/"),r=[n.pop()||""];for(const t of n)yield[[t],[]];for(const n of t){const t=n.split("/");if(t.length<=1){r.push(n);continue}const o=e.splice(0,r.length);r.push(t.shift()||""),yield[r,o],r=[t.pop()||""];for(const e of t)yield[[e],[]]}yield[r,e]}(...t)){if(2===e.length&&!e[0]){const t=e[1];if(["","?","+","*"].includes(t)){const e=r[0];if("symbol"==typeof e){n.push({name:e,pattern:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}if(e&&"object"==typeof e){const{name:r,pattern:o}=e;if("symbol"==typeof r){n.push({name:r,pattern:o instanceof RegExp?o:/^.*$/,optional:"?"===t||"*"===t,many:"+"===t||"*"===t});continue}}}}const t=e.pop()||"",o=e.map(((t,e)=>[t,r[e]])).flat();o.push(t);const s=o.join("");s&&!/^\.+$/.test(s)&&n.push(g(s))}if(n.length)return t=>function(t,e,n){const r={};for(let n=0;n<t.length;n++){const o=t[n],s=e[n];if(o!==s){if("string"==typeof o)return;if(!s)return o.optional?[r,[]]:void 0;if(!o.pattern.test(s))return;r[o.name]=s}}if(!n)return[r,e.slice(t.length)];if(e.length<=t.length)return[r,[]];const o=t[t.length-1];if("string"!=typeof o&&(o.many||!(e.length>t.length))){for(let n=t.length;n<e.length;n++)if(!o.pattern.test(e[n]))return;return r[o.name]=e.slice(t.length-1),[r,[]]}}(n,t,e)}function b(t,e,n,r){const o={match:n,methods:e,handlers:r};t.push(o);let s=!1;return()=>{if(s)return;s=!0;const e=t.indexOf(o);e<0||t.splice(e,1)}}const w=t=>"function"==typeof t;function O(t,e,n){const r=new Set(e);if(!n.length){const e=void 0;return(...n)=>b(t,r,e,n)}const[o]=n;if(o&&"object"==typeof o){const e=m([o,n.slice(1)],!0);return(...n)=>b(t,r,e,n)}const s=m("string"==typeof o?o:"",!0),i=n.filter(w);return i.length?b(t,r,s,i):(...e)=>b(t,r,s,e)}const T=new Set(["GET","POST","PUT","DELETE","HEAD","OPTIONS"]);function E(t){return T.has(t)}function j(t,e,n){const r=n instanceof y?n:"function"==typeof n?y.create(n):new R;return t.push({match:m(e,!1),router:r}),r}class R extends y{#r=[];route(...t){const[e]=t;if(e&&"object"==typeof e&&!(e instanceof y))return n=>j(this.#r,[e,t.slice(1)],n);const n="string"==typeof e?e:"",r="string"==typeof e?t[1]:e;return j(this.#r,n,r)}*find(t,e,n){for(const n of Array.from(this.#r)){if(!n.router&&!n.methods.has(t))continue;const{match:r}=n;if(!r){!n.router&&e.length||(yield[n.router||n.handlers,{},e]);continue}if(!e.length)continue;const o=r(e);o&&(yield[n.router||n.handlers,...o])}}verb(t,e,...n){const r=function(t){return t?"string"==typeof t?[t.toUpperCase()].filter(E):Array.from(t).map((t=>"string"==typeof t&&t.toUpperCase())).filter(E):["GET","POST","PUT","DELETE"]}(t);return r.length?O(this.#r,r,[e,...n]):()=>{}}match(...t){return O(this.#r,["GET","POST","PUT","DELETE"],t)}get(...t){return O(this.#r,["GET"],t)}post(...t){return O(this.#r,["POST"],t)}put(...t){return O(this.#r,["PUT"],t)}delete(...t){return O(this.#r,["DELETE"],t)}head(...t){return O(this.#r,["HEAD"],t)}options(...t){return O(this.#r,["OPTIONS"],t)}}const S=()=>{};t.ApiRouter=R,t.Param=class{#o=Symbol();get name(){return this.#o}#s;get pattern(){return this.#s}constructor(t){this.#s=t}param(t){const e=t.params[this.#o];return Array.isArray(e)?e[0]??null:e??null}params(t){const e=t.params[this.#o];return"string"==typeof e?[e]:Array.isArray(e)?e:null}},t.Router=y,t.createFetch=function(t,e){return async function(n,r){const o=new Request(n,r),{signal:s}=o;s.throwIfAborted();const i=await t(o);return i||("function"==typeof e?e(o):new Response(null,{status:404}))}},t.main=a,t.make=function(t,e){return n=>a(n,t,e)},t.merge=function(...t){return e=>u(e,t.flat())},t.onionskin=function(...t){let e=S;for(const n of t.flat()){const t=e;e=async e=>n(e,(async()=>t(e)))}return e},t.packer=p,t.service=function(t,e,n){const r=function(n){return"function"==typeof e&&n.done((()=>e(n)),(t=>e(n,t))),(...e)=>t(n,...e)},{rootOnly:o}="object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r},t.stateService=function(t,e,n,r){const o=function(r){const o=t(r)||{};return"function"==typeof e&&r.done((()=>e(o,r)),(t=>e(o,r,t))),"function"!=typeof n?()=>o:()=>(n(o,r),o)},{rootOnly:s}="object"==typeof e&&e||"object"==typeof n&&n||"object"==typeof r&&r||{};return Object.assign(o,{rootOnly:Boolean(s)}),o},t.storeService=function(t,e,n){const r=function(n){let r;return"function"==typeof t&&n.done((()=>t(r,n)),(e=>t(r,n,e))),"function"!=typeof e?(...t)=>(t.length&&([r]=t),r):(...t)=>(t.length&&([r]=t,e(r,n)),r)},{rootOnly:o}="object"==typeof t&&t||"object"==typeof e&&e||"object"==typeof n&&n||{};return Object.assign(r,{rootOnly:Boolean(o)}),r}}));
|