k99 0.7.1 → 0.9.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 +327 -323
- package/index.d.ts +156 -137
- package/index.js +327 -323
- package/index.min.js +3 -3
- package/index.min.mjs +3 -3
- package/index.mjs +326 -320
- 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.mjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* k99 v0.
|
|
3
|
-
* (c) 2019-
|
|
2
|
+
* k99 v0.9.0
|
|
3
|
+
* (c) 2019-2026 猛火Fierflame
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
7
|
*
|
|
8
8
|
* @param {string} str
|
|
9
|
-
* @returns {Uint8Array}
|
|
9
|
+
* @returns {Uint8Array<ArrayBuffer>}
|
|
10
10
|
*/
|
|
11
11
|
function str2utf8bin(str) {
|
|
12
|
+
// @ts-ignore
|
|
12
13
|
return new TextEncoder().encode(str);
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
@@ -47,26 +48,15 @@ async function write(writer, chunk) {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
* @param {any} k
|
|
53
|
-
* @param {any} v
|
|
54
|
-
* @returns {any}
|
|
55
|
-
*/
|
|
56
|
-
function replacer(k, v) {
|
|
57
|
-
if (typeof v === 'bigint') {
|
|
58
|
-
return String(v);
|
|
59
|
-
}
|
|
60
|
-
return v;
|
|
61
|
-
}
|
|
62
51
|
|
|
63
52
|
/**
|
|
64
53
|
*
|
|
65
54
|
* @param {any} result
|
|
55
|
+
* @param {(this: any, key: string, value: any) => any} replacer
|
|
66
56
|
* @param {Promise<never>} [aborted]
|
|
67
57
|
* @returns {[BodyInit, number, string] | null}
|
|
68
58
|
*/
|
|
69
|
-
function toBodyData(result, aborted) {
|
|
59
|
+
function toBodyData(result, replacer, aborted) {
|
|
70
60
|
if (result instanceof ReadableStream) {
|
|
71
61
|
return [result, 0, ''];
|
|
72
62
|
}
|
|
@@ -80,11 +70,16 @@ function toBodyData(result, aborted) {
|
|
|
80
70
|
return [result, 0, ''];
|
|
81
71
|
}
|
|
82
72
|
if (ArrayBuffer.isView(result) || result instanceof ArrayBuffer) {
|
|
73
|
+
// @ts-ignore
|
|
83
74
|
return [result, result.byteLength, ''];
|
|
84
75
|
}
|
|
85
76
|
if (typeof result === 'string') {
|
|
86
77
|
const body = str2utf8bin(result);
|
|
87
|
-
return [body, body.byteLength, ''];
|
|
78
|
+
return [body, body.byteLength, 'text/plain'];
|
|
79
|
+
}
|
|
80
|
+
if (['bigint', 'boolean', 'number'].includes(typeof result)) {
|
|
81
|
+
const body = str2utf8bin(JSON.stringify(result, replacer));
|
|
82
|
+
return [body, body.byteLength, 'application/json'];
|
|
88
83
|
}
|
|
89
84
|
if (typeof result !== 'object') {
|
|
90
85
|
return null;
|
|
@@ -111,11 +106,12 @@ function toBodyData(result, aborted) {
|
|
|
111
106
|
*
|
|
112
107
|
* @param {any} result
|
|
113
108
|
* @param {Headers} headers
|
|
109
|
+
* @param {(this: any, key: string, value: any) => any} replacer
|
|
114
110
|
* @param {Promise<never>} [aborted]
|
|
115
111
|
* @returns
|
|
116
112
|
*/
|
|
117
|
-
function toBody(result, headers, aborted) {
|
|
118
|
-
const bodyData = toBodyData(result, aborted);
|
|
113
|
+
function toBody(result, headers, replacer, aborted) {
|
|
114
|
+
const bodyData = toBodyData(result, replacer, aborted);
|
|
119
115
|
if (!bodyData) { return null; }
|
|
120
116
|
const [body, size, type] = bodyData;
|
|
121
117
|
if (type && !headers.get('Content-Type')) {
|
|
@@ -209,7 +205,7 @@ function clearCookie(
|
|
|
209
205
|
}
|
|
210
206
|
}
|
|
211
207
|
|
|
212
|
-
/** @import { Context, Cookie, CookieOption, FindHandler, Method, Options, Params, Service } from './types' */
|
|
208
|
+
/** @import { Context, Cookie, CookieOption, FindHandler, HandlerResult, Method, Options, Params, Service } from './types' */
|
|
213
209
|
|
|
214
210
|
|
|
215
211
|
const noBodyMethods = new Set(['GET', 'OPTIONS']);
|
|
@@ -262,6 +258,18 @@ function getMethod(request, toMethod) {
|
|
|
262
258
|
}
|
|
263
259
|
return /** @type {Method} */(methodStr.toUpperCase());
|
|
264
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
*
|
|
263
|
+
* @param {any} k
|
|
264
|
+
* @param {any} v
|
|
265
|
+
* @returns {any}
|
|
266
|
+
*/
|
|
267
|
+
function defaultReplacer(k, v) {
|
|
268
|
+
if (typeof v === 'bigint') {
|
|
269
|
+
return String(v);
|
|
270
|
+
}
|
|
271
|
+
return v;
|
|
272
|
+
}
|
|
265
273
|
/**
|
|
266
274
|
*
|
|
267
275
|
* @param {Request} request
|
|
@@ -269,10 +277,15 @@ function getMethod(request, toMethod) {
|
|
|
269
277
|
* @param {Options} [options]
|
|
270
278
|
* @returns {Promise<Response | null>}
|
|
271
279
|
*/
|
|
272
|
-
function main(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
280
|
+
function main(request, getHandler, {
|
|
281
|
+
runner,
|
|
282
|
+
error: echoError,
|
|
283
|
+
catch: catchError,
|
|
284
|
+
method: toMethod,
|
|
285
|
+
environment,
|
|
286
|
+
replacer: JSONReplacer,
|
|
287
|
+
} = {}) {
|
|
288
|
+
const replacer = typeof JSONReplacer === 'function' ? JSONReplacer : defaultReplacer;
|
|
276
289
|
/**
|
|
277
290
|
*
|
|
278
291
|
* @param {Request} request
|
|
@@ -296,12 +309,12 @@ function main(
|
|
|
296
309
|
/** @type {any} */
|
|
297
310
|
let error = null;
|
|
298
311
|
|
|
299
|
-
let resolve = () => {};
|
|
312
|
+
let resolve = () => { };
|
|
300
313
|
/** @type {(error: unknown) => void} */
|
|
301
|
-
let reject = () => {};
|
|
314
|
+
let reject = () => { };
|
|
302
315
|
/** @type {Promise<void>} */
|
|
303
316
|
const donePromise = new Promise((a, b) => { resolve = a; reject = b; });
|
|
304
|
-
donePromise.catch(() => {});
|
|
317
|
+
donePromise.catch(() => { });
|
|
305
318
|
|
|
306
319
|
/** @type {Params} */
|
|
307
320
|
let params = {};
|
|
@@ -319,7 +332,7 @@ function main(
|
|
|
319
332
|
if (!data || noBodyMethods.has(method.toUpperCase())) {
|
|
320
333
|
return exec(new Request(fetchUrl, { method, headers, signal }), context);
|
|
321
334
|
}
|
|
322
|
-
const body = toBody(data, headers);
|
|
335
|
+
const body = toBody(data, headers, replacer);
|
|
323
336
|
return exec(new Request(fetchUrl, { method, headers, signal, body }), context);
|
|
324
337
|
},
|
|
325
338
|
done(onfulfilled, onrejected) {
|
|
@@ -364,7 +377,7 @@ function main(
|
|
|
364
377
|
set responseType(type) { setHeader(responseHeaders, 'content-type', type); },
|
|
365
378
|
getCookie(name) { return getCookie(sentCookies, name); },
|
|
366
379
|
setCookie(name, value, { expire, domain, path, secure, httpOnly } = {}) {
|
|
367
|
-
sentCookies.push({name, value, expire, domain, path, secure, httpOnly});
|
|
380
|
+
sentCookies.push({ name, value, expire, domain, path, secure, httpOnly });
|
|
368
381
|
setCookiesHeader(responseHeaders, sentCookies);
|
|
369
382
|
},
|
|
370
383
|
/**
|
|
@@ -382,16 +395,22 @@ function main(
|
|
|
382
395
|
return Promise.race([
|
|
383
396
|
aborted,
|
|
384
397
|
Promise.resolve().then(() => getHandler(context, v => { params = v; })),
|
|
385
|
-
]).then(
|
|
386
|
-
|
|
387
|
-
|
|
398
|
+
]).then(async handlers => {
|
|
399
|
+
const allHandlers = [handlers].flat().filter(h => typeof h === 'function');
|
|
400
|
+
if (!allHandlers.length) { return null; }
|
|
401
|
+
/** @type {HandlerResult?} */
|
|
402
|
+
let result;
|
|
403
|
+
for (const handle of allHandlers) {
|
|
404
|
+
result = await Promise.race([aborted, handle(context)]);
|
|
405
|
+
if (result !== undefined) { break; }
|
|
388
406
|
}
|
|
407
|
+
if (result instanceof Response) { return result; }
|
|
389
408
|
const headers = new Headers(context.responseHeaders);
|
|
390
409
|
const { status } = context;
|
|
391
|
-
if (!result) { return new Response(null, { status, headers }); }
|
|
392
|
-
const body = toBody(result, headers, aborted);
|
|
410
|
+
if (!result == null) { return new Response(null, { status, headers }); }
|
|
411
|
+
const body = toBody(result, headers, replacer, aborted);
|
|
393
412
|
return new Response(body, { status, headers });
|
|
394
|
-
})
|
|
413
|
+
}).then(response => {
|
|
395
414
|
destroyed = true;
|
|
396
415
|
resolve();
|
|
397
416
|
return response;
|
|
@@ -407,40 +426,151 @@ function main(
|
|
|
407
426
|
return exec(request);
|
|
408
427
|
}
|
|
409
428
|
|
|
410
|
-
/** @import {
|
|
429
|
+
/** @import { Method, Params } from './main/types' */
|
|
411
430
|
|
|
412
431
|
/**
|
|
413
|
-
*
|
|
414
|
-
* @
|
|
415
|
-
* @param {Options} options
|
|
416
|
-
* @returns {(request: Request) => Promise<Response | null>}
|
|
432
|
+
* @template {Function} T
|
|
433
|
+
* @typedef {[T | T[] | Router<T>, Record<string | symbol, any>, string[]]} FindItem
|
|
417
434
|
*/
|
|
418
|
-
|
|
419
|
-
|
|
435
|
+
/**
|
|
436
|
+
* @template {Function} T
|
|
437
|
+
* @callback Finder
|
|
438
|
+
* @this {Router<T>}
|
|
439
|
+
* @param {Method} method
|
|
440
|
+
* @param {string[]} path
|
|
441
|
+
* @returns {AsyncIterable<FindItem<T>> | Iterable<FindItem<T>>}
|
|
442
|
+
*/
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* @abstract
|
|
446
|
+
* @template {Function} T
|
|
447
|
+
*/
|
|
448
|
+
class Router {
|
|
449
|
+
disabled = false;
|
|
450
|
+
/**
|
|
451
|
+
*
|
|
452
|
+
* @template {Function} T
|
|
453
|
+
* @param {Router<T> | T[] | T} route
|
|
454
|
+
* @param {Method} method
|
|
455
|
+
* @param {string[]} path
|
|
456
|
+
* @param {Params} params
|
|
457
|
+
* @param {AbortSignal?} [signal]
|
|
458
|
+
* @param {((v: Params) => void)?} [setParams]
|
|
459
|
+
* @returns {Promise<T[] | null>}
|
|
460
|
+
*/
|
|
461
|
+
static async #find(route, method, path, params, signal, setParams) {
|
|
462
|
+
if (!(route instanceof Router)) {
|
|
463
|
+
if (typeof setParams === 'function') { setParams(params); }
|
|
464
|
+
// @ts-ignore
|
|
465
|
+
return [route].flat();
|
|
466
|
+
}
|
|
467
|
+
if (route.disabled) { return null; }
|
|
468
|
+
if (signal?.aborted) { return null; }
|
|
469
|
+
for await (const [r, result, p] of route.find(method, path)) {
|
|
470
|
+
if (signal?.aborted) { return null; }
|
|
471
|
+
const res = await Router.#find(r, method, p, { ...params, ...result }, signal, setParams);
|
|
472
|
+
if (res) { return [...route.#guards, ...res]; }
|
|
473
|
+
}
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
*
|
|
478
|
+
* @template {Function} T
|
|
479
|
+
* @param {Router<T>[]} routers
|
|
480
|
+
* @param {Method} method
|
|
481
|
+
* @param {string[]} path
|
|
482
|
+
* @param {AbortSignal?} [signal]
|
|
483
|
+
* @param {((v: Params) => void)?} [setParams]
|
|
484
|
+
* @returns {Promise<T[] | null>}
|
|
485
|
+
*/
|
|
486
|
+
static async find(routers, method, path, signal, setParams) {
|
|
487
|
+
const m = `${method}`.toLowerCase();
|
|
488
|
+
for (const route of routers.flat()) {
|
|
489
|
+
const res = await Router.#find(route, m, path, {}, signal, setParams);
|
|
490
|
+
if (res) { return res; }
|
|
491
|
+
}
|
|
492
|
+
return null;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* @abstract
|
|
496
|
+
* @param {Method} method
|
|
497
|
+
* @param {string[]} path
|
|
498
|
+
* @returns {AsyncIterable<FindItem<T>> | Iterable<FindItem<T>>}
|
|
499
|
+
*/
|
|
500
|
+
find(method, path) { return []; }
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
/** @type {T[]} */
|
|
504
|
+
#guards = [];
|
|
505
|
+
/**
|
|
506
|
+
*
|
|
507
|
+
* @param {...T | T[]} guards
|
|
508
|
+
*/
|
|
509
|
+
guard(...guards) {
|
|
510
|
+
const list = this.#guards;
|
|
511
|
+
for (const guard of guards.flat()) {
|
|
512
|
+
if (typeof guard !== 'function') { continue; }
|
|
513
|
+
// @ts-ignore
|
|
514
|
+
list.push(guard);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
*
|
|
520
|
+
* @template {Function} T
|
|
521
|
+
* @param {Finder<T>} find
|
|
522
|
+
* @returns {Router<T>}
|
|
523
|
+
*/
|
|
524
|
+
static create(find) {
|
|
525
|
+
return Object.defineProperties(new Router(), {
|
|
526
|
+
'find': { configurable: true, value: find, writable: true },
|
|
527
|
+
});
|
|
528
|
+
}
|
|
420
529
|
}
|
|
421
530
|
|
|
422
|
-
/** @import {
|
|
531
|
+
/** @import { FindHandler, Handler, Options } from './main/types' */
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
*
|
|
535
|
+
* @param {string} t
|
|
536
|
+
* @returns
|
|
537
|
+
*/
|
|
538
|
+
function uriDecode(t) {
|
|
539
|
+
try {
|
|
540
|
+
return decodeURIComponent(t);
|
|
541
|
+
} catch {
|
|
542
|
+
return t;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
423
545
|
/**
|
|
424
546
|
*
|
|
425
|
-
* @param {
|
|
426
|
-
* @param {
|
|
427
|
-
* @returns {
|
|
547
|
+
* @param {Router<Handler> | Router<Handler>[] | FindHandler} routers
|
|
548
|
+
* @param {Options} options
|
|
549
|
+
* @returns {(request: Request) => Promise<Response | null>}
|
|
428
550
|
*/
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (result === undefined) { continue; }
|
|
433
|
-
return result;
|
|
551
|
+
function make(routers, options) {
|
|
552
|
+
if (typeof routers === 'function') {
|
|
553
|
+
return r => main(r, routers, options);
|
|
434
554
|
}
|
|
555
|
+
const list = [routers].flat();
|
|
556
|
+
/** @type {FindHandler} */
|
|
557
|
+
const getHandler = (ctx, setParams) => {
|
|
558
|
+
const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
|
|
559
|
+
return Router.find(list, ctx.method, path, ctx.signal, setParams);
|
|
560
|
+
};
|
|
561
|
+
return r => main(r, getHandler, options);
|
|
435
562
|
}
|
|
436
563
|
|
|
564
|
+
/** @import { FindHandler, Options } from './main/types' */
|
|
565
|
+
|
|
437
566
|
/**
|
|
438
567
|
*
|
|
439
|
-
* @param
|
|
440
|
-
* @
|
|
568
|
+
* @param {FindHandler} getHandler
|
|
569
|
+
* @param {Options} options
|
|
570
|
+
* @returns {(request: Request) => Promise<Response | null>}
|
|
441
571
|
*/
|
|
442
|
-
function
|
|
443
|
-
return
|
|
572
|
+
function bind$1(getHandler, options) {
|
|
573
|
+
return r => main(r, getHandler, options);
|
|
444
574
|
}
|
|
445
575
|
|
|
446
576
|
/** @import { Context, Service } from './main/types' */
|
|
@@ -622,162 +752,6 @@ function storeService(destroy, exec, options) {
|
|
|
622
752
|
return service;
|
|
623
753
|
}
|
|
624
754
|
|
|
625
|
-
/** @import { Handler } from './main/types' */
|
|
626
|
-
/** @import { Onionskin } from './onionskin.mjs' */
|
|
627
|
-
/**
|
|
628
|
-
* @callback Packer
|
|
629
|
-
* @param {Handler} handler
|
|
630
|
-
* @returns {Handler}
|
|
631
|
-
*/
|
|
632
|
-
/** @type {Packer} */
|
|
633
|
-
const noop$1 = h => h;
|
|
634
|
-
/**
|
|
635
|
-
*
|
|
636
|
-
* @param {Onionskin} onionskin
|
|
637
|
-
* @param {Packer} [packer]
|
|
638
|
-
* @returns {Packer}
|
|
639
|
-
*/
|
|
640
|
-
function packer(onionskin, packer = noop$1) {
|
|
641
|
-
return h => {
|
|
642
|
-
const handler = packer(h);
|
|
643
|
-
return async (ctx) => onionskin(ctx, async () => handler(ctx));
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
/** @import { Context, FindHandler, Handler, Method, Params } from './main/types' */
|
|
648
|
-
/** @import { Onionskin } from './onionskin.mjs' */
|
|
649
|
-
|
|
650
|
-
/**
|
|
651
|
-
* @callback Guard
|
|
652
|
-
* @param {Context} ctx
|
|
653
|
-
* @returns {PromiseLike<boolean | Handler | void> | boolean | Handler | void}
|
|
654
|
-
*/
|
|
655
|
-
/**
|
|
656
|
-
* @typedef {[Handler | Router, Record<string | symbol, any>, string[]]} FindItem
|
|
657
|
-
*/
|
|
658
|
-
/**
|
|
659
|
-
* @callback Finder
|
|
660
|
-
* @this {Router}
|
|
661
|
-
* @param {Method} method
|
|
662
|
-
* @param {string[]} path
|
|
663
|
-
* @param {Context} ctx
|
|
664
|
-
* @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
|
|
665
|
-
*/
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
*
|
|
669
|
-
* @param {Set<Guard>} guards
|
|
670
|
-
* @param {Context} ctx
|
|
671
|
-
* @param {(v: any) => void} setParams
|
|
672
|
-
* @param {object} params
|
|
673
|
-
* @returns {Promise<boolean | Handler>}
|
|
674
|
-
*/
|
|
675
|
-
async function execGuard(guards, ctx, setParams, params) {
|
|
676
|
-
if (!guards.size) { return true; }
|
|
677
|
-
setParams(params);
|
|
678
|
-
for (const guard of guards) {
|
|
679
|
-
if (ctx.destroyed) { return false; }
|
|
680
|
-
const ret = await guard(Object.create(ctx, {
|
|
681
|
-
params: { value: { ...params } },
|
|
682
|
-
}));
|
|
683
|
-
if (ret === false) { return false; }
|
|
684
|
-
// @ts-ignore
|
|
685
|
-
if (typeof ret === 'function') { return ret; }
|
|
686
|
-
}
|
|
687
|
-
return true;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
*
|
|
692
|
-
* @param {Router | Handler} route
|
|
693
|
-
* @param {string[]} path
|
|
694
|
-
* @param {Context} ctx
|
|
695
|
-
* @param {(v: Params) => void} setParams
|
|
696
|
-
* @param {Params} params
|
|
697
|
-
* @returns {Promise<Handler | null>}
|
|
698
|
-
*/
|
|
699
|
-
async function find(route, path, ctx, setParams, params) {
|
|
700
|
-
if (!(route instanceof Router)) {
|
|
701
|
-
setParams(params);
|
|
702
|
-
return route;
|
|
703
|
-
}
|
|
704
|
-
if (route.disabled) { return null; }
|
|
705
|
-
const guardResult = await execGuard(route.guards, ctx, setParams, params);
|
|
706
|
-
if (!guardResult) { return null; }
|
|
707
|
-
if (typeof guardResult === 'function') { return guardResult; }
|
|
708
|
-
if (ctx.destroyed) { return null; }
|
|
709
|
-
for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
|
|
710
|
-
if (ctx.destroyed) { return null; }
|
|
711
|
-
const res = await find(r, p, ctx, setParams, { ...params, ...result });
|
|
712
|
-
if (res) { return route.__onionskin(res); }
|
|
713
|
-
}
|
|
714
|
-
return null;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
/**
|
|
718
|
-
*
|
|
719
|
-
* @param {string} t
|
|
720
|
-
* @returns
|
|
721
|
-
*/
|
|
722
|
-
function uriDecode(t) {
|
|
723
|
-
try {
|
|
724
|
-
return decodeURIComponent(t);
|
|
725
|
-
} catch {
|
|
726
|
-
return t;
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
/**
|
|
730
|
-
* @abstract
|
|
731
|
-
*/
|
|
732
|
-
class Router {
|
|
733
|
-
disabled = false;
|
|
734
|
-
/**
|
|
735
|
-
* @abstract
|
|
736
|
-
* @param {Method} method
|
|
737
|
-
* @param {string[]} path
|
|
738
|
-
* @param {Context} ctx
|
|
739
|
-
* @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
|
|
740
|
-
*/
|
|
741
|
-
find(method, path, ctx) { return []; }
|
|
742
|
-
/**
|
|
743
|
-
*
|
|
744
|
-
* @param {Router[]} routers
|
|
745
|
-
* @returns {FindHandler}
|
|
746
|
-
*/
|
|
747
|
-
static make(routers) {
|
|
748
|
-
return async (ctx, setParams) => {
|
|
749
|
-
const list = routers.flat();
|
|
750
|
-
const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
|
|
751
|
-
for (const route of list) {
|
|
752
|
-
const res = await find(route, path, ctx, setParams, {});
|
|
753
|
-
if (res) { return res; }
|
|
754
|
-
}
|
|
755
|
-
return null;
|
|
756
|
-
};
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
*
|
|
761
|
-
* @param {Finder} find
|
|
762
|
-
* @returns {Router}
|
|
763
|
-
*/
|
|
764
|
-
static create(find) {
|
|
765
|
-
return Object.defineProperties(new Router(), {
|
|
766
|
-
'find': { configurable: true, value: find, writable: true },
|
|
767
|
-
});
|
|
768
|
-
}
|
|
769
|
-
/** @readonly @type {Set<Guard>} */
|
|
770
|
-
guards = new Set();
|
|
771
|
-
/**
|
|
772
|
-
*
|
|
773
|
-
* @param {Handler} h
|
|
774
|
-
* @returns {Handler}
|
|
775
|
-
*/
|
|
776
|
-
__onionskin = (h) => h;
|
|
777
|
-
/** @param {Onionskin} os */
|
|
778
|
-
onionskin(os) { this.__onionskin = packer(os, this.__onionskin); }
|
|
779
|
-
}
|
|
780
|
-
|
|
781
755
|
/** @import { Match } from './index.mjs' */
|
|
782
756
|
/** @import { Params } from '../main/types.js' */
|
|
783
757
|
/**
|
|
@@ -960,20 +934,21 @@ function toMatch(path, end) {
|
|
|
960
934
|
return path => exec(list, path, end);
|
|
961
935
|
}
|
|
962
936
|
|
|
963
|
-
/** @import {
|
|
937
|
+
/** @import { Method } from '../main/types' */
|
|
964
938
|
/** @import { Binder, Match, Route, RouterRoute } from './index.mjs' */
|
|
965
939
|
|
|
966
940
|
/**
|
|
967
941
|
*
|
|
968
|
-
* @
|
|
942
|
+
* @template {Function} T
|
|
943
|
+
* @param {(Route<T> | RouterRoute<T>)[]} routes
|
|
969
944
|
* @param {Set<Method>} methods
|
|
970
945
|
* @param {Match | undefined} match
|
|
971
|
-
* @param {
|
|
946
|
+
* @param {T[]} handlers
|
|
972
947
|
* @returns {() => void}
|
|
973
948
|
*/
|
|
974
949
|
function bind(routes, methods, match, handlers) {
|
|
975
|
-
/** @type {Route} */
|
|
976
|
-
const route = { match, methods,
|
|
950
|
+
/** @type {Route<T>} */
|
|
951
|
+
const route = { match, methods, handlers: handlers };
|
|
977
952
|
routes.push(route);
|
|
978
953
|
let removed = false;
|
|
979
954
|
return () => {
|
|
@@ -984,45 +959,45 @@ function bind(routes, methods, match, handlers) {
|
|
|
984
959
|
routes.splice(index, 1);
|
|
985
960
|
};
|
|
986
961
|
}
|
|
987
|
-
/** @type {(v: any) => v is
|
|
962
|
+
/** @type {(v: any) => v is Function} */
|
|
988
963
|
const findHandler = v => typeof v === 'function';
|
|
989
964
|
/**
|
|
990
965
|
*
|
|
991
|
-
* @
|
|
966
|
+
* @template {Function} T
|
|
967
|
+
* @param {(Route<T> | RouterRoute<T>)[]} routes
|
|
992
968
|
* @param {Iterable<Method>} methods
|
|
993
969
|
* @param {any[]} p
|
|
994
|
-
* @returns {Binder | (() => void)}
|
|
970
|
+
* @returns {Binder<T> | (() => void)}
|
|
995
971
|
*/
|
|
996
972
|
function verb(routes, methods, p) {
|
|
997
973
|
const methodSet = new Set(methods);
|
|
998
974
|
if (!p.length) {
|
|
999
975
|
const match = undefined;
|
|
1000
|
-
/** @type {Binder} */
|
|
976
|
+
/** @type {Binder<T>} */
|
|
1001
977
|
return (...handlers) => bind(routes, methodSet, match, handlers);
|
|
1002
978
|
}
|
|
1003
979
|
const [path] = p;
|
|
1004
980
|
if (path && typeof path === 'object') {
|
|
1005
981
|
const match = toMatch([path, p.slice(1)], true);
|
|
1006
|
-
/** @type {Binder} */
|
|
982
|
+
/** @type {Binder<T>} */
|
|
1007
983
|
return (...handlers) => bind(routes, methodSet, match, handlers);
|
|
1008
984
|
}
|
|
1009
985
|
const match = toMatch(typeof path === 'string' ? path : '', true);
|
|
1010
986
|
const handlers = p.filter(findHandler);
|
|
1011
987
|
if (!handlers.length) {
|
|
1012
|
-
/** @type {Binder} */
|
|
988
|
+
/** @type {Binder<T>} */
|
|
1013
989
|
return (...handlers) => bind(routes, methodSet, match, handlers);
|
|
1014
990
|
}
|
|
1015
991
|
return bind(routes, methodSet, match, handlers);
|
|
1016
992
|
}
|
|
1017
993
|
|
|
1018
994
|
/** @import { Method } from '../main/types' */
|
|
1019
|
-
const methods = new Set(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']);
|
|
1020
995
|
/**
|
|
1021
996
|
*
|
|
1022
997
|
* @param {any} v
|
|
1023
998
|
* @returns {v is Method}
|
|
1024
999
|
*/
|
|
1025
|
-
function isMethod(v) { return
|
|
1000
|
+
function isMethod(v) { return Boolean(v); }
|
|
1026
1001
|
/**
|
|
1027
1002
|
*
|
|
1028
1003
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} [methods]
|
|
@@ -1040,7 +1015,7 @@ function getMethods(methods) {
|
|
|
1040
1015
|
.filter(isMethod);
|
|
1041
1016
|
}
|
|
1042
1017
|
|
|
1043
|
-
/** @import {
|
|
1018
|
+
/** @import { Handler, Method, Params } from '../main/types' */
|
|
1044
1019
|
/** @import { Finder, FindItem } from '../Router.mjs' */
|
|
1045
1020
|
|
|
1046
1021
|
/**
|
|
@@ -1049,79 +1024,125 @@ function getMethods(methods) {
|
|
|
1049
1024
|
* @returns {[Params, string[]] | undefined}
|
|
1050
1025
|
*/
|
|
1051
1026
|
|
|
1052
|
-
/**
|
|
1027
|
+
/**
|
|
1028
|
+
* @template {Function} T
|
|
1029
|
+
* @typedef {(handler: T, ...handlers: T[]) => () => void} Binder
|
|
1030
|
+
*/
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* @template {Function} T
|
|
1035
|
+
* @callback Verb1
|
|
1036
|
+
* @param {T} handler 要注册的处理函数
|
|
1037
|
+
* @param {...T} handlers 要注册的处理函数
|
|
1038
|
+
* @returns {() => void}
|
|
1039
|
+
*/
|
|
1040
|
+
/**
|
|
1041
|
+
* @template {Function} T
|
|
1042
|
+
* @callback Verb2
|
|
1043
|
+
* @param {string} path 要注册的路径
|
|
1044
|
+
* @param {T} handler 要注册的处理函数
|
|
1045
|
+
* @param {...T} handlers 要注册的处理函数
|
|
1046
|
+
* @returns {() => void}
|
|
1047
|
+
*/
|
|
1048
|
+
/**
|
|
1049
|
+
* @template {Function} T
|
|
1050
|
+
* @callback Verb3
|
|
1051
|
+
* @param {string} path 要注册的路径
|
|
1052
|
+
* @returns {Binder<T>}
|
|
1053
|
+
*/
|
|
1054
|
+
/**
|
|
1055
|
+
* @template {Function} T
|
|
1056
|
+
* @callback Verb4
|
|
1057
|
+
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1058
|
+
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1059
|
+
* @returns {Binder<T>}
|
|
1060
|
+
*/
|
|
1061
|
+
/**
|
|
1062
|
+
* @template {Function} T
|
|
1063
|
+
* @typedef {Verb1<T> & Verb2<T> & Verb3<T> & Verb4<T>} Verb
|
|
1064
|
+
*/
|
|
1053
1065
|
|
|
1054
1066
|
/**
|
|
1067
|
+
* @template {Function} T
|
|
1055
1068
|
* @typedef {object} Route
|
|
1056
1069
|
* @property {Match} [match] 路径匹配
|
|
1057
1070
|
* @property {null} [router]
|
|
1058
|
-
* @property {
|
|
1059
|
-
* @property {Handler} handler 处理函数
|
|
1071
|
+
* @property {T[]} handlers 处理函数
|
|
1060
1072
|
* @property {Set<Method>} methods 方法列表
|
|
1061
1073
|
*/
|
|
1062
1074
|
|
|
1063
1075
|
/**
|
|
1076
|
+
* @template {Function} T
|
|
1064
1077
|
* @typedef {object} RouterRoute
|
|
1065
1078
|
* @property {Match} [match] 路径匹配
|
|
1066
|
-
* @property {Router} router
|
|
1079
|
+
* @property {Router<T>} router
|
|
1067
1080
|
*/
|
|
1068
1081
|
|
|
1069
1082
|
|
|
1070
1083
|
/**
|
|
1071
|
-
* @template {
|
|
1084
|
+
* @template {Function} T
|
|
1085
|
+
* @template {Router<T> | Finder<T>} [P=MapRouter<T>]
|
|
1072
1086
|
* @callback RouteBinder
|
|
1073
|
-
* @param {
|
|
1074
|
-
* @returns {
|
|
1087
|
+
* @param {P} [router] 要注册的子路由或子路由的 Finder<T>
|
|
1088
|
+
* @returns {P extends Finder<T> ? Router<T> : P}
|
|
1075
1089
|
*/
|
|
1076
1090
|
/**
|
|
1077
1091
|
*
|
|
1078
|
-
* @
|
|
1092
|
+
* @template {Function} T
|
|
1093
|
+
* @param {(Route<T> | RouterRoute<T>)[]} routes
|
|
1079
1094
|
* @param {string | [string[], any[]]} path
|
|
1080
|
-
* @param {Router | Finder} [r]
|
|
1081
|
-
* @returns {Router}
|
|
1095
|
+
* @param {Router<T> | Finder<T>} [r]
|
|
1096
|
+
* @returns {Router<T>}
|
|
1082
1097
|
*/
|
|
1083
1098
|
function bindRouter(routes, path, r) {
|
|
1099
|
+
/** @type {Router<T>} */
|
|
1084
1100
|
const router = r instanceof Router ? r
|
|
1085
1101
|
: typeof r === 'function' ? Router.create(r)
|
|
1086
|
-
: new
|
|
1102
|
+
: new MapRouter();
|
|
1087
1103
|
routes.push({ match: toMatch(path, false), router });
|
|
1088
1104
|
return router;
|
|
1089
1105
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1106
|
+
/**
|
|
1107
|
+
*
|
|
1108
|
+
* @template {Function} T
|
|
1109
|
+
* @extends {Router<T>}
|
|
1110
|
+
*/
|
|
1111
|
+
class MapRouter extends Router {
|
|
1112
|
+
/** @readonly @type {(Route<T> | RouterRoute<T>)[]} 路由列表 */
|
|
1092
1113
|
#routes = [];
|
|
1093
1114
|
/**
|
|
1094
1115
|
* 添加子路由
|
|
1095
|
-
* @template {Router | Finder} [T
|
|
1116
|
+
* @template {Router<T> | Finder<T>} [P=MapRouter<T>]
|
|
1096
1117
|
* @overload
|
|
1097
|
-
* @param {
|
|
1098
|
-
* @returns {
|
|
1118
|
+
* @param {P} [router] 要注册的子路由或子路由的 Finder<T>
|
|
1119
|
+
* @returns {P extends Finder<T> ? Router<T> : P}
|
|
1099
1120
|
*/
|
|
1100
1121
|
/**
|
|
1101
1122
|
* 添加子路由
|
|
1102
|
-
* @template {Router | Finder} [T
|
|
1123
|
+
* @template {Router<T> | Finder<T>} [P=MapRouter<T>]
|
|
1103
1124
|
* @overload
|
|
1104
1125
|
* @param {string} path 要注册的路径
|
|
1105
|
-
* @param {
|
|
1106
|
-
* @returns {
|
|
1126
|
+
* @param {P} [router] 要注册的子路由或子路由的 Finder<T>
|
|
1127
|
+
* @returns {P extends Finder<T> ? Router<T> : P}
|
|
1107
1128
|
*/
|
|
1108
1129
|
/**
|
|
1109
1130
|
* 添加子路由
|
|
1110
1131
|
* @overload
|
|
1111
1132
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1112
1133
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1113
|
-
* @returns {RouteBinder}
|
|
1134
|
+
* @returns {RouteBinder<T>}
|
|
1114
1135
|
*/
|
|
1115
1136
|
/**
|
|
1116
1137
|
* 添加子路由
|
|
1117
1138
|
* @param {...any} p 要注册的路径
|
|
1118
|
-
* @returns {Router | RouteBinder}
|
|
1139
|
+
* @returns {Router<T> | RouteBinder<T>}
|
|
1119
1140
|
*/
|
|
1120
1141
|
route(...p) {
|
|
1121
1142
|
const [a] = p;
|
|
1122
1143
|
if (a && typeof a === 'object' && !(a instanceof Router)) {
|
|
1123
1144
|
/**
|
|
1124
|
-
* @param { Finder | Router} [r];
|
|
1145
|
+
* @param { Finder<T> | Router<T>} [r];
|
|
1125
1146
|
* @returns {any}
|
|
1126
1147
|
*/
|
|
1127
1148
|
return r => bindRouter(this.#routes, [a, p.slice(1)], r);
|
|
@@ -1134,30 +1155,29 @@ class ApiRouter extends Router {
|
|
|
1134
1155
|
*
|
|
1135
1156
|
* @param {Method} method
|
|
1136
1157
|
* @param {string[]} path
|
|
1137
|
-
* @
|
|
1138
|
-
* @returns {Iterable<FindItem>}
|
|
1158
|
+
* @returns {Iterable<FindItem<T>>}
|
|
1139
1159
|
*/
|
|
1140
|
-
*find(method, path
|
|
1160
|
+
*find(method, path) {
|
|
1141
1161
|
for (const route of Array.from(this.#routes)) {
|
|
1142
1162
|
if (!route.router && !route.methods.has(method)) { continue; }
|
|
1143
1163
|
const {match} = route;
|
|
1144
1164
|
if (!match) {
|
|
1145
1165
|
if (route.router || !path.length) {
|
|
1146
|
-
yield [route.router || route.
|
|
1166
|
+
yield [route.router || route.handlers, {}, path];
|
|
1147
1167
|
}
|
|
1148
1168
|
continue;
|
|
1149
1169
|
}
|
|
1150
1170
|
if (!path.length) { continue; }
|
|
1151
1171
|
const result = match(path);
|
|
1152
1172
|
if (!result) { continue; }
|
|
1153
|
-
yield [route.router || route.
|
|
1173
|
+
yield [route.router || route.handlers, ...result];
|
|
1154
1174
|
}
|
|
1155
1175
|
}
|
|
1156
1176
|
/**
|
|
1157
1177
|
* 注册处理函数
|
|
1158
1178
|
* @overload
|
|
1159
1179
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1160
|
-
* @param {
|
|
1180
|
+
* @param {T} handler 要注册的处理函数
|
|
1161
1181
|
* @returns {() => void}
|
|
1162
1182
|
*/
|
|
1163
1183
|
/**
|
|
@@ -1165,7 +1185,7 @@ class ApiRouter extends Router {
|
|
|
1165
1185
|
* @overload
|
|
1166
1186
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1167
1187
|
* @param {string} path 要注册的路径
|
|
1168
|
-
* @param {
|
|
1188
|
+
* @param {T} handler 要注册的处理函数
|
|
1169
1189
|
* @returns {() => void}
|
|
1170
1190
|
*/
|
|
1171
1191
|
/**
|
|
@@ -1173,48 +1193,58 @@ class ApiRouter extends Router {
|
|
|
1173
1193
|
* @overload
|
|
1174
1194
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1175
1195
|
* @param {string} path 要注册的路径
|
|
1176
|
-
* @returns {Binder}
|
|
1196
|
+
* @returns {Binder<T>}
|
|
1177
1197
|
*/
|
|
1178
1198
|
/**
|
|
1179
1199
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} methods
|
|
1180
|
-
* @param {string|
|
|
1181
|
-
* @param {
|
|
1182
|
-
* @returns {Binder | (() => void)}
|
|
1200
|
+
* @param {string| T} [path]
|
|
1201
|
+
* @param {...T} handler
|
|
1202
|
+
* @returns {Binder<T> | (() => void)}
|
|
1183
1203
|
*/
|
|
1184
|
-
verb(methods, path, handler) {
|
|
1204
|
+
verb(methods, path, ...handler) {
|
|
1185
1205
|
const allMethods = getMethods(methods);
|
|
1186
1206
|
if (!allMethods.length) { return () => {}; }
|
|
1187
|
-
return verb(this.#routes, allMethods, [path, handler]);
|
|
1207
|
+
return verb(this.#routes, allMethods, [path, ...handler]);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
/**
|
|
1211
|
+
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1212
|
+
* @returns {Verb<T>}
|
|
1213
|
+
*/
|
|
1214
|
+
method(method) {
|
|
1215
|
+
const methods = getMethods(method);
|
|
1216
|
+
// @ts-ignore
|
|
1217
|
+
return (...p) => verb(this.#routes, methods, p);
|
|
1188
1218
|
}
|
|
1189
1219
|
/**
|
|
1190
1220
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1191
1221
|
* @overload
|
|
1192
|
-
* @param {
|
|
1222
|
+
* @param {...T} handlers 要注册的处理函数
|
|
1193
1223
|
* @returns {() => void}
|
|
1194
1224
|
*/
|
|
1195
1225
|
/**
|
|
1196
1226
|
* 注册处理函数
|
|
1197
1227
|
* @overload
|
|
1198
1228
|
* @param {string} path 要注册的路径
|
|
1199
|
-
* @param {
|
|
1229
|
+
* @param {...T} handlers 要注册的处理函数
|
|
1200
1230
|
* @returns {() => void}
|
|
1201
1231
|
*/
|
|
1202
1232
|
/**
|
|
1203
1233
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1204
1234
|
* @overload
|
|
1205
1235
|
* @param {string} path 要注册的路径
|
|
1206
|
-
* @returns {Binder}
|
|
1236
|
+
* @returns {Binder<T>}
|
|
1207
1237
|
*/
|
|
1208
1238
|
/**
|
|
1209
1239
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1210
1240
|
* @overload
|
|
1211
1241
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1212
1242
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1213
|
-
* @returns {Binder}
|
|
1243
|
+
* @returns {Binder<T>}
|
|
1214
1244
|
*/
|
|
1215
1245
|
/**
|
|
1216
1246
|
* @param {...any} p 要注册的路径
|
|
1217
|
-
* @returns {Binder | (() => void)}
|
|
1247
|
+
* @returns {Binder<T> | (() => void)}
|
|
1218
1248
|
*/
|
|
1219
1249
|
match(...p) {
|
|
1220
1250
|
return verb(this.#routes, ['GET', 'POST', 'PUT', 'DELETE'], p);
|
|
@@ -1222,187 +1252,187 @@ class ApiRouter extends Router {
|
|
|
1222
1252
|
/**
|
|
1223
1253
|
* 注册 HTTP GET 处理函数
|
|
1224
1254
|
* @overload
|
|
1225
|
-
* @param {Handler}
|
|
1255
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1226
1256
|
* @returns {() => void}
|
|
1227
1257
|
*/
|
|
1228
1258
|
/**
|
|
1229
1259
|
* 注册 HTTP GET 处理函数
|
|
1230
1260
|
* @overload
|
|
1231
1261
|
* @param {string} path 要注册的路径
|
|
1232
|
-
* @param {Handler}
|
|
1262
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1233
1263
|
* @returns {() => void}
|
|
1234
1264
|
*/
|
|
1235
1265
|
/**
|
|
1236
1266
|
* 注册 HTTP GET 处理函数
|
|
1237
1267
|
* @overload
|
|
1238
1268
|
* @param {string} path 要注册的路径
|
|
1239
|
-
* @returns {Binder}
|
|
1269
|
+
* @returns {Binder<T>}
|
|
1240
1270
|
*/
|
|
1241
1271
|
/**
|
|
1242
1272
|
* 注册 HTTP GET 处理函数
|
|
1243
1273
|
* @overload
|
|
1244
1274
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1245
1275
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1246
|
-
* @returns {Binder}
|
|
1276
|
+
* @returns {Binder<T>}
|
|
1247
1277
|
*/
|
|
1248
1278
|
/**
|
|
1249
1279
|
* @param {...any} p 要注册的路径
|
|
1250
|
-
* @returns {Binder | (() => void)}
|
|
1280
|
+
* @returns {Binder<T> | (() => void)}
|
|
1251
1281
|
*/
|
|
1252
1282
|
get(...p) { return verb(this.#routes, ['GET'], p); }
|
|
1253
1283
|
/**
|
|
1254
1284
|
* 注册 HTTP POST 处理函数
|
|
1255
1285
|
* @overload
|
|
1256
|
-
* @param {Handler}
|
|
1286
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1257
1287
|
* @returns {() => void}
|
|
1258
1288
|
*/
|
|
1259
1289
|
/**
|
|
1260
1290
|
* 注册 HTTP POST 处理函数
|
|
1261
1291
|
* @overload
|
|
1262
1292
|
* @param {string} path 要注册的路径
|
|
1263
|
-
* @param {Handler}
|
|
1293
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1264
1294
|
* @returns {() => void}
|
|
1265
1295
|
*/
|
|
1266
1296
|
/**
|
|
1267
1297
|
* 注册 HTTP POST 处理函数
|
|
1268
1298
|
* @overload
|
|
1269
1299
|
* @param {string} path 要注册的路径
|
|
1270
|
-
* @returns {Binder}
|
|
1300
|
+
* @returns {Binder<T>}
|
|
1271
1301
|
*/
|
|
1272
1302
|
/**
|
|
1273
1303
|
* 注册 HTTP POST 处理函数
|
|
1274
1304
|
* @overload
|
|
1275
1305
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1276
1306
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1277
|
-
* @returns {Binder}
|
|
1307
|
+
* @returns {Binder<T>}
|
|
1278
1308
|
*/
|
|
1279
1309
|
/**
|
|
1280
1310
|
* @param {...any} p 要注册的路径
|
|
1281
|
-
* @returns {Binder | (() => void)}
|
|
1311
|
+
* @returns {Binder<T> | (() => void)}
|
|
1282
1312
|
*/
|
|
1283
1313
|
post(...p) { return verb(this.#routes, ['POST'], p); }
|
|
1284
1314
|
/**
|
|
1285
1315
|
* 注册 HTTP PUT 处理函数
|
|
1286
1316
|
* @overload
|
|
1287
|
-
* @param {Handler}
|
|
1317
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1288
1318
|
* @returns {() => void}
|
|
1289
1319
|
*/
|
|
1290
1320
|
/**
|
|
1291
1321
|
* 注册 HTTP PUT 处理函数
|
|
1292
1322
|
* @overload
|
|
1293
1323
|
* @param {string} path 要注册的路径
|
|
1294
|
-
* @param {Handler}
|
|
1324
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1295
1325
|
* @returns {() => void}
|
|
1296
1326
|
*/
|
|
1297
1327
|
/**
|
|
1298
1328
|
* 注册 HTTP PUT 处理函数
|
|
1299
1329
|
* @overload
|
|
1300
1330
|
* @param {string} path 要注册的路径
|
|
1301
|
-
* @returns {Binder}
|
|
1331
|
+
* @returns {Binder<T>}
|
|
1302
1332
|
*/
|
|
1303
1333
|
/**
|
|
1304
1334
|
* 注册 HTTP PUT 处理函数
|
|
1305
1335
|
* @overload
|
|
1306
1336
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1307
1337
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1308
|
-
* @returns {Binder}
|
|
1338
|
+
* @returns {Binder<T>}
|
|
1309
1339
|
*/
|
|
1310
1340
|
/**
|
|
1311
1341
|
* @param {...any} p 要注册的路径
|
|
1312
|
-
* @returns {Binder | (() => void)}
|
|
1342
|
+
* @returns {Binder<T> | (() => void)}
|
|
1313
1343
|
*/
|
|
1314
1344
|
put(...p) { return verb(this.#routes, ['PUT'], p); }
|
|
1315
1345
|
/**
|
|
1316
1346
|
* 注册 HTTP DELETE 处理函数
|
|
1317
1347
|
* @overload
|
|
1318
|
-
* @param {Handler}
|
|
1348
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1319
1349
|
* @returns {() => void}
|
|
1320
1350
|
*/
|
|
1321
1351
|
/**
|
|
1322
1352
|
* 注册 HTTP DELETE 处理函数
|
|
1323
1353
|
* @overload
|
|
1324
1354
|
* @param {string} path 要注册的路径
|
|
1325
|
-
* @param {Handler}
|
|
1355
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1326
1356
|
* @returns {() => void}
|
|
1327
1357
|
*/
|
|
1328
1358
|
/**
|
|
1329
1359
|
* 注册 HTTP DELETE 处理函数
|
|
1330
1360
|
* @overload
|
|
1331
1361
|
* @param {string} path 要注册的路径
|
|
1332
|
-
* @returns {Binder}
|
|
1362
|
+
* @returns {Binder<T>}
|
|
1333
1363
|
*/
|
|
1334
1364
|
/**
|
|
1335
1365
|
* 注册 HTTP DELETE 处理函数
|
|
1336
1366
|
* @overload
|
|
1337
1367
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1338
1368
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1339
|
-
* @returns {Binder}
|
|
1369
|
+
* @returns {Binder<T>}
|
|
1340
1370
|
*/
|
|
1341
1371
|
/**
|
|
1342
1372
|
* @param {...any} p 要注册的路径
|
|
1343
|
-
* @returns {Binder | (() => void)}
|
|
1373
|
+
* @returns {Binder<T> | (() => void)}
|
|
1344
1374
|
*/
|
|
1345
1375
|
delete(...p) { return verb(this.#routes, ['DELETE'], p); }
|
|
1346
1376
|
/**
|
|
1347
1377
|
* 注册 HTTP HEAD 处理函数
|
|
1348
1378
|
* @overload
|
|
1349
|
-
* @param {Handler}
|
|
1379
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1350
1380
|
* @returns {() => void}
|
|
1351
1381
|
*/
|
|
1352
1382
|
/**
|
|
1353
1383
|
* 注册 HTTP HEAD 处理函数
|
|
1354
1384
|
* @overload
|
|
1355
1385
|
* @param {string} path 要注册的路径
|
|
1356
|
-
* @param {Handler}
|
|
1386
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1357
1387
|
* @returns {() => void}
|
|
1358
1388
|
*/
|
|
1359
1389
|
/**
|
|
1360
1390
|
* 注册 HTTP HEAD 处理函数
|
|
1361
1391
|
* @overload
|
|
1362
1392
|
* @param {string} path 要注册的路径
|
|
1363
|
-
* @returns {Binder}
|
|
1393
|
+
* @returns {Binder<T>}
|
|
1364
1394
|
*/
|
|
1365
1395
|
/**
|
|
1366
1396
|
* 注册 HTTP HEAD 处理函数
|
|
1367
1397
|
* @overload
|
|
1368
1398
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1369
1399
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1370
|
-
* @returns {Binder}
|
|
1400
|
+
* @returns {Binder<T>}
|
|
1371
1401
|
*/
|
|
1372
1402
|
/**
|
|
1373
1403
|
* @param {...any} p 要注册的路径
|
|
1374
|
-
* @returns {Binder | (() => void)}
|
|
1404
|
+
* @returns {Binder<T> | (() => void)}
|
|
1375
1405
|
*/
|
|
1376
1406
|
head(...p) { return verb(this.#routes, ['HEAD'], p); }
|
|
1377
1407
|
/**
|
|
1378
1408
|
* 注册 HTTP OPTIONS 处理函数
|
|
1379
1409
|
* @overload
|
|
1380
|
-
* @param {Handler}
|
|
1410
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1381
1411
|
* @returns {() => void}
|
|
1382
1412
|
*/
|
|
1383
1413
|
/**
|
|
1384
1414
|
* 注册 HTTP OPTIONS 处理函数
|
|
1385
1415
|
* @overload
|
|
1386
1416
|
* @param {string} path 要注册的路径
|
|
1387
|
-
* @param {Handler}
|
|
1417
|
+
* @param {...Handler} handlers 要注册的处理函数
|
|
1388
1418
|
* @returns {() => void}
|
|
1389
1419
|
*/
|
|
1390
1420
|
/**
|
|
1391
1421
|
* 注册 HTTP OPTIONS 处理函数
|
|
1392
1422
|
* @overload
|
|
1393
1423
|
* @param {string} path 要注册的路径
|
|
1394
|
-
* @returns {Binder}
|
|
1424
|
+
* @returns {Binder<T>}
|
|
1395
1425
|
*/
|
|
1396
1426
|
/**
|
|
1397
1427
|
* 注册 HTTP OPTIONS 处理函数
|
|
1398
1428
|
* @overload
|
|
1399
1429
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1400
1430
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1401
|
-
* @returns {Binder}
|
|
1431
|
+
* @returns {Binder<T>}
|
|
1402
1432
|
*/
|
|
1403
1433
|
/**
|
|
1404
1434
|
* @param {...any} p 要注册的路径
|
|
1405
|
-
* @returns {Binder | (() => void)}
|
|
1435
|
+
* @returns {Binder<T> | (() => void)}
|
|
1406
1436
|
*/
|
|
1407
1437
|
options(...p) { return verb(this.#routes, ['OPTIONS'], p); }
|
|
1408
1438
|
}
|
|
@@ -1430,30 +1460,6 @@ function createFetch(run, notFound) {
|
|
|
1430
1460
|
};
|
|
1431
1461
|
}
|
|
1432
1462
|
|
|
1433
|
-
/** @import { Context, Handler, HandlerResult } from './main/types' */
|
|
1434
|
-
/**
|
|
1435
|
-
* @callback Onionskin
|
|
1436
|
-
* @param {Context} ctx
|
|
1437
|
-
* @param {() => Promise<HandlerResult>} next
|
|
1438
|
-
* @returns {PromiseLike<HandlerResult> | HandlerResult}
|
|
1439
|
-
*/
|
|
1440
|
-
|
|
1441
|
-
const noop = () => {};
|
|
1442
|
-
/**
|
|
1443
|
-
*
|
|
1444
|
-
* @param {...(Onionskin | Onionskin[])} handlers
|
|
1445
|
-
* @returns {Handler}
|
|
1446
|
-
*/
|
|
1447
|
-
function onionskin(...handlers) {
|
|
1448
|
-
/** @type {Handler} */
|
|
1449
|
-
let handler = noop;
|
|
1450
|
-
for (const os of handlers.flat()) {
|
|
1451
|
-
const currentHandler = handler;
|
|
1452
|
-
handler = async ctx => os(ctx, async () => currentHandler(ctx));
|
|
1453
|
-
}
|
|
1454
|
-
return handler;
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
1463
|
/** @import { Context } from './main/types.js' */
|
|
1458
1464
|
class Param {
|
|
1459
1465
|
#symbol = Symbol();
|
|
@@ -1490,4 +1496,4 @@ class Param {
|
|
|
1490
1496
|
}
|
|
1491
1497
|
}
|
|
1492
1498
|
|
|
1493
|
-
export {
|
|
1499
|
+
export { MapRouter, Param, Router, bind$1 as bind, createFetch, main, make, service, stateService, storeService };
|