k99 0.8.0 → 0.9.1
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 +258 -261
- package/index.d.ts +121 -105
- package/index.js +258 -261
- package/index.min.js +2 -2
- package/index.min.mjs +2 -2
- package/index.mjs +257 -258
- package/package.json +1 -1
- package/services.cjs +1 -1
- package/services.d.ts +1 -1
- package/services.js +1 -1
- package/services.min.js +1 -1
- package/services.min.mjs +1 -1
- package/services.mjs +1 -1
package/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* k99 v0.
|
|
2
|
+
* k99 v0.9.1
|
|
3
3
|
* (c) 2019-2026 猛火Fierflame
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -407,7 +407,7 @@ function main(request, getHandler, {
|
|
|
407
407
|
if (result instanceof Response) { return result; }
|
|
408
408
|
const headers = new Headers(context.responseHeaders);
|
|
409
409
|
const { status } = context;
|
|
410
|
-
if (!result) { return new Response(null, { status, headers }); }
|
|
410
|
+
if (!result == null) { return new Response(null, { status, headers }); }
|
|
411
411
|
const body = toBody(result, headers, replacer, aborted);
|
|
412
412
|
return new Response(body, { status, headers });
|
|
413
413
|
}).then(response => {
|
|
@@ -426,40 +426,151 @@ function main(request, getHandler, {
|
|
|
426
426
|
return exec(request);
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
/** @import {
|
|
429
|
+
/** @import { Method, Params } from './main/types' */
|
|
430
430
|
|
|
431
431
|
/**
|
|
432
|
-
*
|
|
433
|
-
* @
|
|
434
|
-
* @param {Options} options
|
|
435
|
-
* @returns {(request: Request) => Promise<Response | null>}
|
|
432
|
+
* @template {Function} T
|
|
433
|
+
* @typedef {[T | T[] | Router<T>, Record<string | symbol, any>, string[]]} FindItem
|
|
436
434
|
*/
|
|
437
|
-
|
|
438
|
-
|
|
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}`.toUpperCase();
|
|
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
|
+
}
|
|
439
529
|
}
|
|
440
530
|
|
|
441
|
-
/** @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
|
+
}
|
|
442
545
|
/**
|
|
443
546
|
*
|
|
444
|
-
* @param {
|
|
445
|
-
* @param {
|
|
446
|
-
* @returns {Promise<
|
|
547
|
+
* @param {Router<Handler> | Router<Handler>[] | FindHandler} routers
|
|
548
|
+
* @param {Options} options
|
|
549
|
+
* @returns {(request: Request) => Promise<Response | null>}
|
|
447
550
|
*/
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (result === undefined) { continue; }
|
|
452
|
-
return result;
|
|
551
|
+
function make(routers, options) {
|
|
552
|
+
if (typeof routers === 'function') {
|
|
553
|
+
return r => main(r, routers, options);
|
|
453
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);
|
|
454
562
|
}
|
|
455
563
|
|
|
564
|
+
/** @import { FindHandler, Options } from './main/types' */
|
|
565
|
+
|
|
456
566
|
/**
|
|
457
567
|
*
|
|
458
|
-
* @param
|
|
459
|
-
* @
|
|
568
|
+
* @param {FindHandler} getHandler
|
|
569
|
+
* @param {Options} options
|
|
570
|
+
* @returns {(request: Request) => Promise<Response | null>}
|
|
460
571
|
*/
|
|
461
|
-
function
|
|
462
|
-
return
|
|
572
|
+
function bind$1(getHandler, options) {
|
|
573
|
+
return r => main(r, getHandler, options);
|
|
463
574
|
}
|
|
464
575
|
|
|
465
576
|
/** @import { Context, Service } from './main/types' */
|
|
@@ -641,151 +752,6 @@ function storeService(destroy, exec, options) {
|
|
|
641
752
|
return service;
|
|
642
753
|
}
|
|
643
754
|
|
|
644
|
-
/** @import { Handler } from './main/types' */
|
|
645
|
-
/** @import { Onionskin } from './onionskin.mjs' */
|
|
646
|
-
/**
|
|
647
|
-
* @callback Packer
|
|
648
|
-
* @param {Handler | Handler[]} handler
|
|
649
|
-
* @returns {Handler | Handler[]}
|
|
650
|
-
*/
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
/** @type {Packer} */
|
|
654
|
-
const noop$1 = h => h;
|
|
655
|
-
/**
|
|
656
|
-
*
|
|
657
|
-
* @param {Onionskin} onionskin
|
|
658
|
-
* @param {Packer} [packer]
|
|
659
|
-
* @returns {Packer}
|
|
660
|
-
*/
|
|
661
|
-
function packer(onionskin, packer = noop$1) {
|
|
662
|
-
return h => {
|
|
663
|
-
const handler = packer(h);
|
|
664
|
-
return async (ctx) => onionskin(ctx, async () => runHandles(ctx, [handler].flat()));
|
|
665
|
-
};
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
/** @import { Context, FindHandler, Handler, Method, Params } from './main/types' */
|
|
669
|
-
/** @import { Onionskin } from './onionskin.mjs' */
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* @callback Guard
|
|
673
|
-
* @param {Context} ctx
|
|
674
|
-
* @returns {PromiseLike<boolean | Handler | void> | boolean | Handler | void}
|
|
675
|
-
*/
|
|
676
|
-
/**
|
|
677
|
-
* @typedef {[Handler | Handler[] | Router, Record<string | symbol, any>, string[]]} FindItem
|
|
678
|
-
*/
|
|
679
|
-
/**
|
|
680
|
-
* @callback Finder
|
|
681
|
-
* @this {Router}
|
|
682
|
-
* @param {Method} method
|
|
683
|
-
* @param {string[]} path
|
|
684
|
-
* @param {Context} ctx
|
|
685
|
-
* @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
|
|
686
|
-
*/
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
/**
|
|
690
|
-
*
|
|
691
|
-
* @param {string} t
|
|
692
|
-
* @returns
|
|
693
|
-
*/
|
|
694
|
-
function uriDecode(t) {
|
|
695
|
-
try {
|
|
696
|
-
return decodeURIComponent(t);
|
|
697
|
-
} catch {
|
|
698
|
-
return t;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* @abstract
|
|
703
|
-
*/
|
|
704
|
-
class Router {
|
|
705
|
-
disabled = false;
|
|
706
|
-
/**
|
|
707
|
-
*
|
|
708
|
-
* @param {Router | Handler[] | Handler} route
|
|
709
|
-
* @param {string[]} path
|
|
710
|
-
* @param {Context} ctx
|
|
711
|
-
* @param {(v: Params) => void} setParams
|
|
712
|
-
* @param {Params} params
|
|
713
|
-
* @returns {Promise<Handler[] | null>}
|
|
714
|
-
*/
|
|
715
|
-
static async #find(route, path, ctx, setParams, params) {
|
|
716
|
-
if (!(route instanceof Router)) {
|
|
717
|
-
setParams(params);
|
|
718
|
-
return [route].flat();
|
|
719
|
-
}
|
|
720
|
-
if (route.disabled) { return null; }
|
|
721
|
-
if (ctx.destroyed) { return null; }
|
|
722
|
-
for await (const [r, result, p] of route.find(ctx.method, path, ctx)) {
|
|
723
|
-
if (ctx.destroyed) { return null; }
|
|
724
|
-
const res = await Router.#find(r, p, ctx, setParams, { ...params, ...result });
|
|
725
|
-
if (res) { return [route.#guards, route.#onionskin(res)].flat(); }
|
|
726
|
-
}
|
|
727
|
-
return null;
|
|
728
|
-
}
|
|
729
|
-
/**
|
|
730
|
-
* @abstract
|
|
731
|
-
* @param {Method} method
|
|
732
|
-
* @param {string[]} path
|
|
733
|
-
* @param {Context} ctx
|
|
734
|
-
* @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
|
|
735
|
-
*/
|
|
736
|
-
find(method, path, ctx) { return []; }
|
|
737
|
-
/**
|
|
738
|
-
*
|
|
739
|
-
* @param {Router[]} routers
|
|
740
|
-
* @returns {FindHandler}
|
|
741
|
-
*/
|
|
742
|
-
static make(routers) {
|
|
743
|
-
return async (ctx, setParams) => {
|
|
744
|
-
const list = routers.flat();
|
|
745
|
-
const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
|
|
746
|
-
for (const route of list) {
|
|
747
|
-
const res = await Router.#find(route, path, ctx, setParams, {});
|
|
748
|
-
if (res) { return res; }
|
|
749
|
-
}
|
|
750
|
-
return null;
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
/** @type {Handler[]} */
|
|
756
|
-
#guards = [];
|
|
757
|
-
/**
|
|
758
|
-
*
|
|
759
|
-
* @param {...Handler | Handler[]} guards
|
|
760
|
-
*/
|
|
761
|
-
guard(...guards) {
|
|
762
|
-
const list =this.#guards;
|
|
763
|
-
for (const guard of guards.flat()) {
|
|
764
|
-
if (typeof guard !== 'function') { continue; }
|
|
765
|
-
list.push(guard);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
/**
|
|
770
|
-
*
|
|
771
|
-
* @param {Finder} find
|
|
772
|
-
* @returns {Router}
|
|
773
|
-
*/
|
|
774
|
-
static create(find) {
|
|
775
|
-
return Object.defineProperties(new Router(), {
|
|
776
|
-
'find': { configurable: true, value: find, writable: true },
|
|
777
|
-
});
|
|
778
|
-
}
|
|
779
|
-
/**
|
|
780
|
-
*
|
|
781
|
-
* @param {Handler | Handler[]} h
|
|
782
|
-
* @returns {Handler | Handler[]}
|
|
783
|
-
*/
|
|
784
|
-
#onionskin = (h) => h;
|
|
785
|
-
/** @param {Onionskin} os */
|
|
786
|
-
onionskin(os) { this.#onionskin = packer(os, this.#onionskin); }
|
|
787
|
-
}
|
|
788
|
-
|
|
789
755
|
/** @import { Match } from './index.mjs' */
|
|
790
756
|
/** @import { Params } from '../main/types.js' */
|
|
791
757
|
/**
|
|
@@ -968,19 +934,20 @@ function toMatch(path, end) {
|
|
|
968
934
|
return path => exec(list, path, end);
|
|
969
935
|
}
|
|
970
936
|
|
|
971
|
-
/** @import {
|
|
937
|
+
/** @import { Method } from '../main/types' */
|
|
972
938
|
/** @import { Binder, Match, Route, RouterRoute } from './index.mjs' */
|
|
973
939
|
|
|
974
940
|
/**
|
|
975
941
|
*
|
|
976
|
-
* @
|
|
942
|
+
* @template {Function} T
|
|
943
|
+
* @param {(Route<T> | RouterRoute<T>)[]} routes
|
|
977
944
|
* @param {Set<Method>} methods
|
|
978
945
|
* @param {Match | undefined} match
|
|
979
|
-
* @param {
|
|
946
|
+
* @param {T[]} handlers
|
|
980
947
|
* @returns {() => void}
|
|
981
948
|
*/
|
|
982
949
|
function bind(routes, methods, match, handlers) {
|
|
983
|
-
/** @type {Route} */
|
|
950
|
+
/** @type {Route<T>} */
|
|
984
951
|
const route = { match, methods, handlers: handlers };
|
|
985
952
|
routes.push(route);
|
|
986
953
|
let removed = false;
|
|
@@ -992,45 +959,45 @@ function bind(routes, methods, match, handlers) {
|
|
|
992
959
|
routes.splice(index, 1);
|
|
993
960
|
};
|
|
994
961
|
}
|
|
995
|
-
/** @type {(v: any) => v is
|
|
962
|
+
/** @type {(v: any) => v is Function} */
|
|
996
963
|
const findHandler = v => typeof v === 'function';
|
|
997
964
|
/**
|
|
998
965
|
*
|
|
999
|
-
* @
|
|
966
|
+
* @template {Function} T
|
|
967
|
+
* @param {(Route<T> | RouterRoute<T>)[]} routes
|
|
1000
968
|
* @param {Iterable<Method>} methods
|
|
1001
969
|
* @param {any[]} p
|
|
1002
|
-
* @returns {Binder | (() => void)}
|
|
970
|
+
* @returns {Binder<T> | (() => void)}
|
|
1003
971
|
*/
|
|
1004
972
|
function verb(routes, methods, p) {
|
|
1005
973
|
const methodSet = new Set(methods);
|
|
1006
974
|
if (!p.length) {
|
|
1007
975
|
const match = undefined;
|
|
1008
|
-
/** @type {Binder} */
|
|
976
|
+
/** @type {Binder<T>} */
|
|
1009
977
|
return (...handlers) => bind(routes, methodSet, match, handlers);
|
|
1010
978
|
}
|
|
1011
979
|
const [path] = p;
|
|
1012
980
|
if (path && typeof path === 'object') {
|
|
1013
981
|
const match = toMatch([path, p.slice(1)], true);
|
|
1014
|
-
/** @type {Binder} */
|
|
982
|
+
/** @type {Binder<T>} */
|
|
1015
983
|
return (...handlers) => bind(routes, methodSet, match, handlers);
|
|
1016
984
|
}
|
|
1017
985
|
const match = toMatch(typeof path === 'string' ? path : '', true);
|
|
1018
986
|
const handlers = p.filter(findHandler);
|
|
1019
987
|
if (!handlers.length) {
|
|
1020
|
-
/** @type {Binder} */
|
|
988
|
+
/** @type {Binder<T>} */
|
|
1021
989
|
return (...handlers) => bind(routes, methodSet, match, handlers);
|
|
1022
990
|
}
|
|
1023
991
|
return bind(routes, methodSet, match, handlers);
|
|
1024
992
|
}
|
|
1025
993
|
|
|
1026
994
|
/** @import { Method } from '../main/types' */
|
|
1027
|
-
const methods = new Set(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']);
|
|
1028
995
|
/**
|
|
1029
996
|
*
|
|
1030
997
|
* @param {any} v
|
|
1031
998
|
* @returns {v is Method}
|
|
1032
999
|
*/
|
|
1033
|
-
function isMethod(v) { return
|
|
1000
|
+
function isMethod(v) { return Boolean(v); }
|
|
1034
1001
|
/**
|
|
1035
1002
|
*
|
|
1036
1003
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} [methods]
|
|
@@ -1048,7 +1015,7 @@ function getMethods(methods) {
|
|
|
1048
1015
|
.filter(isMethod);
|
|
1049
1016
|
}
|
|
1050
1017
|
|
|
1051
|
-
/** @import {
|
|
1018
|
+
/** @import { Handler, Method, Params } from '../main/types' */
|
|
1052
1019
|
/** @import { Finder, FindItem } from '../Router.mjs' */
|
|
1053
1020
|
|
|
1054
1021
|
/**
|
|
@@ -1057,78 +1024,125 @@ function getMethods(methods) {
|
|
|
1057
1024
|
* @returns {[Params, string[]] | undefined}
|
|
1058
1025
|
*/
|
|
1059
1026
|
|
|
1060
|
-
/**
|
|
1027
|
+
/**
|
|
1028
|
+
* @template {Function} T
|
|
1029
|
+
* @typedef {(handler: T, ...handlers: T[]) => () => void} Binder
|
|
1030
|
+
*/
|
|
1031
|
+
|
|
1061
1032
|
|
|
1062
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
|
+
*/
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
* @template {Function} T
|
|
1063
1068
|
* @typedef {object} Route
|
|
1064
1069
|
* @property {Match} [match] 路径匹配
|
|
1065
1070
|
* @property {null} [router]
|
|
1066
|
-
* @property {
|
|
1071
|
+
* @property {T[]} handlers 处理函数
|
|
1067
1072
|
* @property {Set<Method>} methods 方法列表
|
|
1068
1073
|
*/
|
|
1069
1074
|
|
|
1070
1075
|
/**
|
|
1076
|
+
* @template {Function} T
|
|
1071
1077
|
* @typedef {object} RouterRoute
|
|
1072
1078
|
* @property {Match} [match] 路径匹配
|
|
1073
|
-
* @property {Router} router
|
|
1079
|
+
* @property {Router<T>} router
|
|
1074
1080
|
*/
|
|
1075
1081
|
|
|
1076
1082
|
|
|
1077
1083
|
/**
|
|
1078
|
-
* @template {
|
|
1084
|
+
* @template {Function} T
|
|
1085
|
+
* @template {Router<T> | Finder<T>} [P=MapRouter<T>]
|
|
1079
1086
|
* @callback RouteBinder
|
|
1080
|
-
* @param {
|
|
1081
|
-
* @returns {
|
|
1087
|
+
* @param {P} [router] 要注册的子路由或子路由的 Finder<T>
|
|
1088
|
+
* @returns {P extends Finder<T> ? Router<T> : P}
|
|
1082
1089
|
*/
|
|
1083
1090
|
/**
|
|
1084
1091
|
*
|
|
1085
|
-
* @
|
|
1092
|
+
* @template {Function} T
|
|
1093
|
+
* @param {(Route<T> | RouterRoute<T>)[]} routes
|
|
1086
1094
|
* @param {string | [string[], any[]]} path
|
|
1087
|
-
* @param {Router | Finder} [r]
|
|
1088
|
-
* @returns {Router}
|
|
1095
|
+
* @param {Router<T> | Finder<T>} [r]
|
|
1096
|
+
* @returns {Router<T>}
|
|
1089
1097
|
*/
|
|
1090
1098
|
function bindRouter(routes, path, r) {
|
|
1099
|
+
/** @type {Router<T>} */
|
|
1091
1100
|
const router = r instanceof Router ? r
|
|
1092
1101
|
: typeof r === 'function' ? Router.create(r)
|
|
1093
|
-
: new
|
|
1102
|
+
: new MapRouter();
|
|
1094
1103
|
routes.push({ match: toMatch(path, false), router });
|
|
1095
1104
|
return router;
|
|
1096
1105
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1106
|
+
/**
|
|
1107
|
+
*
|
|
1108
|
+
* @template {Function} T
|
|
1109
|
+
* @extends {Router<T>}
|
|
1110
|
+
*/
|
|
1111
|
+
class MapRouter extends Router {
|
|
1112
|
+
/** @readonly @type {(Route<T> | RouterRoute<T>)[]} 路由列表 */
|
|
1099
1113
|
#routes = [];
|
|
1100
1114
|
/**
|
|
1101
1115
|
* 添加子路由
|
|
1102
|
-
* @template {Router | Finder} [T
|
|
1116
|
+
* @template {Router<T> | Finder<T>} [P=MapRouter<T>]
|
|
1103
1117
|
* @overload
|
|
1104
|
-
* @param {
|
|
1105
|
-
* @returns {
|
|
1118
|
+
* @param {P} [router] 要注册的子路由或子路由的 Finder<T>
|
|
1119
|
+
* @returns {P extends Finder<T> ? Router<T> : P}
|
|
1106
1120
|
*/
|
|
1107
1121
|
/**
|
|
1108
1122
|
* 添加子路由
|
|
1109
|
-
* @template {Router | Finder} [T
|
|
1123
|
+
* @template {Router<T> | Finder<T>} [P=MapRouter<T>]
|
|
1110
1124
|
* @overload
|
|
1111
1125
|
* @param {string} path 要注册的路径
|
|
1112
|
-
* @param {
|
|
1113
|
-
* @returns {
|
|
1126
|
+
* @param {P} [router] 要注册的子路由或子路由的 Finder<T>
|
|
1127
|
+
* @returns {P extends Finder<T> ? Router<T> : P}
|
|
1114
1128
|
*/
|
|
1115
1129
|
/**
|
|
1116
1130
|
* 添加子路由
|
|
1117
1131
|
* @overload
|
|
1118
1132
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1119
1133
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1120
|
-
* @returns {RouteBinder}
|
|
1134
|
+
* @returns {RouteBinder<T>}
|
|
1121
1135
|
*/
|
|
1122
1136
|
/**
|
|
1123
1137
|
* 添加子路由
|
|
1124
1138
|
* @param {...any} p 要注册的路径
|
|
1125
|
-
* @returns {Router | RouteBinder}
|
|
1139
|
+
* @returns {Router<T> | RouteBinder<T>}
|
|
1126
1140
|
*/
|
|
1127
1141
|
route(...p) {
|
|
1128
1142
|
const [a] = p;
|
|
1129
1143
|
if (a && typeof a === 'object' && !(a instanceof Router)) {
|
|
1130
1144
|
/**
|
|
1131
|
-
* @param { Finder | Router} [r];
|
|
1145
|
+
* @param { Finder<T> | Router<T>} [r];
|
|
1132
1146
|
* @returns {any}
|
|
1133
1147
|
*/
|
|
1134
1148
|
return r => bindRouter(this.#routes, [a, p.slice(1)], r);
|
|
@@ -1141,10 +1155,9 @@ class ApiRouter extends Router {
|
|
|
1141
1155
|
*
|
|
1142
1156
|
* @param {Method} method
|
|
1143
1157
|
* @param {string[]} path
|
|
1144
|
-
* @
|
|
1145
|
-
* @returns {Iterable<FindItem>}
|
|
1158
|
+
* @returns {Iterable<FindItem<T>>}
|
|
1146
1159
|
*/
|
|
1147
|
-
*find(method, path
|
|
1160
|
+
*find(method, path) {
|
|
1148
1161
|
for (const route of Array.from(this.#routes)) {
|
|
1149
1162
|
if (!route.router && !route.methods.has(method)) { continue; }
|
|
1150
1163
|
const {match} = route;
|
|
@@ -1164,7 +1177,7 @@ class ApiRouter extends Router {
|
|
|
1164
1177
|
* 注册处理函数
|
|
1165
1178
|
* @overload
|
|
1166
1179
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1167
|
-
* @param {
|
|
1180
|
+
* @param {T} handler 要注册的处理函数
|
|
1168
1181
|
* @returns {() => void}
|
|
1169
1182
|
*/
|
|
1170
1183
|
/**
|
|
@@ -1172,7 +1185,7 @@ class ApiRouter extends Router {
|
|
|
1172
1185
|
* @overload
|
|
1173
1186
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1174
1187
|
* @param {string} path 要注册的路径
|
|
1175
|
-
* @param {
|
|
1188
|
+
* @param {T} handler 要注册的处理函数
|
|
1176
1189
|
* @returns {() => void}
|
|
1177
1190
|
*/
|
|
1178
1191
|
/**
|
|
@@ -1180,48 +1193,58 @@ class ApiRouter extends Router {
|
|
|
1180
1193
|
* @overload
|
|
1181
1194
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
|
|
1182
1195
|
* @param {string} path 要注册的路径
|
|
1183
|
-
* @returns {Binder}
|
|
1196
|
+
* @returns {Binder<T>}
|
|
1184
1197
|
*/
|
|
1185
1198
|
/**
|
|
1186
1199
|
* @param {Method | Iterable<Method> | ArrayLike<Method>} methods
|
|
1187
|
-
* @param {string|
|
|
1188
|
-
* @param {...
|
|
1189
|
-
* @returns {Binder | (() => void)}
|
|
1200
|
+
* @param {string| T} [path]
|
|
1201
|
+
* @param {...T} handler
|
|
1202
|
+
* @returns {Binder<T> | (() => void)}
|
|
1190
1203
|
*/
|
|
1191
1204
|
verb(methods, path, ...handler) {
|
|
1192
1205
|
const allMethods = getMethods(methods);
|
|
1193
1206
|
if (!allMethods.length) { return () => {}; }
|
|
1194
1207
|
return verb(this.#routes, allMethods, [path, ...handler]);
|
|
1195
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);
|
|
1218
|
+
}
|
|
1196
1219
|
/**
|
|
1197
1220
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1198
1221
|
* @overload
|
|
1199
|
-
* @param {...
|
|
1222
|
+
* @param {...T} handlers 要注册的处理函数
|
|
1200
1223
|
* @returns {() => void}
|
|
1201
1224
|
*/
|
|
1202
1225
|
/**
|
|
1203
1226
|
* 注册处理函数
|
|
1204
1227
|
* @overload
|
|
1205
1228
|
* @param {string} path 要注册的路径
|
|
1206
|
-
* @param {...
|
|
1229
|
+
* @param {...T} handlers 要注册的处理函数
|
|
1207
1230
|
* @returns {() => void}
|
|
1208
1231
|
*/
|
|
1209
1232
|
/**
|
|
1210
1233
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1211
1234
|
* @overload
|
|
1212
1235
|
* @param {string} path 要注册的路径
|
|
1213
|
-
* @returns {Binder}
|
|
1236
|
+
* @returns {Binder<T>}
|
|
1214
1237
|
*/
|
|
1215
1238
|
/**
|
|
1216
1239
|
* 注册 HTTP GET/POST/PUT/DELETE 处理函数
|
|
1217
1240
|
* @overload
|
|
1218
1241
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1219
1242
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1220
|
-
* @returns {Binder}
|
|
1243
|
+
* @returns {Binder<T>}
|
|
1221
1244
|
*/
|
|
1222
1245
|
/**
|
|
1223
1246
|
* @param {...any} p 要注册的路径
|
|
1224
|
-
* @returns {Binder | (() => void)}
|
|
1247
|
+
* @returns {Binder<T> | (() => void)}
|
|
1225
1248
|
*/
|
|
1226
1249
|
match(...p) {
|
|
1227
1250
|
return verb(this.#routes, ['GET', 'POST', 'PUT', 'DELETE'], p);
|
|
@@ -1243,18 +1266,18 @@ class ApiRouter extends Router {
|
|
|
1243
1266
|
* 注册 HTTP GET 处理函数
|
|
1244
1267
|
* @overload
|
|
1245
1268
|
* @param {string} path 要注册的路径
|
|
1246
|
-
* @returns {Binder}
|
|
1269
|
+
* @returns {Binder<T>}
|
|
1247
1270
|
*/
|
|
1248
1271
|
/**
|
|
1249
1272
|
* 注册 HTTP GET 处理函数
|
|
1250
1273
|
* @overload
|
|
1251
1274
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1252
1275
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1253
|
-
* @returns {Binder}
|
|
1276
|
+
* @returns {Binder<T>}
|
|
1254
1277
|
*/
|
|
1255
1278
|
/**
|
|
1256
1279
|
* @param {...any} p 要注册的路径
|
|
1257
|
-
* @returns {Binder | (() => void)}
|
|
1280
|
+
* @returns {Binder<T> | (() => void)}
|
|
1258
1281
|
*/
|
|
1259
1282
|
get(...p) { return verb(this.#routes, ['GET'], p); }
|
|
1260
1283
|
/**
|
|
@@ -1274,18 +1297,18 @@ class ApiRouter extends Router {
|
|
|
1274
1297
|
* 注册 HTTP POST 处理函数
|
|
1275
1298
|
* @overload
|
|
1276
1299
|
* @param {string} path 要注册的路径
|
|
1277
|
-
* @returns {Binder}
|
|
1300
|
+
* @returns {Binder<T>}
|
|
1278
1301
|
*/
|
|
1279
1302
|
/**
|
|
1280
1303
|
* 注册 HTTP POST 处理函数
|
|
1281
1304
|
* @overload
|
|
1282
1305
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1283
1306
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1284
|
-
* @returns {Binder}
|
|
1307
|
+
* @returns {Binder<T>}
|
|
1285
1308
|
*/
|
|
1286
1309
|
/**
|
|
1287
1310
|
* @param {...any} p 要注册的路径
|
|
1288
|
-
* @returns {Binder | (() => void)}
|
|
1311
|
+
* @returns {Binder<T> | (() => void)}
|
|
1289
1312
|
*/
|
|
1290
1313
|
post(...p) { return verb(this.#routes, ['POST'], p); }
|
|
1291
1314
|
/**
|
|
@@ -1305,18 +1328,18 @@ class ApiRouter extends Router {
|
|
|
1305
1328
|
* 注册 HTTP PUT 处理函数
|
|
1306
1329
|
* @overload
|
|
1307
1330
|
* @param {string} path 要注册的路径
|
|
1308
|
-
* @returns {Binder}
|
|
1331
|
+
* @returns {Binder<T>}
|
|
1309
1332
|
*/
|
|
1310
1333
|
/**
|
|
1311
1334
|
* 注册 HTTP PUT 处理函数
|
|
1312
1335
|
* @overload
|
|
1313
1336
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1314
1337
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1315
|
-
* @returns {Binder}
|
|
1338
|
+
* @returns {Binder<T>}
|
|
1316
1339
|
*/
|
|
1317
1340
|
/**
|
|
1318
1341
|
* @param {...any} p 要注册的路径
|
|
1319
|
-
* @returns {Binder | (() => void)}
|
|
1342
|
+
* @returns {Binder<T> | (() => void)}
|
|
1320
1343
|
*/
|
|
1321
1344
|
put(...p) { return verb(this.#routes, ['PUT'], p); }
|
|
1322
1345
|
/**
|
|
@@ -1336,18 +1359,18 @@ class ApiRouter extends Router {
|
|
|
1336
1359
|
* 注册 HTTP DELETE 处理函数
|
|
1337
1360
|
* @overload
|
|
1338
1361
|
* @param {string} path 要注册的路径
|
|
1339
|
-
* @returns {Binder}
|
|
1362
|
+
* @returns {Binder<T>}
|
|
1340
1363
|
*/
|
|
1341
1364
|
/**
|
|
1342
1365
|
* 注册 HTTP DELETE 处理函数
|
|
1343
1366
|
* @overload
|
|
1344
1367
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1345
1368
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1346
|
-
* @returns {Binder}
|
|
1369
|
+
* @returns {Binder<T>}
|
|
1347
1370
|
*/
|
|
1348
1371
|
/**
|
|
1349
1372
|
* @param {...any} p 要注册的路径
|
|
1350
|
-
* @returns {Binder | (() => void)}
|
|
1373
|
+
* @returns {Binder<T> | (() => void)}
|
|
1351
1374
|
*/
|
|
1352
1375
|
delete(...p) { return verb(this.#routes, ['DELETE'], p); }
|
|
1353
1376
|
/**
|
|
@@ -1367,18 +1390,18 @@ class ApiRouter extends Router {
|
|
|
1367
1390
|
* 注册 HTTP HEAD 处理函数
|
|
1368
1391
|
* @overload
|
|
1369
1392
|
* @param {string} path 要注册的路径
|
|
1370
|
-
* @returns {Binder}
|
|
1393
|
+
* @returns {Binder<T>}
|
|
1371
1394
|
*/
|
|
1372
1395
|
/**
|
|
1373
1396
|
* 注册 HTTP HEAD 处理函数
|
|
1374
1397
|
* @overload
|
|
1375
1398
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1376
1399
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1377
|
-
* @returns {Binder}
|
|
1400
|
+
* @returns {Binder<T>}
|
|
1378
1401
|
*/
|
|
1379
1402
|
/**
|
|
1380
1403
|
* @param {...any} p 要注册的路径
|
|
1381
|
-
* @returns {Binder | (() => void)}
|
|
1404
|
+
* @returns {Binder<T> | (() => void)}
|
|
1382
1405
|
*/
|
|
1383
1406
|
head(...p) { return verb(this.#routes, ['HEAD'], p); }
|
|
1384
1407
|
/**
|
|
@@ -1398,18 +1421,18 @@ class ApiRouter extends Router {
|
|
|
1398
1421
|
* 注册 HTTP OPTIONS 处理函数
|
|
1399
1422
|
* @overload
|
|
1400
1423
|
* @param {string} path 要注册的路径
|
|
1401
|
-
* @returns {Binder}
|
|
1424
|
+
* @returns {Binder<T>}
|
|
1402
1425
|
*/
|
|
1403
1426
|
/**
|
|
1404
1427
|
* 注册 HTTP OPTIONS 处理函数
|
|
1405
1428
|
* @overload
|
|
1406
1429
|
* @param {TemplateStringsArray} template 要注册的路径模板
|
|
1407
1430
|
* @param {...any} substitutions 要注册的路径模板代替内容
|
|
1408
|
-
* @returns {Binder}
|
|
1431
|
+
* @returns {Binder<T>}
|
|
1409
1432
|
*/
|
|
1410
1433
|
/**
|
|
1411
1434
|
* @param {...any} p 要注册的路径
|
|
1412
|
-
* @returns {Binder | (() => void)}
|
|
1435
|
+
* @returns {Binder<T> | (() => void)}
|
|
1413
1436
|
*/
|
|
1414
1437
|
options(...p) { return verb(this.#routes, ['OPTIONS'], p); }
|
|
1415
1438
|
}
|
|
@@ -1437,30 +1460,6 @@ function createFetch(run, notFound) {
|
|
|
1437
1460
|
};
|
|
1438
1461
|
}
|
|
1439
1462
|
|
|
1440
|
-
/** @import { Context, Handler, HandlerResult } from './main/types' */
|
|
1441
|
-
/**
|
|
1442
|
-
* @callback Onionskin
|
|
1443
|
-
* @param {Context} ctx
|
|
1444
|
-
* @param {() => Promise<HandlerResult>} next
|
|
1445
|
-
* @returns {PromiseLike<HandlerResult> | HandlerResult}
|
|
1446
|
-
*/
|
|
1447
|
-
|
|
1448
|
-
const noop = () => {};
|
|
1449
|
-
/**
|
|
1450
|
-
*
|
|
1451
|
-
* @param {...(Onionskin | Onionskin[])} handlers
|
|
1452
|
-
* @returns {Handler}
|
|
1453
|
-
*/
|
|
1454
|
-
function onionskin(...handlers) {
|
|
1455
|
-
/** @type {Handler} */
|
|
1456
|
-
let handler = noop;
|
|
1457
|
-
for (const os of handlers.flat()) {
|
|
1458
|
-
const currentHandler = handler;
|
|
1459
|
-
handler = async ctx => os(ctx, async () => currentHandler(ctx));
|
|
1460
|
-
}
|
|
1461
|
-
return handler;
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
1463
|
/** @import { Context } from './main/types.js' */
|
|
1465
1464
|
class Param {
|
|
1466
1465
|
#symbol = Symbol();
|
|
@@ -1497,4 +1496,4 @@ class Param {
|
|
|
1497
1496
|
}
|
|
1498
1497
|
}
|
|
1499
1498
|
|
|
1500
|
-
export {
|
|
1499
|
+
export { MapRouter, Param, Router, bind$1 as bind, createFetch, main, make, service, stateService, storeService };
|